Opencv 在两张图片之间匹配颜色主导的最佳策略是什么?

Opencv 在两张图片之间匹配颜色主导的最佳策略是什么?,opencv,Opencv,我需要匹配两张不同图片之间的主要颜色,使它们尽可能相似 例如,我想将下面孩子的灰度图片与士兵的深褐色图片进行匹配,并补偿对比度和亮度 到目前为止,我正在考虑将图片转换为YCrCb,并匹配Y通道直方图上的对比度和其他通道中的颜色 我将不得不做同样的彩色图片之间 有什么建议吗 我有一些想法应该是有用的——它们从Photoshop开始,在Perl、ImageMagick和OpenCV中徘徊。很多年前,我就研究出了如何复制他们的色调,我非常喜欢摄影师们所获得的温暖而美丽的色调 首先,在Photosho

我需要匹配两张不同图片之间的主要颜色,使它们尽可能相似

例如,我想将下面孩子的灰度图片与士兵的深褐色图片进行匹配,并补偿对比度和亮度

到目前为止,我正在考虑将图片转换为YCrCb,并匹配Y通道直方图上的对比度和其他通道中的颜色

我将不得不做同样的彩色图片之间

有什么建议吗


我有一些想法应该是有用的——它们从Photoshop开始,在Perl、ImageMagick和OpenCV中徘徊。很多年前,我就研究出了如何复制他们的色调,我非常喜欢摄影师们所获得的温暖而美丽的色调

首先,在Photoshop中加载图像,转换为黑白模式,然后返回RGB模式,添加一个曲线调整层和一个带有原始彩色图像的新层。“图层”窗口将如下所示:

现在关闭除灰色背景之外的所有图层,并使用颜色滴管查找和标记:

  • 四分之一色调像素(即信息窗口中的值约为64)
  • 中间色调像素(即信息窗口中约128)
  • 四分之三色调像素(即信息窗口中约192)

现在重新打开其他图层,并找到这三种色调在RGB中的映射:

现在进入曲线层,调整红色、绿色和蓝色曲线以匹配这些值:

如果随后切换回RGB,则可以在一个图表上看到所有三条曲线:

现在只需将该曲线保存为扩展名为
ACV
的文件,即可将其应用于其他图像:

我对此感到有点厌烦,所以我编写了一个Perl脚本,它的功能与此完全相同。您将色调图像作为文件名传递给它,它会查找四分之一、中间和四分之三色调,然后创建一个Adobe Photoshop曲线文件-一个ACV文件,您可以将该文件批量应用于其他照片

以下是Perl:

#!/usr/bin/perl
use strict;
use warnings;
use Image::Magick;
use Data::Dumper;

my $Debug=1;    # 1=print debug messages, 0=don't
my $NPOINTS=5;  # Number of points in curve we create

# Read in image in first parameter
my $imagename=$ARGV[0];
my $orig=Image::Magick::->new;
my $x = $orig->Read($imagename);
  warn "$x" if "$x";

my $width =$orig->Get('columns');
my $height=$orig->Get('rows');
my $depth=$orig->Get('depth');
print "DEBUG: ",$width,"x",$height,", depth: ",$depth,"\n" if $Debug;

# Access pixel cache
my @RGBpixels  = $orig->GetPixels(map=>'RGB',height=>$height,width=>$width,normalize=>1);

my ($i,$j,$p);
my (@greypoint,@Rpoint,@Gpoint,@Bpoint);
for($p=0;$p<$NPOINTS;$p++){
   my $greylevelsought=int(($p+1)*256/($NPOINTS+1));
   my $nearestgrey=1000;
   for(my $t=0;$t<$height*$width;$t++){
         my $R = int(255*$RGBpixels[(3*$t)+0]);
         my $G = int(255*$RGBpixels[(3*$t)+1]);
         my $B = int(255*$RGBpixels[(3*$t)+2]);
         my $this=int(0.21*$R + 0.72*$G +0.07*$B);
         printf "Point: %d, Greysought: %d, this pixel: %d\n",$p,$greylevelsought,$this if $Debug>1;
         if(abs($this-$greylevelsought)<abs($nearestgrey-$greylevelsought)){
            $nearestgrey=$this;
            $greypoint[$p]=$nearestgrey;
            $Rpoint[$p]=$R;
            $Gpoint[$p]=$G;
            $Bpoint[$p]=$B;
         }
   }
   printf "DEBUG: Point#: %d, sought grey: %d, nearest grey: %d\n",$p,$greylevelsought,$nearestgrey if $Debug;
}

# Work out name of the curve file = image basename + acv
my $curvefile=substr($imagename,0,rindex($imagename,'.')) . ".acv";
open(my $out,'>:raw',$curvefile) or die "Unable to open: $!";
print $out pack("s>",4); # Version=4
print $out pack("s>",4); # Number of curves in file = Master NULL curve + R + G + B

print $out pack("s>",2);            # Master NULL curve with 2 points for all channels
print $out pack("s>",0  ),pack("s>",0  );   # 0 out, 0 in
print $out pack("s>",255),pack("s>",255);   # 255 out, 255 in

print $out pack("s>",2+$NPOINTS);       # Red curve
print $out pack("s>",0  ),pack("s>",0  );   # 0 out, 0 in
for($p=0;$p<$NPOINTS;$p++){
   print $out pack("s>",$Rpoint[$p]),pack("s>",$greypoint[$p]);
}
print $out pack("s>",255),pack("s>",255);   # 255 out, 255 in

print $out pack("s>",2+$NPOINTS);       # Green curve
print $out pack("s>",0  ),pack("s>",0  );   # 0 out, 0 in
for($p=0;$p<$NPOINTS;$p++){
   print $out pack("s>",$Gpoint[$p]),pack("s>",$greypoint[$p]);
}
print $out pack("s>",255),pack("s>",255);   # 255 out, 255 in

print $out pack("s>",2+$NPOINTS);       # Blue curve
print $out pack("s>",0  ),pack("s>",0  );    # 0 out, 0 in
for($p=0;$p<$NPOINTS;$p++){
   print $out pack("s>",$Bpoint[$p]),pack("s>",$greypoint[$p]);
}
print $out pack("s>",255),pack("s>",255);    # 255 out, 255 in

close($out);
#/usr/bin/perl
严格使用;
使用警告;
使用Image::Magick;
使用数据::转储程序;
我的$Debug=1;#1=打印调试消息,0=不打印
我的$NPOINTS=5;#我们创建的曲线中的点数
#在第一个参数中读入图像
my$imagename=$ARGV[0];
my$orig=Image::Magick::->新建;
我的$x=$orig->Read($imagename);
如果“$x”,则警告“$x”;
my$width=$orig->Get('columns');
我的$height=$orig->Get('rows');
my$depth=$orig->Get('depth');
如果$DEBUG,则打印“DEBUG:”、$WITH、$x“、$height、”、depth:“、$depth、”\n”;
#访问像素缓存
my@RGBpixels=$orig->GetPixels(贴图=>'RGB',高度=>$height,宽度=>$width,规格化=>1);
我的($i,$j,$p);
我的(@greypoint、@Rpoint、@Gpoint、@Bpoint);

对于($p=0;$pI),您的问题很难理解。您所说的“我想将灰度图像转换为具有正确颜色的黑白图像”是什么意思?当然灰度图像和黑白图像都没有任何颜色?你可以添加一些图片来说明吗?谢谢你的评论。我已经重新编写了我的问题,试图澄清这个问题。我成功地进行了直方图匹配。我从本教程中的代码开始,这基本上是一个自动版本的过程非常感谢。我必须实时处理,因为其中一张照片是在飞行中拍摄的快照。不过,你的讨论非常有用,它可能会触发正确的代码。哦,顺便说一句,我认为它可能也适用于彩色,你认为呢?我必须将飞行中拍摄的照片与复古彩色图像进行匹配。预处理总之,您的复古图像是旧的;-)因此您必须已经拥有它们,因此您可以在进行实时采集之前预先生成曲线并应用它们。我还没有详细研究过,但也许你可以将你的复古曲线添加到运行在一些佳能相机上的
幻灯
固件中。