我们经常会看到一幅图像中,图中景物左右对调,就像照镜子一样。使用图像处理软件可以很容易实现这一效果,现在一些手机拍照时可以直接进行处理,得到这种图像,我把它称作“图像镜子处理”。用opencv实现一下,代码如下,
int main(){
#pragma region 镜像处理
Mat image = imread("chuli.jpg");
int W=image.cols;
int L=image.rows;
Mat dst(L,2*W,image.type()); //新建一个图像,是原图像宽度的2倍
namedWindow("镜子图");
imshow("镜子图",dst);
waitKey(0);
Mat dst1=image.clone();
dst1.copyTo(dst(Rect(0,0,W,L))); //将原图像复制到新图像中
Vec3b temp;
namedWindow("镜子");
imshow("镜子",dst);
waitKey(0);
for (int y=0;y<L;y++)
{
int x1=0,x2=0;
// for (; x1<W; x1++)
// {
// dst.at<Vec3b>(y,x1)=dst1.at<Vec3b>(y,x1);
// }
for (x1=W-1,x2=W ;x1>=0;x1--,x2++)
{
dst.at<Vec3b>(y,x2)=dst.at<Vec3b>(y,x1);
}
}
namedWindow("镜子变换");
imshow("镜子变换",dst);
waitKey(0);
#pragma endregion 镜像处理
system("pause");
return 0;
}
在程序中所做的处理时,新建一个图像,新图像的宽度是原图像宽度的二倍。新图像刚建立好是一个空的图像(如图1),要先将原图复制进新的图像中,原图出现在新图像的左半部分(如图2)。复制的方式有两种:一是逐个像素点进行复制,这种方法类似很常见的数组复制,在这里就不细说了,注意坐标就可以;另一种是使用opencv中的copyto函数来完成,
dst1.copyTo(dst(Rect(0,0,W,L)));
其中,dst1是原图,dst是我们新建的图像,Rect(0,0,W,L)表示原图复制到新图像中的位置,前两个参数是原图像复制到新图像中的起始位置,后两个参数分别表示在新图像中的宽度和高度,复制结果如图2所示。
将原图像复制到新图像之后就可以进行镜子处理了,方法很简单,类似水平镜像处理,只是中轴线是原图的右边界,结果如图3所示。可以根据图像中不同的目标选择不同的变换边界,以达到更加逼真的效果。
图1 新建宽度为原图宽度二倍的图像
图2 将原图复制到新图中
图3 图像镜子处理