【问题标题】:OpenCV pointer to bitmap processing指向位图处理的 OpenCV 指针
【发布时间】:2011-11-04 20:02:21
【问题描述】:

我创建了一个从 Delphi/Lazarus 应用程序加载的轮廓检测共享库。主应用程序传递一个指向位图的指针,以由库内的函数处理。

这是库中的函数。参数“img”是指向我的位图的指针。

extern "C" {

  void detect_contour(int imgWidth, int imgHeight, unsigned char * img, int &x, int &y, int &w, int &h)
  {
    Mat threshold_output;
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;

    Mat src_gray;
    int thresh = 100;
        int max_thresh = 255;
    RNG rng(12345);

    /// Load source image and convert it to gray
    Mat src(imgHeight, imgWidth, CV_8UC4);
    int idx;

    src.data = img;

    /// Convert image to gray and blur it
    cvtColor( src, src_gray, CV_BGRA2GRAY );

    blur( src_gray, src_gray, Size(10,10) );

    /// Detect edges using Threshold
    threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );
    /// Find contours
    findContours( threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );

    /// Approximate contours to polygons + get bounding rects and circles
    vector<vector<Point> > contours_poly( contours.size() );
    vector<Rect> boundRect( contours.size() );
    vector<Point2f>center( contours.size() );
    vector<float>radius( contours.size() );

    int lArea = 0;
    int lBigger = -1;

    for( int i = 0; i < contours.size(); i++ )
       { 
         approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
         boundRect[i] = boundingRect( Mat(contours_poly[i]) );
         if(lArea < boundRect[i].width * boundRect[i].height)
         {
           lArea = boundRect[i].width * boundRect[i].height;
           lBigger = i;
         }
       }

    if(lBigger > -1)
    {
       x = boundRect[lBigger].x;
       y = boundRect[lBigger].y;
       w = boundRect[lBigger].width;
       h = boundRect[lBigger].height;
    }
  }
}

在 Delphi 方面,我传递了一个指向此结构数组的指针:

TBGRAPixel = packed record
  blue, green, red, alpha: byte;
end; 

我需要在内存中处理位图,这就是我不从库中加载文件的原因。

问题是:这是将位图分配给 cv::Mat 的正确方法吗?

我问这个是因为代码在 Linux 中运行没有问题,但在使用 Mingw 编译的 Windows 上失败。

注意:此行出现 SIGSEGV 失败:

blur( src_gray, src_gray, Size(10,10) );

编辑:仅当我在发布模式下编译 OpenCV 时才会引发 SIGSEGV,在调试模式下它可以正常工作。

提前致谢, 莱昂纳多。

【问题讨论】:

    标签: c++ delphi opencv freepascal lazarus


    【解决方案1】:

    所以你是这样创建图像的:

    Mat src(imgHeight, imgWidth, CV_8UC4);
    int idx;
    
    src.data = img;
    

    第一次声明和实例化 Mat src(imgHeight, imgWidth, CV_8UC4) 将为新图像和引用计数器分配内存,该计数器自动跟踪对分配内存的引用数。 然后你通过

    改变一个实例变量

    src.data = img;

    当实例 src 超出范围时,会调用析构函数,并且很可能会尝试释放您分配的 src.data 中的内存,这可能会导致分段错误。正确的做法是不要更改对象的实例变量,而是在实例化 src 时简单地使用正确的构造函数:

    Mat src(imgHeight, imgWidth, CV_8UC4, img);
    

    这样,你只需创建一个矩阵头,src的析构函数不会执行引用计数器或释放。

    祝你好运!

    编辑:我不确定段错误实际上是由尝试不正确地释放内存引起的,但最好不要通过直接分配给实例变量来破坏数据抽象。

    【讨论】:

    • 谢谢乔纳斯。我尝试了你的建议,它在 Linux 上运行,但 SIGSEGV 在 Windows 上仍然存在。
    猜你喜欢
    • 2014-06-05
    • 1970-01-01
    • 1970-01-01
    • 2017-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-11
    相关资源
    最近更新 更多