[Opencv] Boundary and Filling 구현

김모씨·2023년 5월 30일
0

image processing

목록 보기
2/3

주어진 영상에서 morpological operation을 이용하여 boundary를 계산하고, region filling 을 구현합니다.

실행 과정은 다음과 같습니다.

  1. 입력 영상을 gray scale로 입력 받습니다.
  2. morpological operation을 이용하여 boundary를 계산하여 화면에 표시합니다.
  3. boundary 영상 내부 or 외부를 click 하면 morphological operation을 이용하여 region filling을 진행합니다.
#include <iostream>
#include <array>
#include <vector>
#include <algorithm>
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"

using namespace std;
using namespace cv;

Point ptStart;


void on_MouseHandle(int event, int x, int y, int flag, void* param);


bool equalImg(Mat mat1, Mat mat2);


void RegionFilling(Mat& src, Point ptStart);

int main()
{

    Mat img = imread("/Users/liupei/desktop/Profile.png", 0);
    if (img.empty())
    {
        std::cout << "Could not load image!" << std::endl;
        return -1;
    }
   
    Point anchor(-1, -1);
    
    Size ksize(3, 3);
    
    
    Mat kernal = getStructuringElement(MORPH_ELLIPSE, ksize, anchor);
    
    Mat boundaryImg;
    
    
    morphologyEx(img, boundaryImg, MORPH_GRADIENT, kernal);
   
    imshow("boundaryImg", boundaryImg);
    namedWindow("boundaryImg");
    
    setMouseCallback("boundaryImg", on_MouseHandle, (void*)&boundaryImg);
    waitKey(0);
    return 0;
}

void on_MouseHandle(int event, int x, int y, int flag, void* param)
{
    Mat& img = *(Mat*)param;
    switch (event)
    {
    
    case EVENT_LBUTTONDOWN:
        ptStart.x = x; ptStart.y = y;
        break;
   case EVENT_LBUTTONUP:
        
        RegionFilling(img, ptStart);

        break;
    }
}

void RegionFilling(Mat& src, Point ptStart)
{
    
    Mat dst = Mat::zeros(src.size(), src.type());

    Point anchor(-1, -1);
    Size ksize(3, 3);
       
    Mat kernal = getStructuringElement(MORPH_ELLIPSE, ksize, anchor);
    Mat tempImg = Mat::ones(src.size(), src.type()) * 255;
    
    
    Mat revImg = tempImg - src;

    dst.at<uchar>(ptStart.y, ptStart.x) = 255;
    
    while (true)
    {
        Mat temp;
        
       
        dst.copyTo(temp);
        
       
        dilate(dst, dst, kernal);
                
       
        dst = dst & revImg;
                    
      
        if (equalImg(dst, temp))
        {
            break;
        }
        src = dst;
        imshow("Result", src);
        waitKey(10);
    }
}

bool equalImg(Mat mat1, Mat mat2)
{
   
    if (mat1.empty() && mat2.empty())
    {
        return true;
    }
    
    if (mat1.cols != mat2.cols || mat1.rows != mat2.rows || mat1.dims != mat2.dims ||
        mat1.channels() != mat2.channels())
    {
        return false;
    }
    
    if (mat1.size() != mat2.size() || mat1.channels() != mat2.channels() || mat1.type() != mat2.type())
    {
        return false;
    }
    //////*------------------------------*------------------------////
        
    int nrOfElements1 = mat1.total() * mat1.elemSize();
    
    if (nrOfElements1 != mat2.total() * mat2.elemSize())
    {
      return false;
    }
    
    bool lvRet = memcmp(mat1.data, mat2.data, nrOfElements1) == 0;
    
    return lvRet;
}
profile
아주대학교 디지털미디어학과 & 소프트웨어학과(재학 중)

0개의 댓글