您的位置:首页 > 运维架构

OpenCV学习记录3//仿射变换与重映射

2014-02-23 17:38 225 查看
在图像处理中,发现很多书都会将几何变换分为重映射·,仿射变换与透视变换。对于透视变换不是理解得和透彻,所以先总结一下重映射与放射变换。重映射就是把一个图像中一个位置的像素放置到另一个图片指定位置的过程。在OpenCV中有函数remap()。公式是:



事实上,映射分为向前映射和向后映射,将输入映射到输出的是向前映射,反之就是向后映射,那remap是哪一种呢?下面是检验的代码:
Mat dst,map_x,map_y;
dst.create(src.size(),src.type());
map_x.create(src.size(),CV_32FC1);
map_y.create(src.size(),CV_32FC1);
for(int j=0;j<src.rows;j++){
for(int i=0;i<src.cols;i++){
if( i > src.cols*0.25 && i < src.cols*0.75 &&
j > src.rows*0.25 && j < src.rows*0.75 ){
map_x.at<float>(j,i) = 2*( i - src.cols*0.25 ) + 0.5 ;
map_y.at<float>(j,i) = 2*( j - src.rows*0.25 ) + 0.5 ;
}
else
{ map_x.at<float>(j,i) = 0 ;
map_y.at<float>(j,i) = 0 ;
}
}
}
remap( src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0,0));
namedWindow("ReM");
imshow("ReM",dst);

结果如下:



图像缩小了,根据map_x.at<float>(j,i) = 2*( i - src.cols*0.25 ) + 0.5 ;map_y.at<float>(j,i) = 2*( j - src.rows*0.25 ) + 0.5 ;说明是向后映射!
事实上,向前映射只适合于图像大小不改变的处理,不然会造成映射不完全或映射重叠,而向后映射则没有这种限制,所以大多数的处理都是向后映射。
而放射变换则较好理解:一个任意的仿射变换都能表示为 乘以一个矩阵 (线性变换) 接着再 加上一个向量 (平移),通常用2*3的矩阵表示。
公式直接上图:
.



说白了就是利用原图的3点与目标图的3点算出一条对应的变换公式,然后逐个位置变换,想必也应该是向后映射。程序如下:

src=imread("./CAT.jpg",1);
warp_dst=Mat::zeros(src.rows,src.cols,src.type());
srcTri[0] = Point2f( 0,0 );
srcTri[1] = Point2f( src.cols - 1, 0 );
srcTri[2] = Point2f( 0, src.rows - 1 );

dstTri[0] = Point2f( src.cols-1, 0 );
dstTri[1] = Point2f( 0, src.rows*0.0 );
dstTri[2] = Point2f( src.cols-1, src.rows-1 );

warp_mat=getAffineTransform(srcTri,dstTri);
warpAffine( src, warp_dst, warp_mat, warp_dst.size());

结果就不贴了,基本上网上书上都有!注意上面的程序其实只是将图片做了镜像,说明其实remap是可以和getAffineTransform、warpAffine组合互换的,个人觉得当然是直接仿射来得简单点,但在时间和空间复杂度上,我都没细算。

我的总结还不是和全面,因为没老师指导的关系,也不不一定准确,写出来是希望能和大家多交流,有错误或补充的地方希望一定要指出!谢谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: