I tried to implement the labeling algorithm . I adaped an ancien version using IplImage to Map but I am still in trouble .Any idea is welcomed . Thank you very much
const char * const IMAGE_INITIALE = "Initial";
const char * const IMAGE_FINALE = "Final colored image";
using namespace cv;
using namespace std;
Mat initial_image;
int** table_equivalence = new int*;
class RelatePixel {
public:
RelatePixel(int value, RelatePixel * upneighbour, RelatePixel * leftneighbour);
//Mapping
static RelatePixel*** imageToRelatePixelArray(Mat image);
static Mat RelatePixelArrayToImage(RelatePixel** pixels, int nbRows, int nbCol);
//Getters/Setters
void SetLabel(int label);
int GetLabel() const;
RelatePixel* GetVGauche() const;
RelatePixel* GetVHaut() const;
char GetValeur() const;
void SetValeur(char value);
//Utils
bool isNotNull();
ostream& operator<<(ostream &flux);
private:
char value;
int label;
RelatePixel * vUp;
RelatePixel * vLeft;
};
RelatePixel::RelatePixel(int color, RelatePixel * upneighbour, RelatePixel * leftneighbour){
this->value = color;
this->vUp = upneighbour;
this->vLeft = leftneighbour;
this->label = -1;
}
char RelatePixel::GetValeur() const {
return value;
}
void RelatePixel::SetValeur(char value) {
this->value = value;
}
RelatePixel* RelatePixel::GetVGauche() const {
return vLeft;
}
RelatePixel* RelatePixel::GetVHaut() const {
return vUp;
}
void RelatePixel::SetLabel(int label) {
this->label = label;
this->value = 0;//TODO delete
}
int RelatePixel::GetLabel() const {
return label;
}
/**
* Convertit une image en un tableau de RelatePixel
* @param image l'image à modifier
* @return le tableau de RelatePixel correspondant à l'image
*/
RelatePixel*** RelatePixel::imageToRelatePixelArray(Mat image){
cout<<"imageToRelatePixelArray begins"<<endl;
int nbCol = image.cols;
int nbLigne = image.rows;
RelatePixel*** pixels = new RelatePixel**[nbLigne];
int i,j;
RelatePixel * up,* left;
for (i=0; i<nbLigne; i++){
pixels[i] = new RelatePixel*[nbCol];
for (j=0; j<nbCol; j++){
//first line (not neighbour up)
if (i == 0) {
up = NULL;
} else {
up = pixels[i-1][j];
}
//first column (not neighbour left)
if (j == 0) {
left = NULL;
} else {
left = pixels[i][j-1];
}
//Créate pixel
pixels[i][j] = new RelatePixel(image.at<uchar>(Point(i,j))[0], up, left);
}
}
cout<<"imageToRelatePixelArray ends"<<endl;
return pixels;
}
Mat RelatePixel::RelatePixelArrayToImage(RelatePixel** pixels, int nbRows, int nbCol){
Mat img = cvCreateImage(cvSize(nbRows,nbCol),CV_8UC3,1);
cout<<"RelatePixelArrayToImage begins"<<endl;
int i,j,offset;
for (i=0; i<nbRows ; i++){
offset = i*nbCol;
for(j=0; j<nbCol; j++){
img->imageData[j+offset] = pixels[i][j].GetValeur();
}
}
cout<<"RelatePixelArrayToImage ends"<<endl;
return img;
}
bool RelatePixel::isNotNull(){
if (this == NULL) return false;
else return true;
}
ostream& RelatePixel::operator <<(ostream& flux){
flux<<"Pixel : {value: "<<this->GetValeur()
<<", e: "<<this->GetLabel()
<<", vUp: "<<this->GetVHaut()
<<", vGau: "<<this->GetVGauche();
return flux;
}
bool isValidCommand(int nbArgs, char** args);
inline Mat getLabeling();
RelatePixel*** algoLabeling(RelatePixel*** pixels);
int main(int argc, char** argv) {
//verification des arguments du proramme
if (!isValidCommand(argc, argv)) return EXIT_FAILURE;
//initialisation des fenetres
cvNamedWindow(IMAGE_INITIALE);
cvNamedWindow(IMAGE_FINALE);
//Affichage des images
imshow(IMAGE_INITIALE, initial_image);
imshow(IMAGE_FINALE, getLabeling());
//Attente d'une entrée clavier
cvWaitKey();
//fermeture du programme
cvDestroyAllWindows();
return EXIT_SUCCESS;
}
/**
* Verifie la validité des arguments
* @param nbArgs le nombre d'arguments passés
* @param args les arguments
* @return true si les arguments sont valides, false sinon;
*/
bool isValidCommand(int nbArgs, char** args) {
//Verification du nombre d'arguments
if (nbArgs != 2) {
cerr << "Utilisation: \n\t etiquetage <nom_fichier_image>" << endl;
return false;
}
//Chargement des images
Mat tmp = imread(args[1], CV_LOAD_IMAGE_GRAYSCALE);
if (tmp == 0) {
cerr << "Impossible de lire : " << args[1] << "\n";
return false;
}
initial_image = clone(tmp);
return true;
}
RelatePixel*** algoLabeling(RelatePixel*** pixels) {
cout<<"algoLabeling begins"<<endl;
int nbLigne = initial_image.rows;
int nbCol = initial_image.cols;
RelatePixel* pixel, * vup, * vleft;
int currentEtiq = 0, eh, eg;
int i, j;
//loop table RelatePixels
for (i = 0; i < nbLigne; i++) {
for (j = 0; j < nbCol; j++) {
pixel = pixels[i][j];
//if pixel
if (pixel->GetValeur() > 250) {
} else {
//get neighbours up and left
vup = pixel->GetVHaut();
vleft = pixel->GetVGauche();
//if pixel has 2 neighbours
if (vup->isNotNull() && vleft->isNotNull()) {
eh = vup->GetLabel();
eg = vleft->GetLabel();
//if the two neighbours have the same label
if (eh == eg) {
if (eh == -1) { // labels nulles
pixel->SetLabel(currentEtiq++);
} else {
pixel->SetLabel(eh);
}
}
//if the two neighbours have different label
else {
// neighbour up has no label
if (eh == -1) {
pixel->SetLabel(eg);
}
// neighbour left has no label
else if (eg == -1) {
pixel->SetLabel(eh);
}
// labels différentes
else {
pixel->SetLabel(min(eh,eg));
//TODO equiv
}
}
}//if pixel has a least a neighbour null
else {
// 2 neighbours are null
if (!vup->isNotNull() && !vleft->isNotNull()) {
pixel->SetLabel(currentEtiq++);
}// one of two is null
else {
RelatePixel* neighbour;
if (vup->isNotNull()) {
neighbour = vup;
} else {
neighbour = vleft;
}
//verify label neighbour
eh = neighbour->GetLabel();
if (eh >= 0){
pixel->SetLabel(eh);
} else {
pixel->SetLabel(currentEtiq++);
}
}
}
}
}
}
cout<<"algoLabeling ends, currentEtiq = "<<currentEtiq<<endl;
return pixels;
}
Mat getLabeling() {
cout << "getEtiq begins" << endl;
RelatePixel*** pixels = RelatePixel::imageToRelatePixelArray(initial_image);
pixels = algoLabeling(pixels);
//IplImage * img = RelatePixel::RelatePixelArrayToImage(pixels, initial_image->height, initial_image->width);
Mat img = NULL;
cout << "getEtiq ends" << endl;
return img;
}
I have an error with :
- pixels[i][j] = new RelatePixel(image.at(Point(i,j))[0], up, left); - tp1.cpp:116:73: error: invalid types ‘unsigned char[int]’ for array subscript
tp1.cpp:124:28: error: conversion from ‘IplImage* {aka _IplImage*}’ to non-scalar type ‘cv::Mat’ requested Mat img = cvCreateImage(cvSize(nbRows,nbCol),CV_8UC3,1);
img->imageData[j+offset] = pixels[i][j].GetValeur(); tp1.cpp:130:16: error: base operand of ‘->’ has non-pointer type ‘cv::Mat’
- initial_image = clone(tmp); tp1.cpp:193:30: error: cannot convert ‘cv::Mat’ to ‘int ()(void)’ for argument ‘1’ to ‘int clone(int ()(void), void*, int, void*, ...)’
- Mat img = NULL; tp1.cpp:289:15: error: conversion from ‘long int’ to non-scalar type ‘cv::Mat’ requested