DY N DY

opencv dilate/erode 연산 정리 본문

PARK/영상처리 관련

opencv dilate/erode 연산 정리

손세지 2016. 11. 8. 23:50
opencv 3.1기준. 
dilate(팽창), erode(침식) 간단한 이론과 사용법 정리. 

공부를 하다가 쓸일이 생겨 간단히 정리한다. 


Erode, Dilate 연산을 보통 모폴로지 기법이라고 한다. 

위키에서 morphology에 대해 찾아보면...

  • Mathematical morphology, a theoretical model based on lattice theory, used for digital image processing
    • 를 타고 들어가면 https://en.wikipedia.org/wiki/Mathematical_morphology에 자세히 설명이 되어있는데 영어인지라...

      대충... 기하학적인 구조의 분석과 처리를 위한 이론 및 기술이라고 한다. 

      영상내의 특정한 객체의 형태를 변형시킴으로써 작은 노이즈를 제거한다던가 미세하게 검출된 무언가를 키운다던가 등등...을 위해 사용한다. 

      보통은 이진영상에서 주로 사용한다. 


      Erode 연산 : 필터 내부의 가장 낮은(어두운) 값으로 변환(and) - 침식연산

      Dilate 연산 : 필터 내부의 가장 높은(밝은) 값으로 변환(or) - 팽창연산


      두 연산은 순서에 따라 서로 다른 기능을 한다. 

      Erode - Dilate = Opening 연산 : 주로 작은 노이즈들을 제거하는데 사용한다.

      Dilate - Erode = Closing 연산 : 보통 한 객체를 추출했을 때 두개 이상의 작은 부분으로 나올 경우 큰 객체로 합칠 때 사용한다. 


      아래는 opencv(3.1에서 사용하였음.) 코드이다. 


      mask는 erode, dilate를 적용할 필터로 여기서는 3x3 사각형 구조의 필터를 사용한다.

      일반적으로 타원형, 십자형도 있지만 주로 사각형을 많이 사용한다. 

      필터 크기를 크게 할 수록 변화량이 많아질 것이다.. 실험을 통해 확인해보면 쉽게 이해할 수 있다. 

      erode, dilate 연산은 반복하여 수행할 수 있다. 마지막 인자 3은 3번 반복수행한다는 뜻이다. 

      3번째 인자는 mask의 중심점인데 default로 -1,-1이 들어간다. 

      1
      2
      3
      cv::Mat mask = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(33), cv::Point(11));
      cv::erode(src, dst, mask, cv::Point(-1-1), 3);
      cv::dilate(src, dst, mask, cv::Point(-1-1), 3);
      cs

      이외에 morphologyEx함수가 opening, closing을 수행할 수 있다고 한다. 

      http://docs.opencv.org/3.1.0/d4/d86/group__imgproc__filter.html#ga67493776e3ad1a3df63883829375201f

      문서를 살펴보면... 대략 

      1
      2
      3
      4
      5
      6
      7
      8
      9
      void cv::morphologyEx    (InputArray     src,
          OutputArray     dst,
          int     op,
          InputArray     kernel,
          Point     anchor = Point(-1,-1),
          int     iterations = 1,
          int     borderType = BORDER_CONSTANT,
          const Scalar &     borderValue = morphologyDefaultBorderValue() 
      )        
      cs

      라고 나와있는데... 거의 다르지 않아보인다. 결국 뭐 뒤에는 다 default가 있으니.. 

      1
      2
      cv::morphologyEx(src, dst, cv::MORPH_OPEN, mask)
      cv::morphologyEx(src, dst, cv::MORPH_CLOSE, mask)
      cs

      이렇게 사용하면 될 것 같다... 


      아래와 같은 코드로 실험해 보았다. (위의 연산들을 사용하기 위해서는 imgproc.hpp를 include해야 한다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      #include <opencv2/core/core.hpp>
      #include <opencv2/highgui/highgui.hpp>
      #include <imgproc.hpp>
      #include <iostream>
       
      using namespace cv;
      using namespace std;
       
      int main()
      {
          Mat image;
          image = imread("simple.jpg", IMREAD_COLOR); // Read the file
       
          if (!image.data) // Check for invalid input
          {
              cout << "Could not open or find the image" << std::endl;
              return -1;
          }
       
          namedWindow("Display window", WINDOW_AUTOSIZE); // Create a window for display.
          imshow("Display window", image); // Show our image inside it.
       
          Mat mask = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(33), cv::Point(11));
          Mat eroded, dilated, opened, closed;
          erode(image, eroded, mask, cv::Point(-1-1), 3);
          imshow("Eroded", eroded);
          dilate(image, dilated, mask, cv::Point(-1-1), 3);
          imshow("Dilated", dilated);
          morphologyEx(image, opened, cv::MorphTypes::MORPH_OPEN, mask);
          imshow("open", opened);
          morphologyEx(image, closed, cv::MorphTypes::MORPH_CLOSE, mask);
          imshow("close", closed);
          waitKey(0); // Wait for a keystroke in the window
          return 0;
      }
      cs

      simple.jpg는 유명한 lena이미지의 이진화 영상이다. (혹시 연습할 분들을 위해 첨부하였다. - 구글에서 쉽게 구할 수도 있다.)

      결과는 아래와 같다. 



      눈으로 확인해보면 어떤 연산인지 조금 더 쉽게 이해할 수 있을 것 같다. 

      simple.jpg

      아마 오른쪽클릭하여 이미지 저장하면 저장 될 것이다.