我最近不得不合并这些图像:
这些图像代表在不同位置发生的不同类型的事件。我们的想法是合并这些图像,以保持每个图像(红 - 黄 - 绿)的“热”区域,以全局了解全局发生的事情。
在我目前的方法中,我拍摄第二张图像并提取红色/绿色通道,以形成相关部分的掩模,如下所示:
然后我使用此蒙版将其与第一张图像合并,因此只复制相关部分。
以下是用于此目的的脚本:
#!/bin/bash
# Extract RGB
convert b.png -colorspace RGB -separate b-sep-%d.png
# Keep red & green only
convert b-sep-2.png b-sep-0.png -compose minus -composite b-tmp-br.png
convert b-sep-2.png b-sep-1.png -compose minus -composite b-tmp-bg.png
convert b-tmp-br.png b-tmp-bg.png -compose plus -composite -level 10%,100% b-mask.png
# Composite!
composite b.png a.png b-mask.png final.png
这是我目前的结果:
如您所见,它适用于红黄绿色部分,但缺少蓝色部分。问题是,如果我将遮罩放大以包含蓝色部分,那么它将覆盖第一个图像中的红黄绿色部分,第二个部分使用蓝色部分!这在最终结果中已经可见,左上角的第一个图像红色部分被第二个图像的绿色部分覆盖。
正确获取蓝色部分比较棘手,但我认为以下算法应该有效(伪代码):
function merge_pixel(pixel a, pixel b)
{
points = { :red => 4, :yellow => 3, :green => 2, :blue => 1, :default => 0 }
a_points = points[a.color()]
b_points = points[b.color()]
return a_points > b_points ? a : b
}
也就是说,在合并图像时,根据哪种颜色对最终图像最重要,从图像a或b复制像素。也许这个算法不合理(例如如何处理渐变部分,可能有一个阈值),随意揭穿它。
真实问题:
使用imagemagick,如何:
你不需要回答这两个问题,只需找到一种获得所需结果的图像匹配方法就可以了。
[编辑]
提示:我刚才有一个想法,我认为你可以为这两个图像生成蒙版(包括蓝色部分)并做一些“设置交集/联合/差异/任何”的蒙版来生成适当的“最终”蒙版所以只复制了图像b的真实相关部分。
答案 0 :(得分:0)
好的,我做了“merge_pixel”策略并且有效!
require 'RMagick'
include Magick
def pixel_score(p)
r, g, b = [p.red, p.green, p.blue].map{ |i| i / 256 }
is_flat = (r-g).abs < 20 && (r-b).abs < 20 && (g-b).abs < 20
is_grey = is_flat && r < 200
is_red = r >= 240 && g <= 100 # && b < 10
is_yellow = r >= 150 && g >= 100 && b <= 10
is_green = r <= 200 && g >= 200 && b <= 100
is_cyan = r <= 10 && g >= 100 && b >= 30
is_blue = r <= 10 && g <= 100 && b >= 200
if is_red
(999**8) + (r - g)
elsif is_yellow
(999**7) + (r + g)
elsif is_green
(999**6) + (g - b)
elsif is_cyan
(999**5) + (g + b)
elsif is_blue
(999**4) + (b - g)
else
(999**1) + r ** 3 + g ** 2 + b
end
end
def rmagick_merge(file_a, file_b, file_merged)
img_a = ImageList.new(file_a)
img_b = ImageList.new(file_b)
result = Image.new(img_a.columns, img_a.rows)
img_a.columns.times do |col|
img_a.rows.times do |row|
pixel_a = img_a.pixel_color(col, row)
pixel_b = img_b.pixel_color(col, row)
pixel = [pixel_a, pixel_b].sort_by{ |p| pixel_score(p) }.last
#pixel = [pixel_a, pixel_b].sort_by{ |p| [p.red - p.green, p.green, p.blue] }.first
#pixel = [pixel_a, pixel_b].sort_by{ |p| [p.red - p.green - p.blue * 100, p.green, p.blue] }.last
result.pixel_color(col, row, pixel)
end
end
result.format = "PNG"
result.write(file_merged)
end
if __FILE__ == $0
if ARGV.size < 3
puts "usage #{__FILE__} a.png b.png merged.png"
exit 1
end
rmagick_merge(ARGV[0], ARGV[1], ARGV[3])
end
这是结果(不完美,但根据我对真实照片的需求进行了微调):