更新时间:2023-02-20 13:07:16
我有一些有用的想法-它们有点像从Photoshop开始,然后在Perl,ImageMagick和OpenCV中徘徊.我是 David Fokos 和
I have some ideas that should be of use - they kind of start in Photoshop and wander through Perl, ImageMagick and OpenCV. I am a big fan of the warm and beautiful tonalities achieved by photographers such as David Fokos and Michael Kenna and I worked out, many years back, how to replicate their toning.
首先,在Photoshop中加载图像,转换为黑白模式,然后返回RGB模式,添加一个Curves调整层和一个带有原始彩色图像的新层.您的图层"窗口将如下所示:
First, load your image up in Photoshop, convert to black and white mode, and then back to RGB mode, add a Curves adjustment layer and a new layer with the original colour image. Your Layers window will look like this:
现在关闭除灰色背景以外的所有图层,并使用颜色滴管"查找并标记:
Now turn off all layers except the grey background, and use the Color Dropper to find and mark:
现在重新打开其他图层,并找到这三种色调在RGB中的映射:
Now turn the other layers back on and find what those three tones map to in RGB:
现在进入曲线"层,并调整红色,绿色和蓝色曲线以匹配这些值:
Now go in the Curves layer and adjust the Red, Green and Blue curves to match those values:
然后如果您切换回RGB,则可以在一张图上看到所有三条曲线:
And if you then switch back to RGB, you can see all three curves on one diagram:
您现在只需要将该Curve保存为扩展名为ACV
的文件,即可将其应用于其他图像:
You now just need to save that Curve as a file with ACV
extension and you can apply it to other images:
这样做让我有点无聊,所以我写了一个Perl脚本,它完全一样.您将其传递为定调后的图像作为文件名,它会找到四分之一,中四分之三的色调,然后创建一个Adobe Photoshop Curves文件-一个ACV文件,您可以将其批量应用到其他照片上.
I got a bit bored doing that, so I wrote a Perl script that does exactly the same. You pass it a toned image as a filename, it finds the quarter, mid and three-quarter tones and then creates an Adobe Photoshop Curves file - an ACV file for you which you can then batch apply to other photos.
这是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()
复制或克隆色调的其他图像.
If you want to do this in OpenCV, you could translate the first 70% of the script to OpenCV pretty simply - it is just 2 loops. Then you would have the quarter, mid and three-quarter tone points. You could use a curve-fitting program such as gnuplot
(I have no idea of your skillset) to fit a curve to the points and then generate a lookup table for each of the 256 values 0-255, and apply that to your other images using cv::LUT()
to replicate or clone the tone.