2014-03-29 46 views
1

我一直試圖使用OpenCV和C++來跟蹤2D灰度圖像中曲面的輪廓(線條),但是我一直運行到無限循環。我嘗試了各種調試,但無法糾正我的問題。請幫忙!C++ - 停止無限循環 - 跟蹤輪廓

我的形象看起來是這樣的:http://snag.gy/fAs9a.jpg(第四圖像)

這就是我的「初步」輪廓看上去像:http://snag.gy/fAs9a.jpg(第五圖像)

這是我迄今所做的:

  1. 初始化包含圖像表面「初始」輪廓的圖像蒙版。
  2. 在掩碼中,獲取所有值大於255的點座標,並將它們存儲在向量中。
  3. 對於每個座標集,將行值遞增以沿圖像中的當前列下降,並找到其所有鄰居大於閾值的第一個像素。
  4. 找到像素後,轉到下一列並重復該過程,直到在所有列中找到所有像素。
  5. 如果沒有發現這樣的像素,則最後的(行,列)值設置爲0。
  6. 一旦所有的明亮像素被找到,這構成了「最終輪廓」

問題:我即使我的邏輯聽起來很合理,我的代碼也看起來很合理,但仍然會陷入無限循環。在當前列中可能沒有找到像素大於閾值的像素。

調試:我調試我的代碼,以確定在無限循環發生的一切,並發現它在if-else代碼塊中main功能while循環下。

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

} 

的main()

// ... 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); 
    } 

回答

0

我通過強制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++; 
     } 

    }  

} 
0

您正在試圖擺脫while((mc1 != setC.end()) && (mr1 != setR.end())) {}循環的,對嗎?如果是這樣,你已經把你的break放在錯誤的地方。

break只會打破了你的do{...}while(result==false)循環,而不是你的大while循環。一個提示是使用FLAG。如果問題仍然存在,請告訴我。和平。

+0

我昨天晚上解決了它。在'if(result == false)'循環中,我將while循環轉換爲for循環。所以,我所做的是我強迫迭代從當前行到最後,檢查結果和命中'break'只有當'結果== TRUE'。我還包括一個'check'變量,看看所有結果是否都是錯誤的。如果檢查設置爲true(您建議的標誌),我將轉到下一個座標集。我將在今天晚些時候發佈代碼,因爲我離開了我編寫代碼的實際系統。 – Eagle

+0

不,我想就這樣打破了我的'如果.. else'循環。請記住,在循環的「else」部分中,如果當前列中所有像素的所有像素鄰居(逐個迭代)小於閾值,則意味着沒有像素可以設置爲當前列中的255。所以,我必須移動到下一列,獲取下一個座標集,然後執行相同的操作。 – Eagle

+0

@eagle,很高興你解決它,然後,是啊,你的'check'和我的'flag'其實是同樣的事情,就是採取這樣的檢查步驟。另外,如果你試圖擺脫'if ... else'循環,'break'不會這樣做。 'break'不上'如果... else',通常人們用'goto'工作,而不是,但我不是那種風扇。不過,很高興你解決了這個問題,我希望我能以同樣的方式幫助你。乾杯(: – rockinfresh