Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 指向位图处理的OpenCV指针_C++_Delphi_Opencv_Freepascal_Lazarus - Fatal编程技术网

C++ 指向位图处理的OpenCV指针

C++ 指向位图处理的OpenCV指针,c++,delphi,opencv,freepascal,lazarus,C++,Delphi,Opencv,Freepascal,Lazarus,我创建了一个用于轮廓检测的共享库,该库是从Delphi/Lazarus应用程序加载的。主应用程序传递一个指向位图的指针,该位图将由库中的函数处理 这是库中的函数。参数“img”是指向位图的指针 extern "C" { void detect_contour(int imgWidth, int imgHeight, unsigned char * img, int &x, int &y, int &w, int &h) { Mat thresho

我创建了一个用于轮廓检测的共享库,该库是从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;
    }
  }
}
我需要在内存中处理位图,这就是我没有从库中加载文件的原因

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

我这样问是因为代码在Linux中工作没有问题,但在使用Mingw编译的Windows上失败

注:此线路上的SIGSEGV故障:

blur( src_gray, src_gray, Size(10,10) );
编辑:只有当我在发布模式下编译OpenCV时,SIGSEGV才会启动,在调试模式下它工作正常

提前感谢,,
莱昂纳多。

因此,您可以通过以下方式创建图像:

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的析构函数不会执行引用计数器或释放

祝你好运


编辑:我不确定segfault是否是由于试图错误地释放内存而导致的,但最好不要通过直接分配给实例变量来中断数据抽象。

谢谢Jonas。我尝试了你的建议,它在Linux上运行,但SIGSEGV在Windows上仍然存在。
Mat src(imgHeight, imgWidth, CV_8UC4, img);