重映射在图像处理中主要的功能为:将一个图像中一个位置的像素放置到另一个图像指定位置的过程,可以根据自己设定的函数将图像进行变换,较常见的功能有关于x轴翻转,关于y轴翻转,关于x、y轴翻转;仿射变换在图像处理中的主要功能为:对图像进行缩放、旋转、平移、扭曲等。
从下面三个链接可以详细的了解到重映射和仿射变换的原理
重映射:http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/imgtrans/remap/remap.html#remap
仿射变换:http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/imgtrans/warp_affine/warp_affine.html#warp-affine
学习OpenCV:http://download.csdn.net/detail/chenjiazhou12/7083295
程序的功能是:生成两个窗口分别显示重映射的结果和仿射变换的结果
重映射窗口上建立了一个滑动条
0表示:显示原图
1表示:图像宽高缩小一半,并显示在中间
2表示:图像上下颠倒
3表示:图像左右颠倒
4表示:同时执行上下和左右的颠倒
仿射变换窗口建立两个滑动条,一个为缩放功能,一个为旋转功能
旋转的角度为-180—180
缩放因子为:0.1-1.0
#include "stdafx.h" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace cv; /// Global variables Mat src; Mat warp_dst; const char* remaptrackbarname="remapvalue"; const char* warprotatetrackbarname="warprotatevalue"; const char* warpscaletrackbarname="warpscalevalue"; const char* remap_window = "Remap demo"; const char* warprotate_window="warprotate demo"; const int remapmaxcount=4,warprotatemaxcount=360,warpscalemaxcount=10; int remapvalue,warprotatevalue=180, warpscalevalue=10; /// Function Headers void update_map( void ); void remapcontrol(int,void*); void warprotatecontrol(int,void*); void warpaffinecontrol(); /** * @function main */ int main( int argc, char** argv ) { /// Load the image src = imread( "scenery.jpg", 1 ); /// Create dst, map_x and map_y with the same size as src: /// Create window namedWindow( remap_window, CV_WINDOW_AUTOSIZE ); namedWindow(warprotate_window,CV_WINDOW_AUTOSIZE); createTrackbar(remaptrackbarname,remap_window,&remapvalue,remapmaxcount,remapcontrol); createTrackbar(warprotatetrackbarname,warprotate_window,&warprotatevalue,warprotatemaxcount,warprotatecontrol); createTrackbar(warpscaletrackbarname,warprotate_window,&warpscalevalue,warpscalemaxcount,warprotatecontrol); remapcontrol(0,0); warpaffinecontrol(); warprotatecontrol(0,0); waitKey(); return 0; } /** * @function update_map * @brief Fill the map_x and map_y matrices with 4 types of mappings */ void remapcontrol(int,void*) { 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++ ) { switch( remapvalue ) { case 0: map_x.at<float>(j,i) = i ; map_y.at<float>(j,i) = j ; break; case 1: 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 ; } break; case 2: map_x.at<float>(j,i) = i ; map_y.at<float>(j,i) = src.rows - j ; break; case 3: map_x.at<float>(j,i) = src.cols - i ; map_y.at<float>(j,i) = j ; break; case 4: map_x.at<float>(j,i) = src.cols - i ; map_y.at<float>(j,i) = src.rows - j ; break; } // end of switch } } remap( src, dst, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0, 0) ); /// Display results imshow( remap_window, dst ); } void warprotatecontrol(int,void*) { Mat warp_rotate_dst; Mat rot_mat( 2, 3, CV_32FC1 ); Point center = Point( warp_dst.cols/2, warp_dst.rows/2 ); double angle =warprotatevalue-180; double scale =double(warpscalevalue)/10; printf("%f\n",scale); /// 通过上面的旋转细节信息求得旋转矩阵 rot_mat = getRotationMatrix2D( center, angle, scale ); /// 旋转已扭曲图像 warpAffine( warp_dst, warp_rotate_dst, rot_mat, warp_dst.size() ); imshow(warprotate_window,warp_rotate_dst); } void warpaffinecontrol() { Point2f srcTri[3]; Point2f dstTri[3]; Mat warp_mat( 2, 3, CV_32FC1 ); 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*0.0, src.rows*0.33 ); dstTri[1] = Point2f( src.cols*0.85, src.rows*0.25 ); dstTri[2] = Point2f( src.cols*0.15, src.rows*0.7 ); warp_mat = getAffineTransform( srcTri, dstTri ); warpAffine( src, warp_dst, warp_mat, warp_dst.size() ); };
图1、原图
图2、图像宽高缩小一半 图3、 图像上下颠倒
图4、图像左右颠倒 图5、图像上下左右颠倒
图6、图像旋转 图7、图像缩小
图8、图像仿射
功能:对图像进行普通几何变换
结构:
void remap(InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
函数操作为:
函数不能in_place操作
功能:由三个不共线点计算仿射变换
结构:
Mat getAffineTransform(const Point2f* src, const Point2f* dst)
dst:输出图像的相应的三角形顶点坐标
函数操作为:
map_matrix为2*3的矩阵
功能:计算二维旋转的仿射变换矩阵
结构:
Mat getRotationMatrix2D(Point2f center, double angle, double scale)
angle:旋转角度(度),正值表示逆时针旋转
scale:缩放因子
函数操作为:
功能:对图像做仿射变换
结构:
void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
函数操作为:
函数 WarpAffine 利用下面指定的矩阵变换输入图像:
函数不能in_place操作