C# OpenCV 강좌 : 제 54강 - 개체 제거
개체 제거(Inpaint)
이미지에서 불필요한 부분
이나 영역
을 제거한 후, 주변의 화소값으로 대체합니다.
원본(Source, src)
은 영상이나 이미지를 사용합니다.
메인 코드
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp;
namespace Project
{
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);
}
}
}
세부 코드
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);
}
};
마우스 콜백
함수를 적용하여 윈도우 창
위에 마스크
를 직접 생성합니다.
이전 마우스 좌표인 prevPt
를 생성하고 초기 위치를 (-1, -1)
로 초기화합니다.
마우스
가 이동하는 동안 계산 이미지
와 마스크
에 선
을 그립니다.
계산 이미지
에는 시각적으로 마스크
가 어떻게 그려지는지 확인할 수 있습니다.
마우스 콜백 알아보기
: 37강 바로가기
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;
}
}
키 이벤트
함수를 적용하여 윈도우 창
에서 서로 다른 함수
를 적용합니다.
r 키
가 눌렸을 때 마스크
와 계산 이미지
를 초기화합니다.
Enter 키
가 눌렸을 때 개체 제거
함수를 적용하고, 새로운 윈도우 창에 결과
를 표시합니다.
Esc 키
가 눌렸을 때 반복
을 종료하고 결과를 반환합니다.
키 이벤트 알아보기
: 53강 바로가기
Cv.Inpaint(paint, mask, inpaint, 3, InpaintMethod.NS);
Cv.Inpaint()
를 사용하여 마스크
위치에 해당하는 개체
를 제거
합니다.
Cv.Inpaint(계산 이미지, 마스크, 결과, 반지름, 알고리즘)
를 의미합니다.
반지름
: 마스크 내부 픽셀의 색상을 결정하기 위한 주변 영역의 반지름알고리즘
InpaintMethod.NS
: Navier-Stokes 방식InpaintMethod.Telea
: Alexandru Telea 방식
출력 결과
마스크
결과
공유하기


댓글 남기기