C# OpenCV 강좌 : 제 54강 - 개체 제거

C# OpenCV Inpaint

C# OpenCV 강좌 : 제 54강 - 개체 제거
[ C#-OpenCvSharp2 ] - 윤대희

개체 제거(Inpaint)


1 이미지에서 불필요한 부분이나 영역제거한 후, 주변의 화소값으로 대체합니다.


원본(Source, src)를 영상이나 이미지를 사용하면 됩니다.

영상 사용하기 : 3강 바로가기

이미지 사용하기 : 4강 바로가기



Main Code


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp;

namespace test
{
    class OpenCV : IDisposable
    {
        IplImage inpaint;

        public IplImage InpaintImage(IplImage src)
        {
            inpaint = new IplImage(src.Size, BitDepth.U8, 3);
            IplImage paint = src.Clone();
            IplImage mask = new IplImage(src.Size, BitDepth.U8, 1);

            CvWindow win_Paint = new CvWindow("Paint", WindowMode.AutoSize, paint);

            CvPoint prevPt = new CvPoint(-1, -1);
            win_Paint.OnMouseCallback += delegate (MouseEvent eve, int x, int y, MouseEvent flag)
            {
                if (eve == MouseEvent.LButtonDown)
                {
                    prevPt = new CvPoint(x, y);
                }
                else if (eve == MouseEvent.LButtonUp || (flag & MouseEvent.FlagLButton) == 0)
                {
                    prevPt = new CvPoint(-1, -1);
                }
                else if (eve == MouseEvent.MouseMove && (flag & MouseEvent.FlagLButton) != 0)
                {
                    CvPoint pt = new CvPoint(x, y);

                    Cv.DrawLine(mask, prevPt, pt, CvColor.White, 5, LineType.AntiAlias, 0);
                    Cv.DrawLine(paint, prevPt, pt, CvColor.White, 5, LineType.AntiAlias, 0);
                    prevPt = pt;
                    win_Paint.ShowImage(paint);
                }
            };

            bool repeat = true;
            while (repeat)
            {
                switch (CvWindow.WaitKey(0))
                {
                    case 'r':
                        mask.SetZero();
                        Cv.Copy(src, paint);
                        win_Paint.ShowImage(paint);
                        break;
                    case '\r':
                        CvWindow win_Inpaint = new CvWindow("Inpainted", WindowMode.AutoSize);
                        Cv.Inpaint(paint, mask, inpaint, 3, InpaintMethod.NS);
                        win_Inpaint.ShowImage(inpaint);
                        break;
                    case (char)27:
                        CvWindow.DestroyAllWindows();
                        repeat = false;
                        break;
                }
            }
            return inpaint;
        }

        public void Dispose()
        {
            if (inpaint != null) Cv.ReleaseImage(inpaint);  
        }
    }
}



Class Code


inpaint = new IplImage(src.Size, BitDepth.U8, 3);
IplImage paint = src.Clone();
IplImage mask = new IplImage(src.Size, BitDepth.U8, 1);

결과 이미지로 사용할 inpaint의 속성을 설정합니다.

계산 이미지로 사용할 paint를 생성하고 원본을 복제합니다.

마스크로 사용할 mask를 생성하고 속성을 설정합니다.


CvWindow win_Paint = new CvWindow("Paint", WindowMode.AutoSize, paint);

계산 이미지위에 마스크를 그릴 수 있게 윈도우 창을 생성합니다.


CvPoint prevPt = new CvPoint(-1, -1);
win_Paint.OnMouseCallback += delegate (MouseEvent eve, int x, int y, MouseEvent flag)
{
    if (eve == MouseEvent.LButtonDown)
    {
        prevPt = new CvPoint(x, y);
    }
    else if (eve == MouseEvent.LButtonUp || (flag & MouseEvent.FlagLButton) == 0)
    {
        prevPt = new CvPoint(-1, -1);
    }
    else if (eve == MouseEvent.MouseMove && (flag & MouseEvent.FlagLButton) != 0)
    {
        CvPoint pt = new CvPoint(x, y);

        Cv.DrawLine(mask, prevPt, pt, CvColor.White, 5, LineType.AntiAlias, 0);
        Cv.DrawLine(paint, prevPt, pt, CvColor.White, 5, LineType.AntiAlias, 0);
        prevPt = pt;
        win_Paint.ShowImage(paint);
    }
};

마우스 콜백 함수를 적용하여 윈도우 창위에 마스크를 직접 생성합니다.

마우스 콜백 알아보기 : 37강 바로가기


이전 마우스 좌표인 prevPt를 생성하고 초기 위치를 (-1, -1)로 초기화합니다.

마우스가 이동하는 동안 계산 이미지마스크을 그립니다.

계산 이미지에는 시각적으로 마스크가 어떻게 그려지는지 확인할 수 있습니다.


bool repeat = true;
while (repeat)
{
    switch (CvWindow.WaitKey(0))
    {
        case 'r':
            mask.SetZero();
            Cv.Copy(src, paint);
            win_Paint.ShowImage(paint);
            break;
        case '\r':
            CvWindow win_Inpaint = new CvWindow("Inpainted", WindowMode.AutoSize);
            Cv.Inpaint(paint, mask, inpaint, 3, InpaintMethod.NS);
            win_Inpaint.ShowImage(inpaint);
            break;
        case (char)27:
            CvWindow.DestroyAllWindows();
            repeat = false;
            break;
    }
}

키 이벤트 함수를 적용하여 윈도우 창에서 서로 다른 함수를 적용합니다.

키 이벤트 알아보기 : 53강 바로가기


r 키가 눌렸을 때 마스크계산 이미지를 초기화합니다.

Enter 키가 눌렸을 때 개체 제거함수를 적용하고, 새로운 윈도우 창에 결과를 표시합니다.

Esc 키가 눌렸을 때 반복을 종료하고 결과를 반환합니다.


Cv.Inpaint(paint, mask, inpaint, 3, InpaintMethod.NS);

Cv.Inpaint()를 사용하여 마스크 위치에 해당하는 개체제거합니다.

Cv.Inpaint(계산 이미지, 마스크, 결과, 반지름, 알고리즘)를 의미합니다.


  • 반지름 : 마스크 내부 픽셀의 색상을 결정하기 위한 주변 영역의 반지름
  • 알고리즘
    • InpaintMethod.NS : Navier-Stokes 방식
    • InpaintMethod.Telea : Alexandru Telea 방식



Result


마스크

2


결과

3



Book Image

개정판이 출간됐습니다!

C#과 파이썬을 활용한 OpenCV 4 프로그래밍 (개정판)

컴퓨터 비전 기초 이론부터 머신러닝을 활용한 영상 처리 프로젝트까지

  • C#과 파이썬용 OpenCV의 데이터 형식과 행렬 및 배열 연산
  • 이미지/동영상/카메라를 활용한 입출력과 결과 저장
  • 전처리 과정과 정보를 탐색하기 위한 이미지 변형
  • 유의미한 정보를 검출하기 위한 이미지 변환
  • 이미지에서 정보를 검출 및 인식
  • 객체 검출을 포함한 모션 추적
  • K-means, KNN, SVM 등의 머신러닝 알고리즘 적용 방법
  • 카페(Caffe), 다크넷(Darknet), 텐서플로 모델을 활용한 딥러닝 모듈 적용 방법
  • Tesseract-OCR과 C# OpenCvSharp4를 활용한 프로젝트
  • 텐서플로와 Python OpenCV4를 활용한 프로젝트
  • 윤대희 저 | 위키북스

    [yes24 바로가기] [알라딘 바로가기] [교보문고 바로가기]

    후원하기


    ⤧  Previous post C# OpenCV 강좌 : 제 53강 - 키 이벤트 ⤧  Next post C# OpenCV 강좌 : 제 55강 - 적분
    C#-OpenCvSharp2 Category