重映射(remapping)
主要涉及函数 remap
因为重映射函数所做的就是通过相应的矩阵参数,将原图像对应的像素点按照参数表达式重新排列到目标矩阵,所以通过不同的算法的描写可以形成许多操作:
1.保持原样:
1 #include <opencv2\opencv.hpp> 2 #include <iostream> 3 #include <string> 4 5 #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) 6 7 using namespace std; 8 using namespace cv; 9 10 void showImg(const string &win_name, const Mat &img) 11 { 12 namedWindow(win_name, CV_WINDOW_AUTOSIZE); 13 imshow(win_name, img); 14 } 15 16 int main(void) 17 { 18 Mat src = imread("lena.jpg"); 19 if (src.empty()) 20 return -1; 21 showImg("Src", src); 22 23 24 Mat dst; 25 Mat map_x; 26 Mat map_y; 27 dst.create(src.size(), src.type());//目标图像与原图像大小类型均需相同 28 map_x.create(src.size(), CV_32FC1);//映射的变换矩阵与原图像大小相同,类型固定 29 map_y.create(src.size(), CV_32FC1); 30 31 for (int i = 0; i < src.rows; ++i)//对每一行 32 { 33 for (int j = 0; j < src.rows; ++j)//对每一列 34 { 35 /* 36 因为在map_x保存的是此行的每一行的列变换信息,所以其等于j(列号),标识保持此行上的列信息位置不变 37 map_y同理; 38 因此此用用法是图像映射后不变 39 */ 40 map_x.at<float>(i, j) = j;//保存每行上的列变换 41 map_y.at<float>(i, j) = i;//保存对列上的行变换 42 } 43 } 44 remap(src, dst, map_x,map_y,CV_INTER_LINEAR,BORDER_CONSTANT,Scalar(0,0,0)); 45 46 showImg("dst", dst); 47 waitKey(); 48 return 0; 49 }
结果:
2.图像水平翻转:
1 #include <opencv2\opencv.hpp> 2 #include <iostream> 3 #include <string> 4 5 #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) 6 7 using namespace std; 8 using namespace cv; 9 10 void showImg(const string &win_name, const Mat &img) 11 { 12 namedWindow(win_name, CV_WINDOW_AUTOSIZE); 13 imshow(win_name, img); 14 } 15 16 int main(void) 17 { 18 Mat src = imread("lena.jpg"); 19 if (src.empty()) 20 return -1; 21 showImg("Src", src); 22 23 24 Mat dst; 25 Mat map_x; 26 Mat map_y; 27 dst.create(src.size(), src.type());//目标图像与原图像大小类型均需相同 28 map_x.create(src.size(), CV_32FC1);//映射的变换矩阵与原图像大小相同,类型固定 29 map_y.create(src.size(), CV_32FC1); 30 31 for (int i = 0; i < src.rows; ++i)//对每一行 32 { 33 for (int j = 0; j < src.rows; ++j)//对每一列 34 { 35 map_x.at<float>(i, j) = src.cols - j;//对于每行的每一列像素都用相应的翻转像素填充--水平翻转 36 map_y.at<float>(i, j) = i;//保持 37 } 38 } 39 remap(src, dst, map_x,map_y,CV_INTER_LINEAR,BORDER_CONSTANT,Scalar(0,0,0)); 40 41 showImg("dst", dst); 42 waitKey(); 43 return 0; 44 }
结果:
3.垂直翻转
1 #include <opencv2\opencv.hpp> 2 #include <iostream> 3 #include <string> 4 5 #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) 6 7 using namespace std; 8 using namespace cv; 9 10 void showImg(const string &win_name, const Mat &img) 11 { 12 namedWindow(win_name, CV_WINDOW_AUTOSIZE); 13 imshow(win_name, img); 14 } 15 16 int main(void) 17 { 18 Mat src = imread("lena.jpg"); 19 if (src.empty()) 20 return -1; 21 showImg("Src", src); 22 23 24 Mat dst; 25 Mat map_x; 26 Mat map_y; 27 dst.create(src.size(), src.type());//目标图像与原图像大小类型均需相同 28 map_x.create(src.size(), CV_32FC1);//映射的变换矩阵与原图像大小相同,类型固定 29 map_y.create(src.size(), CV_32FC1); 30 31 for (int i = 0; i < src.rows; ++i)//对每一行 32 { 33 for (int j = 0; j < src.rows; ++j)//对每一列 34 { 35 map_x.at<float>(i, j) = j;//保持 36 map_y.at<float>(i, j) =src.rows - i;//对于每列的每一行像素都用相应的翻转像素填充--垂直翻转 37 } 38 } 39 remap(src, dst, map_x,map_y,CV_INTER_LINEAR,BORDER_CONSTANT,Scalar(0,0,0)); 40 41 showImg("dst", dst); 42 waitKey(); 43 return 0; 44 }
结果:
4.缩小显示
1 #include <opencv2\opencv.hpp> 2 #include <iostream> 3 #include <string> 4 5 #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) 6 7 using namespace std; 8 using namespace cv; 9 10 void showImg(const string &win_name, const Mat &img) 11 { 12 namedWindow(win_name, CV_WINDOW_AUTOSIZE); 13 imshow(win_name, img); 14 } 15 16 int main(void) 17 { 18 Mat src = imread("lena.jpg"); 19 if (src.empty()) 20 return -1; 21 showImg("Src", src); 22 23 24 Mat dst; 25 Mat map_x; 26 Mat map_y; 27 dst.create(src.size(), src.type());//目标图像与原图像大小类型均需相同 28 map_x.create(src.size(), CV_32FC1);//映射的变换矩阵与原图像大小相同,类型固定 29 map_y.create(src.size(), CV_32FC1); 30 31 for (int i = 0; i < src.rows; ++i)//对每一行 32 { 33 for (int j = 0; j < src.rows; ++j)//对每一列 34 { 35 //横竖缩放到原来的一半 36 if (j > src.cols*0.25 && j < src.cols*0.75 && i > src.rows*0.25 && i < src.rows*0.75) 37 { 38 map_x.at<float>(i, j) = 2 * (j - src.cols*0.25) + 0.5;//采样 39 map_y.at<float>(i, j) = 2 * (i - src.rows*0.25) + 0.5; 40 } 41 else 42 { 43 map_x.at<float>(i, j) = 0;//被0位置处的元素填充 44 map_y.at<float>(i, j) = 0; 45 } 46 } 47 } 48 remap(src, dst, map_x,map_y,CV_INTER_LINEAR,BORDER_CONSTANT,Scalar(0,0,0)); 49 50 showImg("dst", dst); 51 waitKey(); 52 return 0; 53 }
结果:
还有其他的有趣操作,可以自行研究算法自己实现。
以上。
时间: 2024-10-10 05:30:11