C++ 连通元件标记算法C++;
我试图实现标记算法。我使用IplImage绘制地图,这是一个古老的版本,但我仍然有麻烦。欢迎任何想法。多谢各位C++ 连通元件标记算法C++;,c++,opencv,opencv3.0,opencv3.1,C++,Opencv,Opencv3.0,Opencv3.1,我试图实现标记算法。我使用IplImage绘制地图,这是一个古老的版本,但我仍然有麻烦。欢迎任何想法。多谢各位 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 = ne
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;
}
const char*const IMAGE\u INITIALE=“Initial”;
const char*const IMAGE_FINALE=“最终彩色图像”;
使用名称空间cv;
使用名称空间std;
Mat初始图像;
int**表_等效=新int*;
类关联像素{
公众:
RelatePixel(int值,RelatePixel*上邻居,RelatePixel*左邻居);
//映射
静态相关像素***图像到最新像素阵列(Mat图像);
静态Mat RelatePixelArrayToImage(RelatePixel**像素,整数nbRows,整数nbCol);
//能手/二传手
无效设置标签(int标签);
int GetLabel()常量;
RelatePixel*GetVGauche()常量;
RelatePixel*GetVHaut()常量;
char GetValeur()常量;
void SetValeur(字符值);
//乌提尔斯
bool不是null();
ostream&operatorvUp=upnexture;
这->vLeft=左邻居;
此->标签=-1;
}
char RelatePixel::GetValeur()常量{
返回值;
}
void RelatePixel::SetValeur(字符值){
这个->值=值;
}
RelatePixel*RelatePixel::GetVGauche()常量{
返回vLeft;
}
RelatePixel*RelatePixel::GetVHaut()常量{
返回vUp;
}
void RelatePixel::SetLabel(int-label){
此->标签=标签;
此->值=0;//TODO delete
}
int RelatePixel::GetLabel()常量{
退货标签;
}
/**
*将图像转换为关系像素表
*@param image l'imageá修饰符
*@return le tableau de RelatePixel correspondantál'image
*/
RelatePixel***RelatePixel::imageToRelatePixelArray(Mat图像){
库特
像素[i][j]=新的RelatePixel(图像位于(i,j))[0],向上,左侧)-
tp1.cpp:116:73:错误:数组的类型“unsigned char[int]”无效
image.at(点(i,j))[0]
不正确。at
将返回一个uchar
。因此,您不应该使用[0]
,图像解除引用。at(点(i,j))
应该足够了
下标tp1.cpp:124:28:错误:从'IplImage*{aka'转换
_IplImage*}'到非标量类型“cv::Mat”请求的Mat img=cvCreateImage(cvSize(nbRows,nbCol),cv_8UC3,1)
cvCreateImage是旧的API。只需使用cv::Mat
构造函数:
cv::Mat img(nbRows、nbCol、cv_8UC3);
img->imageData[j+offset]=像素[i][j].GetValeur();tp1.cpp:130:16:
错误:“->”的基操作数具有非指针类型“cv::Mat”
您可以通过调用img.ptr
initial_image=clone(tmp);tp1.cpp:193:30:错误:无法转换
参数“1”到“int clone(int)”的“cv::Mat”到“int()(void)”
()(void),void*,int,void*,…)'
我看不出您在哪里定义了这个clone()
函数,但您没有向它传递正确的参数。第一个参数要求函数不带参数并返回int
Mat img=NULL;tp1.cpp:289:15:
错误:从“long int”转换为非标量类型“cv::Mat”
请求
您不能将NULL
分配给cv::Mat
对象。这没有任何意义。非常感谢您^^^^^所以对于img->imageData[j+offset]=pixels[i][j]。GetValeur();指令我不明白…它应该是img-.ptr[j+offset]=pixels[i][j]。GetValeur();?我有一个类似于tp1的错误。cpp:130:29:错误:无效类型“[int]'对于数组下标Mat.ptr
是一个函数,您应该像uchar*dst=img.ptr(rowNum)
一样调用FindTours是否可以作为替代方法?是的,当然可以^^^^,但我必须对该方法进行编码;)