OpenCV 几何变换-图像镜像

分手后的思念是犯贱 2022-06-15 22:15 484阅读 0赞

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

  1. #include <opencv/highgui.h>
  2. #include <time.h>
  3. #include <opencv2/opencv.hpp>
  4. #include <opencv/cv.h>
  5. #include <iostream>
  6. using namespace std;
  7. using namespace cv;
  8. int main()
  9. {
  10. Mat SrcImage = imread("1.jpg",0);
  11. imshow("原图",SrcImage);
  12. Mat dst;
  13. dst.create( SrcImage.size(), SrcImage.type());
  14. Mat map_x;
  15. Mat map_y;
  16. map_x.create( SrcImage.size(), CV_32FC1);
  17. map_y.create( SrcImage.size(), CV_32FC1);
  18. for( int i = 0; i < SrcImage.rows; i++)
  19. {
  20. for( int j = 0; j < SrcImage.cols; j++)
  21. {
  22. //map_x.at<float>(i, j) = (float) (SrcImage.cols - j-1) ;
  23. //map_y.at<float>(i, j) = (float) i ; //水平
  24. map_x.at<float>(i, j) = (float) j ;
  25. map_y.at<float>(i, j) = (float) (SrcImage.rows - i-1) ; //垂直
  26. }
  27. }
  28. remap(SrcImage, dst, map_x, map_y, CV_INTER_LINEAR);
  29. imshow("镜像图", dst);
  30. waitKey(0);
  31. return 0;
  32. }

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

  1. CV_EXPORTS_W void remap(
  2. InputArray src,
  3. OutputArray dst,
  4. InputArray map1,
  5. InputArray map2,
  6. int interpolation,
  7. int borderMode=BORDER_CONSTANT,
  8. const Scalar& borderValue=Scalar());

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

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

  1. for( int i = 0; i < SrcImage.rows; i++)
  2. {
  3. for( int j = 0; j < SrcImage.cols; j++)
  4. {
  5. //map_x.at<float>(i, j) = (float) (SrcImage.cols - j-1) ;
  6. //map_y.at<float>(i, j) = (float) i ; //水平
  7. map_x.at<float>(i, j) = (float) j ;
  8. map_y.at<float>(i, j) = (float) (SrcImage.rows - i-1) ; //垂直
  9. }
  10. }

矩阵的赋值就是在这里实现的:
假设原图像为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矩阵中放的根本就不是像素的灰度,而是映射前后的位置。

这里写图片描述

这里写图片描述

这里写图片描述

发表评论

表情:
评论列表 (有 0 条评论,484人围观)

还没有评论,来说两句吧...

相关阅读

    相关 OpenCV 几何变换-图像缩放

    图像的缩放主要用于改变图像的大小,缩放后图像的图像的宽度和高度会发生变化。在图像处理中是一种很基础的几何变换,但是具有很重要的作用,比如:当输入图片尺寸过大时,处理速度会很慢,

    相关 图像几何变换

    包含相同内容的两幅图像可能由于成像角度、透视关系乃至镜头自身原因所造成的几何失 真而呈现出截然不同的外观,这就给观测者或是图像识别程序带来了困扰。通过适当的几何变 换可