我目前正在编写BLOB检测算法。当我运行它时,我收到错误
blobdetector.exe中0x00007FF70476CDA7处的未处理异常:0xC0000005:
访问冲突读取位置0x0000007BDDA0347D。
这是代码中断的部分。
调试器在if(val == 255)
void connectivity(BlobBurnMat temp, size_t y, size_t x){
uchar* ptr = (uchar*)temp.getTemp().data;
size_t min_y = temp.getTemp().rows, min_x = temp.getTemp().cols, max_y = 0, max_x = 0;
for (int i = 0; i < 4; i++){
int kernel[4][2] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
int temp_y = y + kernel[i][0];
int temp_x = x + kernel[i][1];
uchar val = ptr[temp.getTemp().step * temp_y + temp_x]; //breaks here
if (val == 255) {
temp.setValZero(x, y);
x = temp_x;
y = temp_y;
if (temp_x > max_x)
max_x = temp_x;
if(temp_x < min_x)
min_x = temp_x;
if (temp_y > max_y)
max_y = temp_y;
if (temp_y < min_y)
min_y = temp_y;
int pass_x = ((max_x - min_x) / 2);
int pass_y((max_y - min_y) / 2);
setCoordinates(pass_x, pass_y);
connectivity(temp, y, x);
}
}
}
这是代码的其余部分。上述connectivity()
方法位于BLOB
类。
#include "opencv2/opencv.hpp"
#include<stdio.h>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
using namespace std;
class BlobBurnMat{
//Class used to store a copy of the source image where pixels get burned in BLOB finding.
private:
Mat temp;
public:
void initiate(Mat temp){
this -> temp = temp;
}
Mat getTemp(){
return temp;
}
void setValZero(int x, int y){
temp.at<uchar>(y, x) = 0;
}
};
class BLOB{
//BLOB class to store coordinates of the BLOBs before they are added to the vector-array-list-thingamajig
private:
int x, y;
public:
void setCoordinates(int x, int y){
this->x = x;
this->y = y;
}
int getX(){
return x;
}
int getY(){
return y;
}
void connectivity(BlobBurnMat temp){
connectivity(temp, x, y);
}
void connectivity(BlobBurnMat temp, int y, int x){
uchar* ptr = (uchar*)temp.getTemp().data;
int min_y = temp.getTemp().rows, min_x = temp.getTemp().cols, max_y = 0, max_x = 0;
for (int i = 0; i < 4; i++){
int kernel[4][2] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
int temp_y = y + kernel[i][0];
int temp_x = x + kernel[i][1];
uchar val = ptr[temp.getTemp().step * temp_y + temp_x];
if (val == 255) {
temp.setValZero(x, y);
x = temp_x;
y = temp_y;
if (temp_x > max_x)
max_x = temp_x;
if(temp_x < min_x)
min_x = temp_x;
if (temp_y > max_y)
max_y = temp_y;
if (temp_y < min_y)
min_y = temp_y;
int pass_x = ((max_x - min_x) / 2);
int pass_y((max_y - min_y) / 2);
setCoordinates(pass_x, pass_y);
connectivity(temp, y, x);
}
}
}
};
vector<Point2i> getBlobCoordinates(Mat src){
BlobBurnMat *temp = new BlobBurnMat();
temp->initiate(src.clone());
vector<Point2i> blobCoordinates; //Vector holding all BLOB coordinates
Point2i blobCoords; //Coordinates of a single BLOB
//Go through the binary matrix looking for white pixels.
for (size_t y = 0; y < src.rows; y++) {
for (size_t x = 0; x < src.cols; x++) {
uchar* ptr = (uchar*)temp->getTemp().data;
uchar val = ptr[temp->getTemp().step * y + x];
if (val == 255){
BLOB *blob = new BLOB();
blob->setCoordinates(x, y);
blob->connectivity(*temp);
blobCoords.x = blob->getX();
blobCoords.y = blob->getY();
blobCoordinates.push_back(blobCoords); //add a new element to the vector.
}
}
}
return blobCoordinates;
}
int main(int, char){
Mat src;
String path = "C:/Users/Runagar/Desktop/segment.jpg";
src = imread(path, 0);
if (src.data && !src.empty()){
imshow("blobie", src);
}
else cout << "You fucked up ";
vector <Point2i> blobCoordinates = getBlobCoordinates(src);
for (int k = 0; k < blobCoordinates.size(); k++)
cout << blobCoordinates[k];
waitKey(0);
return 0;
}
提前致谢!
答案 0 :(得分:1)
当i == 2且x == 0时,temp_x == -1所以你在分配内存之外的ptr之前读取1个字节。
当x == 0,y == 0,x == src.cols和y == src.rows时,你必须处理这种情况。
答案 1 :(得分:0)
Mat getTemp()
会返回您的Mat实例的副本。
uchar* ptr = (uchar*)temp.getTemp().data;
从临时Mat实例中检索指针。然后立即删除此实例,并留下指向(可能)正确删除的数据的指针。
请尝试Mat & getTemp()
。