根据图像中已知区域的 HSV 调整颜色(使用 ImageMagick 或类似工具)

Adjust colors based on known HSV of region in image (using ImageMagick or similar)

这是一个关于如何使用 ImageMagick 或类似工具对图像进行颜色校正的问题。

我们有一张带有 CMYK 样本的图像。样本印在无光泽的白卡纸上,我们在预先确定的照明条件下测量了青色(在现实生活中)的 HSV。然后,我们将此样本包含在我们拍摄的其他图像前景的卡片纸上。因为其他图片都有不同的光照条件,我们无法客观地识别图像中其他物体的颜色。

有没有一种方法,使用 ImageMagick 或类似工具,以青色为基础,在整个图像中移动 HSV 值,以便颜色或图像中的其他对象反映出与它们本来具有的值相似的值,它们是在与 CMYK 样本相同的光照条件下拍摄的吗?

简而言之,我们的目标是能够以一定的准确性确定 HSV,例如 "Yellow"(如果没有足够的光线,它可能看起来是橙色或棕色)。

我找到了几篇文章,这些文章提出了执行类似操作的技巧,但与我们在这里尝试执行的操作完全不同。

这里有两种使用 ImageMagick 和 Unix 工具的简单方法。

输入图像(来自http://im.snibgo.com/dcrawwb.htm

1) 从http://xritephoto.com/documents/literature/en/ColorData-1p_EN.pdf

获取参考青色
cyan_ref="srgb(8,133,161)"

cyan_ref=`echo $cyan_ref | tr -cs "[0-9]*\n" " " | sed 's/^[ ]*//'`
echo "$cyan_ref"
8 133 161 

分离 r、g 和 b 值

cyan_ref_r=`echo $cyan_ref | cut -d\  -f1`
cyan_ref_g=`echo $cyan_ref | cut -d\  -f2`
cyan_ref_b=`echo $cyan_ref | cut -d\  -f3`

2) 从图像中裁剪一个小矩形并获取青色色块的平均测量颜色。

cyan_mea=`convert cyan_measure.png -scale 1x1! -format "[pixel:u.p{0,0}]" info:`

echo "cyan_mea=$cyan_mea"
srgb(2,147,187)

cyan_mea=`echo $cyan_mea | tr -cs "[0-9]*\n" " " | sed 's/^[ ]*//'`
echo "$cyan_mea"
2 147 187 

分离 r、g 和 b 值

cyan_mea_r=`echo $cyan_mea | cut -d\  -f1`
cyan_mea_g=`echo $cyan_mea | cut -d\  -f2`
cyan_mea_b=`echo $cyan_mea | cut -d\  -f3`

3) 将差异计算为百分比(相对于 255)

red_pct=`convert xc: -format "%[fx:(cyan_ref_r-cyan_mea_r)/255]" info:`
green_pct=`convert xc: -format "%[fx:(cyan_ref_g-cyan_mea_g)/255]" info:`
blue_pct=`convert xc: -format "%[fx:(cyan_ref_b-cyan_mea_b)/255]" info:`

4) 转换图片:

convert ftc_typ_sm.jpg \
-channel r -evaluate add $red_pct% +channel \
-channel g -evaluate add $green_pct% +channel \
-channel b -evaluate add $blue_pct% +channel \
ftc_typ_sm_corrected_rgb.jpg

现在您有了校正后的图像,可以测量图表或图像中的任何其他颜色。

如果您的图像是 cmyk,则对 c、m、y、k 执行相同操作或转换为 RGB 并执行上述操作。

或者,您可以在 HCL 颜色空间中执行此操作:

1) 从http://xritephoto.com/documents/literature/en/ColorData-1p_EN.pdf获取参考青色 并转换为 HCL(或 HSL 或 HSV 等)。

cyan_ref="srgb(8,133,161)"
cyan_ref_hcl=`convert xc:"$cyan_ref" -colorspace HCL -format "%[pixel:u.p{0,0}]" info: | tr -cs "[0-9]*\n" " " | sed 's/^[ ]*//'`
echo "$cyan_ref_hcl"
191 60 39


将 h、c、l 值分开

cyan_ref_h=`echo "$cyan_ref_hcl" | cut -d\  -f1`
cyan_ref_c=`echo "$cyan_ref_hcl" | cut -d\  -f2`
cyan_ref_l=`echo "$cyan_ref_hcl" | cut -d\  -f3`

2) 测量青色样本并将平均值转换为 HCL

cyan_mea=`convert cyan_measure.png -scale 1x1! -format "%[pixel:u.p{0,0}]" info:`
echo "$cyan_mea"
srgb(2,147,187)

cyan_mea_hcl=`convert xc:"$cyan_mea" -colorspace HCL -format "%[pixel:u.p{0,0}]" info: | tr -cs "[0-9]*\n" " " | sed 's/^[ ]*//'`
echo "$cyan_mea_hcl"
193 73 42


将 h、c、l 值分开

cyan_mea_h=`echo "$cyan_mea_hcl" | cut -d\  -f1`
cyan_mea_c=`echo "$cyan_mea_hcl" | cut -d\  -f2`
cyan_mea_l=`echo "$cyan_mea_hcl" | cut -d\  -f3`

3) 计算差异并更改为 -modulate 的值 suitable(参见 http://www.imagemagick.org/script/command-line-options.php#modulate

cyan_h_diff=$((cyan_ref_h-cyan_mea_h))
cyan_c_diff=$((cyan_ref_c-cyan_mea_c))
cyan_l_diff=$((cyan_ref_l-cyan_mea_l))
echo "cyan_h_diff=$cyan_h_diff; cyan_c_diff=$cyan_c_diff; cyan_l_diff=$cyan_l_diff;"
cyan_h_diff=-2; cyan_c_diff=-13; cyan_l_diff=-3;

modh=`convert xc: -format "%[fx:100+$cyan_h_diff*200/360]" info:`
modc=$((100+cyan_c_diff))
modl=$((100+cyan_l_diff))
echo "modh=$modh; modc=$modc; modl=$modl"
modh=98.8889; modc=87; modl=97


4)处理图像

convert ftc_typ_sm.jpg -define modulate:colorspace=HCL -modulate $modh,$modc,$modl ftc_typ_sm_corrected_hcl.jpg


如需更准确的方法:

1) 对所有样本执行 RGB 方法并计算平均 R、G、B 差异。

2) 执行 HCL 方法并计算平均 H、C、L 差异

3) 执行相同的操作,但计算 table 来自每个色块中每个色块的输入和输出值对的每个红色、绿色和蓝色(或色调、色度、亮度)通道图片和参考 table.