当前位置:   article > 正文

OpenCV 图像重映射函数remap()实例详解

OpenCV 图像重映射函数remap()实例详解

         OpenCV 图像重映射函数remap()对图像应用通用几何变换。其原型如下:

        void remap(InputArray  src, 

                             OutputArray dst,

                               InputArray  map1,

                               InputArray map2,

                                int   interpolation,

                                int borderMode = BORDER_CONSTANT,

                                const Scalar & borderValue = Scalar()

           )

   参数:

       src 源图像。

       dst 输出目标图像。它的大小与 map1 相同,类型与 src 相同。

       map1 (x,y) 点或仅 x 值的第一个映射具有 CV_16SC2 、 CV_32FC1 或 CV_32FC2                                 类型。

                    map2  y 值的第二个映射分别具有 CV_16UC1、CV_32FC1 类型或无类型(如果映射         1 是 (x,y) 点,则为空映射)。

                      interpolation 插值方法,可选:  INTER_NEAREST,                                                                                                                           INTER_LINEAR ,                                                                                                                              INTER_CUBIC,                                                                                                                                INTER_LANCZOS4,                                                                                                              INTER_NEAREST_EXACT                                                                                                                INTER_MAX                                                                                                                                      WARP_FILL_OUTLIERS ,                                                                     WARP_INVERSE_MAP 

                        borderMode 像素外推法。当 borderMode=BORDER_TRANSPARENT 时,意味                着目标图像中与源图像中的“异常值”相对应的像素不会被该函数修改。可为:BORDER_CONSTANT ,BORDER_REPLICATE,BORDER_REFLECT,BORDER_WRAP ,BORDER_REFLECT_101 ,BORDER_TRANSPARENT ,BORDER_REFLECT101 ,BORDER_DEFAULT,BORDER_ISOLATED

                        borderValue 在边界恒定的情况下使用的值。默认值为 0。

        OpenCV的remap函数的主要用途是重新映射图像中像素的位置或值。用它可以实现图像镜像、形态改变、特效制作、图像分割等。下面以例演示 其用法。先写一个示例程序,读入一张图片然后,用remap函数分别获取水平镜像图片,示例程序代码如下:

  1. // RemapTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
  2. #include<opencv2/opencv.hpp>
  3. #include <iostream>
  4. using namespace cv;
  5. using namespace std;
  6. int main()
  7. {
  8. Mat src = imread("1.png");
  9. if (src.empty())
  10. {
  11. cout << "Cann't load Image!";
  12. return -1;
  13. }
  14. imshow("原始图像:",src);
  15. Mat srcx(src.rows, src.cols, CV_32F); // x 方向
  16. Mat srcy(src.rows, src.cols, CV_32F); // y 方向
  17. for (size_t i = 0; i < src.rows; i++)
  18. {
  19. for (int j = 0; j < src.cols; j++)
  20. {
  21. srcx.at<float>(i, j) = src.cols - j - 1;
  22. srcy.at<float>(i, j) = i;
  23. }
  24. }
  25. remap(src, src, srcx, srcy, INTER_LINEAR);
  26. imshow("水平镜像:", src);
  27. waitKey(0);
  28. return 1;
  29. }

试运行,结果如下:

       获取垂直镜像,其代码如下:

  1. // RemapTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
  2. #include<opencv2/opencv.hpp>
  3. #include <iostream>
  4. using namespace cv;
  5. using namespace std;
  6. int main()
  7. {
  8. Mat src = imread("1.png");
  9. if (src.empty())
  10. {
  11. cout << "Cann't load Image!";
  12. return -1;
  13. }
  14. imshow("原始图像:",src);
  15. Mat srcx(src.rows, src.cols, CV_32F); // x 方向
  16. Mat srcy(src.rows, src.cols, CV_32F); // y 方向
  17. //水平镜像
  18. /*
  19. for (size_t i = 0; i < src.rows; i++)
  20. {
  21. for (int j = 0; j < src.cols; j++)
  22. {
  23. srcx.at<float>(i, j) = src.cols - j - 1;
  24. srcy.at<float>(i, j) = i;
  25. }
  26. }
  27. remap(src, src, srcx, srcy, INTER_LINEAR);
  28. imshow("水平镜像:", src);
  29. */
  30. //垂直镜像
  31. for (size_t i = 0; i < src.rows; i++)
  32. {
  33. for (int j = 0; j < src.cols; j++)
  34. {
  35. srcx.at<float>(i, j) = j;
  36. srcy.at<float>(i, j) = src.rows -i -1;
  37. }
  38. }
  39. remap(src, src, srcx, srcy, INTER_LINEAR);
  40. imshow("垂直镜像:", src);
  41. waitKey(0);
  42. return 1;
  43. }

       试运行结果如下:

  再写一段改变图形形状的代码,代码如下:

  1. // RemapTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
  2. #include<opencv2/opencv.hpp>
  3. #include <iostream>
  4. using namespace cv;
  5. using namespace std;
  6. int main()
  7. {
  8. Mat src = imread("1.png");
  9. if (src.empty())
  10. {
  11. cout << "Cann't load Image!";
  12. return -1;
  13. }
  14. imshow("原始图像:",src);
  15. Mat srcx(src.rows, src.cols, CV_32F); // x 方向
  16. Mat srcy(src.rows, src.cols, CV_32F); // y 方向
  17. //水平镜像
  18. /*
  19. for (size_t i = 0; i < src.rows; i++)
  20. {
  21. for (int j = 0; j < src.cols; j++)
  22. {
  23. srcx.at<float>(i, j) = src.cols - j - 1;
  24. srcy.at<float>(i, j) = i;
  25. }
  26. }
  27. remap(src, src, srcx, srcy, INTER_LINEAR);
  28. imshow("水平镜像:", src);
  29. */
  30. //垂直镜像
  31. /*
  32. for (size_t i = 0; i < src.rows; i++)
  33. {
  34. for (int j = 0; j < src.cols; j++)
  35. {
  36. srcx.at<float>(i, j) = j;
  37. srcy.at<float>(i, j) = src.rows -i -1;
  38. }
  39. }
  40. remap(src, src, srcx, srcy, INTER_LINEAR);
  41. imshow("垂直镜像:", src);
  42. */
  43. //改变图像形状
  44. for (size_t i = 0; i < src.rows; i++)
  45. {
  46. for (int j = 0; j < src.cols; j++)
  47. {
  48. srcx.at<float>(i, j) = j;
  49. srcy.at<float>(i, j) = i + 5.0 * cos(i / 5.0);
  50. }
  51. }
  52. remap(src, src, srcx, srcy, INTER_LINEAR);
  53. imshow("改变图形形状:", src);
  54. waitKey(0);
  55. return 1;
  56. }

       割裂效果呈现,实现的程序代码如下:

  1. // RemapTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
  2. #include<opencv2/opencv.hpp>
  3. #include <iostream>
  4. using namespace cv;
  5. using namespace std;
  6. int main()
  7. {
  8. Mat src = imread("1.png");
  9. if (src.empty())
  10. {
  11. cout << "Cann't load Image!";
  12. return -1;
  13. }
  14. imshow("原始图像:",src);
  15. Mat srcx(src.rows, src.cols, CV_32F); // x 方向
  16. Mat srcy(src.rows, src.cols, CV_32F); // y 方向
  17. //水平镜像
  18. /*
  19. for (size_t i = 0; i < src.rows; i++)
  20. {
  21. for (int j = 0; j < src.cols; j++)
  22. {
  23. srcx.at<float>(i, j) = src.cols - j - 1;
  24. srcy.at<float>(i, j) = i;
  25. }
  26. }
  27. remap(src, src, srcx, srcy, INTER_LINEAR);
  28. imshow("水平镜像:", src);
  29. */
  30. //垂直镜像
  31. /*
  32. for (size_t i = 0; i < src.rows; i++)
  33. {
  34. for (int j = 0; j < src.cols; j++)
  35. {
  36. srcx.at<float>(i, j) = j;
  37. srcy.at<float>(i, j) = src.rows -i -1;
  38. }
  39. }
  40. remap(src, src, srcx, srcy, INTER_LINEAR);
  41. imshow("垂直镜像:", src);
  42. */
  43. //改变图像形状
  44. /*
  45. for (size_t i = 0; i < src.rows; i++)
  46. {
  47. for (int j = 0; j < src.cols; j++)
  48. {
  49. srcx.at<float>(i, j) = j;
  50. srcy.at<float>(i, j) = i + 5.0 * cos(i / 5.0);
  51. }
  52. }
  53. remap(src, src, srcx, srcy, INTER_LINEAR);
  54. imshow("改变图形形状:", src);
  55. */
  56. //割裂效果呈现
  57. for (size_t i = 0; i < src.rows; i++)
  58. {
  59. for (int j = 0; j < src.cols; j++)
  60. {
  61. srcx.at<float>(i, j) = j + 10.0 * tan(j / 5.0);;
  62. srcy.at<float>(i, j) = i;
  63. }
  64. }
  65. remap(src, src, srcx, srcy, INTER_LINEAR);
  66. imshow("割裂效果:", src);
  67. waitKey(0);
  68. return 1;
  69. }

 试运行,结果如下:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/255142
推荐阅读
相关标签
  

闽ICP备14008679号