OpenCV 几何变换-图像镜像

图像镜像是图像基本的几何变换之一,实现起来也很简单,先贴上源码:

#include <opencv/highgui.h>  
#include <time.h>  
#include <opencv2/opencv.hpp>  
#include <opencv/cv.h>  
#include <iostream> 

using namespace std;  
using namespace cv; 

int main()
{
	Mat SrcImage = imread("1.jpg",0);
	imshow("原图",SrcImage);
	Mat dst;    
	dst.create( SrcImage.size(), SrcImage.type());    
	Mat map_x;    
	Mat map_y;    
	map_x.create( SrcImage.size(), CV_32FC1);    
	map_y.create( SrcImage.size(), CV_32FC1);    
	for( int i = 0; i < SrcImage.rows; i++)    
	{    
	    for( int j = 0; j < SrcImage.cols; j++)    
		{    
			//map_x.at<float>(i, j) = (float) (SrcImage.cols - j-1) ;    
			//map_y.at<float>(i, j) = (float) i ;  //水平  
			map_x.at<float>(i, j) = (float) j ;    
			map_y.at<float>(i, j) = (float) (SrcImage.rows - i-1) ;  //垂直  
		}    
	}    
		remap(SrcImage, dst, map_x, map_y, CV_INTER_LINEAR);    
		imshow("镜像图", dst); 
	    waitKey(0);
	    return 0;
}

图像镜像功能主要用到OpenCV中的remap()函数,其原型如下:

CV_EXPORTS_W void remap( 
InputArray src, 
OutputArray dst,
InputArray map1, 
InputArray map2,
int interpolation, 
int borderMode=BORDER_CONSTANT,
const Scalar& borderValue=Scalar());

其功能为根据map1和map2两个矩阵,对输入图像src做出重映射,并将映射结果以dst输出。所以参数就很直观了:
第一个参数:输入图像
第二个参数:输出图像
第三个参数:输入图像中各像素点的坐标映射到目标图像的哪个x(列)
第四个参数:输入图像中各像素点的坐标映射到目标图像的哪个x(行)
第五个参数:图像插值方式,可以参考:常用插值方法
第六个参数:边界模式,有默认值BORDER_CONSTANT。
第七个参数:const Scalar&类型的borderValue,当有常数边界时使用的值,其有默认值Scalar( ),即默认值为0。

所以,到底实现怎样的镜像或者是重映射就是由map1和map2两个矩阵决定的了,我们回到上面的代码中具体看下如何实现:

for( int i = 0; i < SrcImage.rows; i++)    
	{    
	    for( int j = 0; j < SrcImage.cols; j++)    
		{    
			//map_x.at<float>(i, j) = (float) (SrcImage.cols - j-1) ;    
			//map_y.at<float>(i, j) = (float) i ;  //水平  
			map_x.at<float>(i, j) = (float) j ;    
			map_y.at<float>(i, j) = (float) (SrcImage.rows - i-1) ;  //垂直  
		}    
	}    

矩阵的赋值就是在这里实现的:
假设原图像为6*3的尺寸,当遍历到i=0,j=0时,及
map_x.at(0, 0) = 0
map_y.at(0, 0) = 3-0-1=2
也就是说,原图像的 (0, 0) 会被映射到目标图像的(0, 2),同理:
map_x.at(0, 2) = 0
map_y.at(0, 2) = 3-2-1=0
原图像的 (0, 2) 会被映射到目标图像的(0,0),所以实现了垂直镜像。特别要注意的一点是:OpenCV中图像的行列式标号是从0开始的,所以,要(SrcImage.rows - i-1),不然镜像后的图像会有黑边的。

**注意:**其实还有一点不知道大家留意到没有,我们只用了单通道,并没有用image.at<Vec3b>(i,j)[0] 这样的写法,为什么可以镜像彩色图呢?
因为map_x和map_y矩阵中放的根本就不是像素的灰度,而是映射前后的位置。

这里写图片描述

这里写图片描述

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值