(NB : Sorry for my bad english...)
Hi everyone, I need help woth my code (C++) : I need to label regions from a greyscale image using OpenCV.
To do that, I'm initializing a new matrix to zeros.
I search for the first 0 (non labeled pixel), get the coordinates and begin the recursivity : I look at its 8 neighbors. For each : If the pixel exists (if the pixel i'm currently using is not on the edges), then if the "distance" between the current pixel and his neighbor is inferior to a threshold, than I put it in the same region (same label) and had it to a list.
As long as the list isn't empty, I pick another pixel from the same region and start again (pixels in the list).
When a region doesn't have anymore pixel to work with, and if all the pixels aren't labeled, I start a new region and so on.
So probleme is, after several pixels, I get a segmentation fault, which is, according to gdb, a problem coming from std::list.back() with a "Cannot access memory adresse ...".
I started using a std:list of pair. I'm now just using a std::list with 2 push_front to add coordinates in the list, and 2 back (followed by pop_back) to get them back.
I tried with vectors without any good result.
When I use little pictures (64x64), it works without problem. But when it comes to bigger pictures / non-square pictures, I always get a segmentation fault (which, using gdb, seems to be at "int b = listePix.back()").
Thank you.
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/contrib/contrib.hpp>
#include <iostream>
#include <stdio.h>
#include <utility>
#include <list>
using namespace cv;
using namespace std;
void agregation(Mat src, Mat dst);
void expendReg(Mat src, Mat dst, int compteur);
pair<int,int> premiereOcc(Mat dst);
std::list <int> listePix;
int seuil = 20;
int main( int argc, char** argv )
{
Mat image;
image = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
Mat reg = Mat::zeros(image.rows, image.cols, 0);
agregation(image,reg);
cout << "WORKED" << endl;
waitKey(0);
return 0;
}
void agregation(Mat src, Mat dst){
bool flag = 0;
int compteur = 0;
do{
compteur++;
pair<int,int> coord = premiereOcc(dst);
if(coord.first == -1 || coord.second == -1){
flag = 1;
}
else{
int pm = coord.first;
int pn = coord.second;
dst.at<uchar>(pm,pn) = compteur;
listePix.push_front(pn);
listePix.push_front(pm);
expendReg(src,dst,compteur);
listePix.clear();
}
}while(!flag);
}
void expendReg(Mat src, Mat dst, int compteur){
if(listePix.size()>=2){
int b = listePix.back();
listePix.pop_back();
int a = listePix.back();
listePix.pop_back();
int dist;
if((a+1)<dst.rows){
dist = abs(src.at<uchar>(a,b) - src.at<uchar>(a+1,b));
int temp = dst.at<uchar>(a+1,b);
if((dist<=seuil) && (temp == 0)){
dst.at<uchar>(a+1,b) = compteur;
listePix.push_front(b);
listePix.push_front(a+1);
}
}
if((b+1)<dst.cols){
dist = abs(src.at<uchar>(a,b) - src.at<uchar>(a,b+1));
int temp = dst.at<uchar>(a,b+1);
if((dist<=seuil) && (temp == 0)){
dst.at<uchar>(a,b+1) = compteur;
listePix.push_front(b+1);
listePix.push_front(a);
}
}
expendReg(src,dst,compteur);
}
}
pair<int,int> premiereOcc(Mat dst){
//Return the coord of the first pixel without region
for(int i = 0; i<dst.rows; i++){
for(int j = 0; j<dst.cols; j++){
int tmp = dst.at<uchar>(i,j);
if(tmp == 0){
pair<int,int> coord = make_pair(i,j);
return coord;
}
}
}
pair<int,int> coord = make_pair(-1,-1);
return coord;
}
EDIT2 : Image i'm using : https://www.bogotobogo.com/Matlab/images/MATLAB_DEMO_IMAGES/blobs.png