一。重映射
void remap(InputArray src, OutputArraydst, InputArray map1, InputArray map2, int interpolation, intborderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())ios
- 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象便可,且需为单通道8位或者浮点型图像。
- 第二个参数,OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放函数调用后的输出结果,需和源图片有同样的尺寸和类型。
- 第三个参数,InputArray类型的map1,它有两种可能的表示对象。
- 表示点(x,y)的第一个映射。
- 表示CV_16SC2 , CV_32FC1 或CV_32FC2类型的X值。
- 第四个参数,InputArray类型的map2,一样,它也有两种可能的表示对象,并且他是根据map1来肯定表示那种对象。
- 若map1表示点(x,y)时。这个参数不表明任何值。
- 表示CV_16UC1 , CV_32FC1类型的Y值(第二个值)。
- 第五个参数,int类型的interpolation,插值方式,以前的resize( )函数中有讲到,须要注意,resize( )函数中提到的INTER_AREA插值方式在这里是不支持的,因此可选的插值方式以下:
- INTER_NEAREST - 最近邻插值
- INTER_LINEAR – 双线性插值(默认值)
- INTER_CUBIC – 双三次样条插值(逾4×4像素邻域内的双三次插值)
- INTER_LANCZOS4 -Lanczos插值(逾8×8像素邻域的Lanczos插值)
- 第六个参数,int类型的borderMode,边界模式,有默认值BORDER_CONSTANT,表示目标图像中“离群点(outliers)”的像素值不会被此函数修改。
- 第七个参数,const Scalar&类型的borderValue,当有常数边界时使用的值,其有默认值Scalar( ),即默认值为0。
1 #include<iostream> 2 #include<vector> 3 #include<opencv2/opencv.hpp> 4 using namespace std; 5 using namespace cv; 6 int main() 7 { 8 Mat srcImage, dstImage; 9 Mat map_x, map_y; 10 11 //【1】载入原始图 12 srcImage = imread("E:/test.jpg", 1); 13 if (!srcImage.data) { printf("读取图片错误,请肯定目录下是否有imread函数指定的图片存在~! \n"); return false; } 14 imshow("原始图", srcImage); 15 16 //【2】建立和原始图同样的效果图,x重映射图,y重映射图 17 dstImage.create(srcImage.size(), srcImage.type()); 18 map_x.create(srcImage.size(), CV_32FC1); 19 map_y.create(srcImage.size(), CV_32FC1); 20 21 //【3】双层循环,遍历每个像素点,改变map_x & map_y的值 22 for (int j = 0; j < srcImage.rows; j++) 23 { 24 for (int i = 0; i < srcImage.cols; i++) 25 { 26 //改变map_x & map_y的值. 27 map_x.at<float>(j, i) = static_cast<float>(srcImage.cols-i); //关于x轴对称 28 map_y.at<float>(j, i) = static_cast<float>(j); //y轴不变 29 } 30 } 31 32 //【4】进行重映射操做 33 remap(srcImage, dstImage, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0)); 34 35 //【5】显示效果图 36 imshow("【程序窗口】", dstImage); 37 waitKey(); 38 39 return 0; 40 }
二。仿射变换
- 旋转,rotation (线性变换)
- 平移,translation(向量加)
- 缩放,scale(线性变换)
1.getAffineTransform(求平移矩阵)
Mat getAffineTransform( const Point2f src[], const Point2f dst[] );数组
参数1:Point2f类型的数组,源图像的三个点位置函数
参数2:Point2f类型的数组,目标图像的三个点位置ui
经过指定3个点的偏移肯定图像的变换矩阵。spa
2.getRotationMatrix2D(求旋转、缩放矩阵)
Mat getRotationMatrix2D(Point2fcenter, double angle, double scale)code
3.warpAffine(进行仿射变换)
void warpAffine(InputArray src,OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, intborderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())orm
1 #include "opencv2/highgui/highgui.hpp" 2 #include "opencv2/imgproc/imgproc.hpp" 3 #include <iostream> 4 5 using namespace cv; 6 using namespace std; 7 8 int main() 9 { 10 11 Point2f srcTriangle[3]; //计算平移矩阵的三个点 12 Point2f dstTriangle[3]; 13 14 Mat rotMat(2, 3, CV_32FC1); //旋转矩阵 15 Mat warpMat(2, 3, CV_32FC1); //平移矩阵 16 Mat srcImage, dstImage_warp, dstImage_rotate; 17 18 srcImage = imread("F:/opencv/lena.jpg", 1); 19 23 srcTriangle[0] = Point2f(0, 0); //左上角点 24 srcTriangle[1] = Point2f(static_cast<float>(srcImage.cols - 1), 0); //右上角点 25 srcTriangle[2] = Point2f(0, static_cast<float>(srcImage.rows - 1)); //左下角点 26 27 dstTriangle[0] = Point2f(static_cast<float>(srcImage.cols*0.0), static_cast<float>(srcImage.rows*0.3)); //对应变换的点 28 dstTriangle[1] = Point2f(static_cast<float>(srcImage.cols*0.5), static_cast<float>(srcImage.rows*0.5)); 29 dstTriangle[2] = Point2f(static_cast<float>(srcImage.cols*0.2), static_cast<float>(srcImage.rows*0.6)); 30 warpMat=getAffineTransform(srcTriangle, dstTriangle); //计算平移矩阵 31 warpAffine(srcImage, dstImage_warp, warpMat, dstImage_warp.size()); //进行仿射变换 32 33 Point center = Point(dstImage_warp.cols / 2, dstImage_warp.rows / 2); //获得旋转中心点 34 double angle = -90; //旋转角度,+ 逆时针 -顺时针 35 double scale = 0.5; //缩放比例 36 rotMat = getRotationMatrix2D(center, angle, scale); //计算旋转矩阵 37 warpAffine(srcImage, dstImage_rotate, rotMat, srcImage.size()); //进行仿射变换 38 39 imshow("源图像", srcImage); 40 imshow("平移变换的图像", dstImage_warp); 41 imshow("旋转,缩放的图像", dstImage_rotate); 42 waitKey(0); 43 44 return 0; 45 }