2014年1月3日 星期五

OpenCV: Erosion and Dilation

since: 2014/01/03
update: 2014/01/03

reference:
1. Amazon.com: Practical OpenCV eBook
2. Welcome to opencv documentation!
3. I touchs: Using OpenCV on Mac OS X

A. 前置作業:
     1. 先依照 I touchs: Using OpenCV on Mac OS X 的說明, 建置好開發環境.

     2. 需要加入到專案的 OpenCV 函式庫爲: (Add Files to Project...)
          libopencv_core.dylib
          libopencv_highgui.dylib
          libopencv_imgproc.dylib

     3. 將 main.cpp 的 main function 更名.(不作為程式執行的進入點)
          //int main(int argc, const char * argv[])  
          int main_main(int argc, const char * argv[])

     4. 爲專案新增 C++ 檔案:      
         點選專案 > New File... > OS X > C and C++ > C++ Class > Next >
         Save as: ErosionAndDilation.cpp > Create

----------------------------------------------------------------------------------------

B. 撰寫程式:
    1. 開啓 ErosionAndDilation.h 檔案, 修改如下:
#ifndef __HelloOpenCV__ErosionAndDilation__
#define __HelloOpenCV__ErosionAndDilation__

#include <iostream>

//@add
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>


#endif /* defined(__HelloOpenCV__ErosionAndDilation__) */

---------------------------------------------------------------------------------
    2. 開啓 ErosionAndDilation.cpp 檔案, 修改如下:
#include "ErosionAndDilation.h"

using namespace std;
using namespace cv;


// 原始照片, 處理過的照片

Mat ED_image, ED_imageProcessed;

// 選擇的形態學類型: 0: erode(侵蝕), 1: dilate(擴張)
int choice_slider = 0;

// 形態學的結構元素的大小: n x n (ex: 5 x 5)
int size_slider = 5;

const int choice_slider_max = 1; // 選擇形態學類型的最大值
const int size_slider_max = 21; // 形態學的結構元素之最大值

// 進行形態學處理
void process()
{

    // 設定形態學的結構元素(在此為矩形, 長寬皆為 size_slider 的大小)
    Mat st_elem = getStructuringElement(MORPH_RECT, Size(size_slider, size_slider));
   
    // erode(侵蝕)
    if (choice_slider == 0) {
        erode(ED_image, ED_imageProcessed, st_elem);
    }

    // dilate(擴張)
    else {
        dilate(ED_image, ED_imageProcessed, st_elem);
    }
   
    imshow("Processed image", ED_imageProcessed);
    printf("morphological type: %s \n", choice_slider == 0 ? "Erosion" : "Dilation");
    printf("size_slider position: %d \n\n", size_slider);
}


// 選擇形態學類型
void on_choice_slider(int, void*)
{
    process();
}


// 調整形態學的結構元素大小
void on_size_slider(int, void*)
{

    // 將形態學的結構元素大小(值為 size_slider), 調整為大於零的奇數
    size_slider = max(1, size_slider);
    size_slider = size_slider % 2 == 0 ? size_slider + 1 : size_slider;
    setTrackbarPos("Kernel Size", "Processed image", size_slider);
   
    process();
}

int main()
{

    // 讀取檔案
    ED_image = imread("/Lanli/RD/Projects/OpenCV_Mac/HelloOpenCV/pipiGray.png");
    namedWindow("Original image");
    namedWindow("Processed image");
    imshow("Original image", ED_image);

   
    // 設定形態學的結構元素(在此為矩形, 長寬皆為 size_slider 的大小)
    Mat st_elem = getStructuringElement(MORPH_RECT, Size(size_slider, size_slider));
   
    // erode(侵蝕)
    erode(ED_image, ED_imageProcessed, st_elem);
    imshow("Processed image", ED_imageProcessed);
   
    createTrackbar("Erode/Dilate", "Processed image", &choice_slider, choice_slider_max, on_choice_slider);
    createTrackbar("Kernel Size", "Processed image", &size_slider, size_slider_max, on_size_slider);
   
    printf("morphological type: %s \n", choice_slider == 0 ? "Erosion" : "Dilation");
    printf("size_slider position: %d \n\n", size_slider);
   
    while (char(waitKey(1) != 'q')) {}
   
    return 0;
}


----------------------------------------------------------------------------------------

C. 執行結果:
     原始圖片:

     erosion(侵蝕): 結構元素大小: 5 x 5

     dilation(擴張): 結構元素大小: 5 x 5