2017-04-23 33 views
-2

我試圖在C++中實現侵蝕(形態學操作),我使用OpenCV進行讀取並在侵蝕後顯示第一幅圖像和圖像。侵蝕不能正常工作

我想解釋一步一步我是如何做到:

  1. 我創造了我的「二值圖像」(我用的只有黑和白),所用的255隨機值或0
  2. 矩陣我複製初始圖像到最終圖像
  3. 然後,我通過矩陣去(最終圖像)與3×3掩模和餘數,如果我有255

9值My掩模像:

[255 255 255 
255 255 255 
255 255 255] 
  1. 如果我的計數器= 9,我將與黑色中心不同的像素着色。

這是我的代碼:

#include <iostream> 
#include "opencv2/imgproc/imgproc.hpp" 
#include "opencv2/highgui/highgui.hpp" 

using namespace std; 
using namespace cv; 

#define WIDTH 16 
#define HEIGHT 16 

int main(int argc, char** argv) 
{ 
    Mat image(HEIGHT, WIDTH, CV_8UC1); 
    Mat imageFinal(HEIGHT, WIDTH, CV_8UC1); 

    int values[WIDTH][HEIGHT] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
           0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
           0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
           0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 
           0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 
           0, 0, 0, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 
           0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 
           0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 
           0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 
           0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 
           0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 
           0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 
           0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 
           0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 

    for(int row = 0; row < WIDTH; row++){ 
     for(int col = 0; col < HEIGHT; col++){ 
      image.data[col + row * image.cols] = values[row][col]; 
     } 
    } 

    image.copyTo(imageFinal); 

    int count = 0; 

    for(int row = 1; row < image.rows-1; row++){ 
     for(int col = 1; col < image.cols-1; col++){ 
      count = 0; 
      for(int a = -1; a <= 1; a++){ 
       for(int b = -1; b <= 1; b++){ 
        if(image.at<uchar>(row + a, col + b) == 255){ 
         count++; 
        } 
       } 
      }cout << count << endl; 
      if(count == 9){ 
       for(int a = -1; a <= 1; a++){ 
        for(int b = -1; b <= 1; b++){ 
         if(a != 0 && b != 0){ 
          imageFinal.at<uchar>(row + a, col + b) = 0; 
         } 
        } 
       } 
      } 
     } 
    } 

    imshow("Image", image); 
    imshow("final", imageFinal); 

    waitKey(0); 
    return 0; 
} 

但結果是不正確的。

Initial image and correct result: [錯誤結果] [1]

+0

爲什麼我有-1?這不是個好問題嗎?要麼 ? – Laurentiu

+1

「但結果不正確」......什麼是「不正確」?圖像太小,看不到任何區別 – user463035818

+0

但什麼是正確的公式或過濾器侵蝕? – Laurentiu

回答

1

我不是100%肯定,但看完後wiki entry on erosion我認爲正確的實施將是這樣的:

for each pixel(x,y) in original_image 
    count neigbours where original_image == 255 
    if count == 9 
     new_image(x,y) = 255 
    else 
     new_image(x,y) = 0 
    end 
end 

當你有

for each pixel(x,y) in original_image 
    count neigbours where original_image == 255 
    if count == 9 
     set all neighbours (but not the pixel itself) in new_image to 0 
end 

基本上侵蝕應該爲圖像的一個3x3的一部分做...

1 1 1   ? ? ?   0 1 1  ? ? ? 
1 1 1 -> ? 1 ?  and 1 1 1 -> ? 0 ? 
1 1 1   ? ? ?   1 1 1  ? ? ? 

但你

1 1 1   0 0 0 
1 1 1 -> 0 1 0 
1 1 1   0 0 0 

申請時,你應該改變你正在尋找在像素僅值過濾器,但你改變所有的鄰居,而不是像素本身。

我覺得維基文章中的公式不是太有啓發性,這也許有助於理解:

new_image(x,y) = (3x3Sub(old_image,x,y) == mask) * 255 
+0

非常感謝您的解釋:D – Laurentiu

+1

@Laurentiu歡迎您。即使您的問題已解決,並且您已接受答案,請考慮改進問題。在目前的狀態下,不清楚產生的圖像有什麼問題。 – user463035818