首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >利用Elixir / Vix / libvips去除色度键

利用Elixir / Vix / libvips去除色度键
EN

Stack Overflow用户
提问于 2022-10-16 21:03:20
回答 2查看 29关注 0票数 0

这只是从Vix示例中复制的一些处理程序代码。

代码语言:javascript
复制
defmodule VixExt do
  alias Vix.Vips.Image
  alias Vix.Vips.Operation

  @max_height 500

  def show(%Image{} = image) do
    height = Image.height(image)

    # scale down if image height is larger than 500px
    image =
      if height > @max_height do
        Operation.resize!(image, @max_height / height)
      else
        image
      end

    # write vips-image as png image to memory
    {:ok, image_bin} = Image.write_to_buffer(image, ".png")
    Kino.render(Kino.Image.new(image_bin, "image/png"))

    :ok
  end
end

做事情的代码:

代码语言:javascript
复制
import VixExt

{:ok, fore} = Image.open("/home/user/Downloads/greenscreen.jpg")

{:ok, back} = Image.open("/home/user/Downloads/background.jpg")

# Lower bound green
{:ok, l_green} = Image.Math.greater_than(fore, [0.0, 100.0, 0.0])
# Upper bound green
{:ok, u_green} = Image.Math.less_than(fore, [100.0, 255.0, 95.0])

{:ok, color_fore_mask} = Image.Math.boolean_and(l_green, u_green)

{:ok, fore_mask} = Vix.Vips.Operation.bandbool(color_fore_mask, :VIPS_OPERATION_BOOLEAN_AND)

{:ok, masked} = Image.Math.subtract(fore, fore_mask)

{:ok, inverted_fore_mask} = Vix.Vips.Operation.invert(fore_mask)

{:ok, masked_back} = Image.Math.subtract(back, inverted_fore_mask)

{:ok, masked_bin} = Vix.Vips.Image.write_to_buffer(masked, ".jpg")
{:ok, masked_clone} = Vix.Vips.Image.new_from_buffer(masked_bin)


{:ok, masked_back_bin} = Vix.Vips.Image.write_to_buffer(masked_back, ".jpg")
{:ok, masked_back_clone} = Image.from_binary(masked_back_bin)

{:ok, composite} = Vix.Vips.Operation.add(masked_back, masked_clone)

show(composite)

我一开始遇到的问题是,剪裁后的图像没有被正确地添加到一起。长生不老,所以我有点期待这种行为。然而,它们都指向相同的图像,所以当我试图将它们加在一起时,这是一种原始数据的混搭。

我可以通过加载预先剪裁的图像来强制它达到正确的行为,然后像我所期望的那样运行,但是我不想因为明显的原因而不得不保存到磁盘。所以现在我试图强制复制,以便我得到剪裁的版本,而不是原来的版本。

所显示的图像是我想要的结果。这个人从一个绿色的背景开始,这个背景被移除并合成到场景中。

我现在遇到的错误是

代码语言:javascript
复制
** (MatchError) no match of right hand side value: {:error, "Failed to write VipsImage to memory"}

每当我尝试写两次缓冲区时,都会发生这种情况。

我会认为绿色屏幕删除是一个相当例行的用例,这样做会更容易。我很高兴能采取更好的方法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-17 13:36:42

针对来自@GeneticJam的这一挑战,图像药剂库现在提供Image.chroma_key/2像这样用基本上是:

代码语言:javascript
复制
Image.chroma_key!(foreground) 
|> then(&Image.compose!(background, &1))

默认的色度包括可能的色域绿色。

票数 1
EN

Stack Overflow用户

发布于 2022-10-16 22:46:08

我设法用两种不同的方法解决了这个问题。

代码语言:javascript
复制
import VixExt
# Opening with this option makes it possible to have more than one pipeline so it avoids the above error.
{:ok, fore} = Image.open("/home/kevinedey/Downloads/greenscreen.jpg", access: :random)

{:ok, back} = Image.open("/home/kevinedey/Downloads/background.jpg", access: :random)

# Lower bound green
{:ok, l_green} = Image.Math.greater_than(fore, [0.0, 100.0, 0.0])
# Upper bound green
{:ok, u_green} = Image.Math.less_than(fore, [100.0, 255.0, 95.0])

{:ok, color_fore_mask} = Image.Math.boolean_and(l_green, u_green)

{:ok, fore_mask} = Vix.Vips.Operation.bandbool(color_fore_mask, :VIPS_OPERATION_BOOLEAN_AND)

{:ok, masked} = Image.Math.subtract(fore, fore_mask)

{:ok, inverted_fore_mask} = Vix.Vips.Operation.invert(fore_mask)

{:ok, masked_back} = Image.Math.subtract(back, inverted_fore_mask)

{:ok, masked_bin} = Vix.Vips.Image.write_to_buffer(masked, ".jpg")
{:ok, masked_clone} = Vix.Vips.Image.new_from_buffer(masked_bin)

{:ok, masked_back_bin} = Vix.Vips.Image.write_to_buffer(masked_back, ".jpg")
{:ok, masked_back_clone} = Image.from_binary(masked_back_bin)

{:ok, comp} = Vix.Vips.Operation.add(masked_back_clone, masked_clone)

show(comp)

可能更接近贵宾打算如何使用,因为额外的管道是不需要的。

代码语言:javascript
复制
import VixExt

{:ok, fore} = Image.open("/home/kevinedey/Downloads/greenscreen.jpg")

{:ok, back} = Image.open("/home/kevinedey/Downloads/background.jpg")

# Lower bound green
{:ok, l_green} = Image.Math.greater_than(fore, [0.0, 100.0, 0.0])
# Upper bound green
{:ok, u_green} = Image.Math.less_than(fore, [100.0, 255.0, 95.0])

{:ok, color_fore_mask} = Image.Math.boolean_and(l_green, u_green)

{:ok, fore_mask} = Vix.Vips.Operation.bandbool(color_fore_mask, :VIPS_OPERATION_BOOLEAN_AND)

{:ok, inverted_fore_mask} = Vix.Vips.Operation.invert(fore_mask)

{:ok, masked_person} = Vix.Vips.Operation.bandjoin([fore, inverted_fore_mask])

{:ok, comp} = Image.compose(back, masked_person)

show(comp)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74090698

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档