C++ - 停止无限循环 - 跟踪轮廓



我一直在尝试使用 OpenCV 和 C++ 在 2D 灰度图像中追踪表面的轮廓(线),但是,我一直遇到无限循环。我已经尝试了各种调试,但无法纠正我的问题。请帮忙!

我的图像如下所示:http://snag.gy/fAs9a.jpg(第四张图像)

这是我的"初始"轮廓的样子:http://snag.gy/fAs9a.jpg(第五张图片)

这是我到目前为止所做的:

    初始化图像的
  1. 蒙版,其中包含图像中表面的"初始"轮廓。
  2. 在掩码中,获取所有值大于 255 的点坐标,并将它们存储在向量中。
  3. 对于每个坐标集,递增行值以向下移动图像中的当前列,并找到具有大于阈值的所有相邻像素的第一个像素。
  4. 找到像素后,转到下一列并重复该过程,直到在所有列中找到所有像素。
  5. 如果未找到此类像素,则将最后一个(列,行)值设置为 0。
  6. 一旦找到所有明亮的像素,这就构成了"最终轮廓"

问题:我一直在遇到无限循环,即使我的逻辑看起来很合理,我的代码看起来也很合理。在当前列中可能找不到相邻像素大于阈值的像素。

调试

:我调试了代码以确定无限循环发生的位置,并发现它在 main 函数中while循环下的if-else代码块中。

  1. 我只检查了第一列的代码,它起作用了。但是,当我概括我的代码时,它会进入无限循环。
  2. 试图降低邻域模式的要求;如果只有几个邻居大于阈值,那么该点就足以形成"最终轮廓"
  3. 我检查了是否遍历了所有行,并看到行计数不断重置。
  4. 为了解决第 3 点,我设置了一个计数,如果无限循环超过 200,则切断无限循环。但是,输出的"最终轮廓"图像与初始蒙版图像相同。

我已经没有关于如何删除错误的想法了。再次,我们将非常感谢帮助!

这是我的代码:

// function to get the neigbourhood pattern 
bool checkLBP(unsigned char *GMOtemp, unsigned char *contour, int &row, int &col, int width, int thresh)
{ 
const int arrSize = 9; 
const int semiArrSize = 6; 

// for first column, need only 6 neighbours 
// since it is at one end of the image
if( col == 0 ) {
    int array [semiArrSize]; 
    // start storing values in the array
    array[0] = GMOtemp[(row*width) + (col)];
    array[1] = GMOtemp[((row+1)*width) + (col)];
    array[2] = GMOtemp[((row+2)*width) + (col)];
    array[3] = GMOtemp[(row*width) + (col+1)];
    array[4] = GMOtemp[((row+1)*width) + (col+1)];
    array[5] = GMOtemp[((row+2)*width) + (col+1)];
    int cnt = 0;
    for(int i = 0; i<semiArrSize; i++) {
        if(array[i] >= thresh) {
        cnt++; 
        }
    }
    printf("n cnt %d n",cnt);
    if( cnt >= 2 ) { 
        return true; 
    }
    else { 
        return false; 
    }
}   
// for last column, need only 6 neighbours
else if( col == width - 1) {
    int array [semiArrSize]; 
    // start storing values in the array
    array[0] = GMOtemp[(row*width) + (col)];
    array[1] = GMOtemp[((row+1)*width) + (col)];
    array[2] = GMOtemp[((row+2)*width) + (col)];
    array[3] = GMOtemp[(row*width) + (col-1)];
    array[4] = GMOtemp[((row+1)*width) + (col-1)];
    array[5] = GMOtemp[((row+2)*width) + (col-1)];
    int cnt = 0;
    for(int i = 0; i<semiArrSize; i++) {
        if(array[i] >= thresh) {
        cnt++; 
        }
    }
    printf("n cnt %d n",cnt);
    if( cnt >= 2 ) { 
        return true; 
    }
    else { 
        return false; 
    }
}   
else {
    int array [arrSize]; 
    // start filling all the elements 
    array[0] = GMOtemp[((row)*width) +(col-1)];
    array[1] = GMOtemp[((row)*width) +(col)];
    array[2] = GMOtemp[((row)*width) +(col+1)];
    array[3] = GMOtemp[((row+1)*width) +(col-1)];
    array[4] = GMOtemp[((row+1)*width) +(col)];
    array[5] = GMOtemp[((row+1)*width) +(col+1)];
    array[6] = GMOtemp[((row+2)*width) +(col-1)];
    array[7] = GMOtemp[((row+2)*width) +(col)];
    array[8] = GMOtemp[((row+2)*width) +(col+1)];
    int cnt = 0;
    for(int i = 0; i<arrSize; i++) {
        if(array[i] >= thresh) {
        cnt++; 
        }
    }
    printf("n cnt %d n",cnt);
    if( cnt >= 1) { 
        return true; 
    }
    else { 
        return false; 
    }
}
}

主()

// ... previous code to do blurring of the image. 

// code to get the point-coordinates from the "initial mask" image 
std::vector<int> setC;
std::vector<int> setR;  
for(int xc = 0; xc < input.cols; xc++) {
for(int xr = 0; xr < input.rows; xr++) {
    int val = mask[xr*input.cols + xc];
    if(val == 255) {
        //setC[i] = xc; 
        //setR[i] = xr; 
        //i++; 
        setC.push_back(xc);
        setR.push_back(xr);
        }
    }
}

// get the LBP pattern
// LBP PATTERN IS A 3X3 NEIGHBOURHOOD
std::vector<int>::iterator mc1 = setC.begin();
std::vector<int>::iterator mr1 = setR.begin();
int rr = 0;
int cc = 0; 
int width = input.cols; 
//rowcount = 0;
int infiniteCount = 0;
unsigned char *GMOtemp; 
unsigned char *contour;
GMOtemp = (unsigned char*) malloc(sizeof(unsigned char) * input.rows * input.cols);
contour = (unsigned char*) malloc(sizeof(unsigned char) * input.rows * input.cols);
memcpy(GMOtemp, OCVout2.data, sizeof(unsigned char) * input.rows * input.cols); 
memset(contour, 0, sizeof(unsigned char) * input.rows * input.cols);
while( (mc1 != setC.end()) && (mr1 != setR.end()) ) {

    //looping:
    rr = *mr1; // get row and col
    cc = *mc1; 
    printf("n %d %d n", rr, cc); 

    rr++; // increment the row
    bool result = checkLBP(GMOtemp, contour, rr, cc, width, sum);
    //printf("n %d n", rr);

    if(result == true)
    {
        contour[rr*width + cc] = 255; // set current point to be equal to 255
        mc1++; // increment the vector iterators - so, go to next column
        mr1++;
    }
    else { 
        do{         
            rr++; 
            result = checkLBP(GMOtemp, contour, rr, cc, width, sum);
            infiniteCount++;
            //printf("n rr %d n", rr);
            //printf("n %d n", infiniteCount);
            if (rr == (input.rows - 1) || infiniteCount == 200) {
                contour[rr*width + cc] = 255;
                mr1++;
                mc1++;
                infiniteCount = 0;
                result = true; 
                break;
            }
            //printf("n rr %d n", rr);
        } while(result == false);
    }

你试图打破while( (mc1 != setC.end()) && (mr1 != setR.end()) ) {}循环,对吗?如果是这样,那么您break放错了地方。

break只会打破你的do{...}while(result==false)循环,而不是你的大while循环。一个提示是使用标志。如果问题仍然存在,请告诉我。和平。

我通过强制if..else代码块从当前行迭代到for循环中的最后一行来解决无限循环。这是代码:

while( mm < ind ) {
    // 'ind' corresponds to number of coordinate-sets = 254
    // I used two arrays here, each was set to 256 (width of image).
    int rr = setR[mm]; // get row and col
    int cc = setC[mm]; 
    //printf("n %d %d n", rr, cc); 
    rr = rr + skiprows; // increment row; to skip if needed (skiprows = 0 now) 
    bool result = checkLBP(GMOtemp, rr, cc, width, height, sum);
    //printf("n %d n", rr);

    if(result == true)
    {
        if(rr<height){
        contour[rr*width + cc] = 255; // set current point to be equal to 255
        mm++;
        }
    }
    else {
        int check = 0; // boolean check variable - to see if none of the neighbors of a given pixel are greater
        rr = rr + skiprows; // increment row 
        for(int currRow = rr; currRow < height; currRow = currRow+skiprows)
        {
            result = checkLBP(GMOtemp, currRow, cc, width, height, sum);
            if( result == true) 
            {
                contour[currRow*width + cc] = 255;
                mm++;
                check = 1;
                break; // break out of for-loop
            }
        }
        if(check == 0)
        { 
            mm++;
        }
    }       
}

最新更新