我有一些应该有用的想法 - 它们有点从 Photoshop 开始,然后经过 Perl、ImageMagick 和 OpenCV。我非常喜欢这样的摄影师所取得的温暖而美丽的色调大卫·福科斯 http://davidfokos.net and 迈克尔·肯纳 http://www.michaelkenna.net很多年前我就研究出了如何复制他们的色调。
首先,在 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);
如果您想在 OpenCV 中执行此操作,您可以非常简单地将脚本的前 70% 转换为 OpenCV - 它只有 2 个循环。然后你就会得到四分之一、中音和四分之三音调点。您可以使用曲线拟合程序,例如gnuplot
(我不知道你的技能)将曲线拟合到点,然后为 256 个值 0-255 中的每个值生成一个查找表,并将其应用到你的其他图像中cv::LUT()
复制或克隆音调。