连接的组件标记算法C
Connected components labeling algorithm C++
我尝试实现标签算法。我使用iPlimage映射了一个Ancien版本,但我仍然遇到麻烦。任何想法都受到欢迎。非常感谢
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: nt 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;
}
我有一个错误:
- pixels [i] [j] = new RelatePixel(image.at(point(i,j(([0],向上,左(;-tp1.cpp:116:73:错误:无效类型的"无符号char [int]'for Array下标
tp1.cpp:124:28:错误:从'iplimage* {aka _iplimage*}'转换为非降低类型'cv :: mat'请求垫子img = cvcreateimage(cvsize(cvsize((cvsize(nbrows,nbcol(,CV_8UC3,1(;
img-> imagedata [j offset] =像素[i] [j] .getValeur((;TP1.CPP:130:16:错误:" ->"的基本操作数具有非销钉类型的" CV :: MAT"
- initial_image = clone(tmp(;tp1.cpp:193:30:错误:无法将'cv :: mat'转换为'int(((void ('for参数'1'to'int clone(int(int(int(((((void (,void*,int,void*,...('
- mat img = null;tp1.cpp:289:15:错误:从"长int"转换为非量表类型'cv :: mat'请求
pixels [i] [j] = new RelatePixel(image.at(point(i,j(([0],向上,左(; - TP1.CPP:116:73:错误:无效类型的"无符号char [int]"数组
image.at<uchar>(Point(i,j))[0]
不正确。at
将返回uchar
。因此,您不应该使用[0]
,image.at<uchar>(Point(i,j))
就足够了。
下标tp1.cpp:124:28:错误:从'iplimage* {aka转换 _iplimage*}’to非量表类型的" cv :: 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: 错误:" ->"的基本操作数具有非销钉类型的" cv :: mat’
您可以通过调用img.ptr
initial_image = clone(tmp(;TP1.CPP:193:30:错误:无法转换 " cv :: mat'to" int(((void(" for参数'1'to'int clone(int( (((void(,void*,int,void*,...(’
我看不到您在哪里定义了此clone()
函数,但是您并没有将其传递给正确的参数。第一个参数期望一个函数没有参数并返回int。
mat img = null;TP1.CPP:289:15: 错误:从"长int"转换为非量表类型的" cv :: mat" 请求
您无法将NULL
分配给cv::Mat
对象。这是没有意义的。
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 如何将 txt 文件中的行分隔为组件C++
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- C++A*算法并不总是在路径中具有目标节点
- 排序算法c++
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- 算法问题:查找从堆栈中弹出的所有序列
- 下面是排序算法O(n)吗
- KMP算法和LPS表构造的运行时间
- 为什么我的排序算法会更改数组值
- 求最大元素位置的分治算法
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 到连接组件算法的问题(递归)
- 连接的组件标记算法C
- 计算QuickSort算法中的组件明智比较数量
- 图形组件之间的路径算法
- 连接组件算法输出
- C++-如何增加堆栈大小以允许Kosaraju算法进行更多递归以计算强连接组件