gpt4 book ai didi

c++ - OpenCV 指向位图处理的指针

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:46:45 24 4
gpt4 key购买 nike

我创建了一个从 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) );

编辑:仅当我在 Release模式下编译 OpenCV 时才会引发 SIGSEGV,在 Debug模式下它工作正常。

提前致谢,莱昂纳多。

最佳答案

因此您正在以这种方式创建图像:

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

祝你好运!

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

关于c++ - OpenCV 指向位图处理的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8015084/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com