欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OpenCV Mat数据类型指针ptr的使用

程序员文章站 2022-05-16 11:23:49
...
    cv::Mat image = cv::Mat(400, 600, CV_8UC1); //宽400,长600
    uchar * data00 = image.ptr<uchar>(0);
    uchar * data10 = image.ptr<uchar>(1);
    uchar * data01 = image.ptr<uchar>(0)[1];
  • 1
  • 2
  • 3
  • 4

解释:

  • 定义了一个Mat变量image。
  • data00是指向image第一行第一个元素的指针。
  • data10是指向image第二行第一个元素的指针。
  • data01是指向image第一行第二个元素的指针。

注意: 
如果你的程序使用来image.ptr指针,并且出现了下面这样的错误:(假设你使用的软件是Visual Studio 201x)

某某.exe中的 0x75065b68 处有未经处理的异常:Microsoft C++ 异常; 内存位置0x85e790处的cv::Exception
  • 1

这可能是因为你不理解image.ptr这个指针,犯了这样的错误:image.ptr(1);指的不是image中第二个像素,而是第一行第二个像素的指针。 
使用上面的代码举例:image有400行,有400*600个像素。假设现在你想得到第3行第42个像素的指针,如果你写成:

uchar * data = image.ptr<uchar>(3*image.cols + 41);
  • 1

这样写是错误的,会出现上面的错误。你得到的不是第3行第42个像素的指针,而是第(3×image.cols + 41)行第0个像素的指针,因为没有(3×image.cols + 41)行,所以没有这个指针,所以错误。 
正确的写法:

uchar * data = image.ptr<uchar>(3)[41];
  • 1

所以要注意这一点:如果程序可以正常编译,但是运行时出错,很有可能是你给指针赋值的时候,索引值溢出指定范围,指针乱指,导致程序跑偏,所以只有在运行时才能发现错误


  • 1
  • 2
  • 3
  • 4
  • 5
    cv::Mat image = cv::Mat(400, 600, CV_8UC3); //宽400,长600,3通道彩色图片
    cv::Vec3b * data000 = image.ptr<cv::Vec3b>(0);
    cv::Vec3b * data100 = image.ptr<cv::Vec3b>(1);
    cv::Vec3b * data001 = image.ptr<cv::Vec3b>(0)[1];
    cv::Vec3b * data
  1. void colorReduce11(cv::Mat &image, int div=64) {  
  2.       int nr= image.rows; // number of rows  
  3.       int nc= image.cols; // number of columns  
  4.       for (int j=0; j<nr; j++) {  
  5.           for (int i=0; i<nc; i++) {  
  6.                   image.at<cv::Vec3b>(j,i)[0]=     image.at<cv::Vec3b>(j,i)[0]/div*div + div/2;  
  7.                   image.at<cv::Vec3b>(j,i)[1]=     image.at<cv::Vec3b>(j,i)[1]/div*div + div/2;  
  8.                   image.at<cv::Vec3b>(j,i)[2]=     image.at<cv::Vec3b>(j,i)[2]/div*div + div/2;  
  9.             } // end of row                   
  10.       }  
  11. }