[英]OpenCV pointer to bitmap processing
I've created a shared library for contour detection that is loaded from a Delphi/Lazarus application. 我已经创建了一个从Delphi / Lazarus应用程序加载的轮廓检测共享库。 The main app, passes a pointer to a bitmap to be processed by a function inside the library. 主应用程序将指针传递给位图,该指针由库内的函数处理。
Here's the function inside the library. 这是库中的功能。 The parameter "img" is the pointer to my bitmap. 参数“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;
}
}
}
From the Delphi side, I'm passing a pointer to an array of this structure: 从Delphi方面,我传递一个指向这个结构数组的指针:
TBGRAPixel = packed record
blue, green, red, alpha: byte;
end;
I need to process the bitmap in-memory, that's why I'm not loading the file from inside the library. 我需要在内存中处理位图,这就是我没有从库中加载文件的原因。
The question is: Is this the right way to assign a bitmap to a cv::Mat ? 问题是:这是将位图分配给cv :: Mat的正确方法吗?
I ask this because the code works without problems in Linux, but fails on Windows compiled with Mingw. 我问这个是因为代码在Linux中没有问题,但在使用Mingw编译的Windows上失败了。
Note: it fails with a SIGSEGV on this line: 注意:它在此行上失败并带有SIGSEGV:
blur( src_gray, src_gray, Size(10,10) );
EDIT: The SIGSEGV is raised only if I compile OpenCV in Release mode, in Debug mode it works ok. 编辑:只有我在发布模式下编译OpenCV时才会引发SIGSEGV,在调试模式下它可以正常工作。
Thanks in advance, Leonardo. 提前谢谢,莱昂纳多。
So you are creating an image this way: 所以你用这种方式创建一个图像:
Mat src(imgHeight, imgWidth, CV_8UC4);
int idx;
src.data = img;
The first declaration and instantiation Mat src(imgHeight, imgWidth, CV_8UC4) will allocate memory for a new image and a reference counter that automatically keeps track of the number of references to the allocated memory. 第一个声明和实例化Mat src(imgHeight,imgWidth,CV_8UC4)将为新映像和引用计数器分配内存,该计数器自动跟踪分配的内存的引用数。 Then you mutate an instance variable through 然后通过改变实例变量
src.data = img; src.data = img;
When the the instance src goes out of scope, the destructor is called and most likely tries to deallocate the memory at src.data, which you assigned and this might cause a segmentation fault. 当实例src超出范围时,析构函数被调用,并且很可能尝试在您指定的src.data处释放内存,这可能会导致分段错误。 The right way to do it is to not change instance variable of an object, but to simply use the right constructor when you instantiate src: 正确的方法是不更改对象的实例变量,而是在实例化src时简单地使用正确的构造函数:
Mat src(imgHeight, imgWidth, CV_8UC4, img);
This way, you just create a matrix header and no reference counter or deallocation will be performed by the destructor of src. 这样,您只需创建一个矩阵头,并且src的析构函数不会执行引用计数器或释放。
Good luck! 祝好运!
EDIT: I am not sure that the segfault is actually caused by an attempt to deallocate memory incorrectly, but it is a good practice not to break data abstraction by assigning directly to instance variables. 编辑:我不确定segfault实际上是由于尝试不正确地释放内存引起的,但最好不要通过直接分配给实例变量来破坏数据抽象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.