gpt4 book ai didi

c++ - 连通分量标记算法 C++

转载 作者:太空宇宙 更新时间:2023-11-03 22:38:37 26 4
gpt4 key购买 nike

我尝试实现标签算法。我使用 IplImage 将旧版本改编为 Map,但我仍然遇到麻烦。欢迎任何想法。非常感谢

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;
}

我有一个错误:

  1. pixels[i][j] = new RelatePixel(image.at(Point(i,j))[0], up, left); - tp1.cpp:116:73: 错误:数组下标的无效类型“unsigned char[int]”
  2. tp1.cpp:124:28:错误:从“IplImage* {aka _IplImage*}”到非标量类型“cv::Mat”的转换请求 Mat img = cvCreateImage(cvSize(nbRows,nbCol) ,CV_8UC3,1);

  3. img->imageData[j+offset] = pixels[i][j].GetValeur(); tp1.cpp:130:16: 错误:“->”的基操作数具有非指针类型“cv::Mat”

  4. 初始图像=克隆(tmp); tp1.cpp:193:30: 错误:无法将参数“1”的“cv::Mat”转换为“int ()(void)”到“int clone(int ()” (void), void*, int, void*, ...)'
  5. Mat img = NULL; tp1.cpp:289:15: 错误:请求从“long int”转换为非标量类型“cv::Mat”

最佳答案

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

image.at<uchar>(Point(i,j))[0]是不正确的。 at将返回 uchar .所以你不应该取消对 [0] 的引用, image.at<uchar>(Point(i,j))应该足够了。

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);

cvCreateImage 是旧的 API。只需使用 cv::Mat构造函数:

cv::Mat img(nbRows, nbCol, CV_8UC3);

img->imageData[j+offset] = pixels[i][j].GetValeur(); tp1.cpp:130:16: error: base operand of ‘->’ has non-pointer type ‘cv::Mat’

您可以通过调用img.ptr 获取指向图像数据的指针。

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*, ...)’

我没看到你在哪里定义了这个 clone()函数,但您没有向它传递正确的参数。第一个参数需要一个不带参数并返回 int 的函数。

Mat img = NULL; tp1.cpp:289:15: error: conversion from ‘long int’ to non-scalar type ‘cv::Mat’ requested

您不能分配 NULLcv::Mat目的。这没有意义。

关于c++ - 连通分量标记算法 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56087621/

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