C# OpenCV 강좌 : 제 48강 - 윤곽 추적
윤곽 추적(Snake Image)
SnakeImage
함수를 이용하여 이미지나 영상의 윤곽을 추적합니다.
원본(Source, src)
은 영상이나 이미지를 사용합니다.
-
영상 사용하기
: [3강 바로가기][3강] -
이미지 사용하기
: [4강 바로가기][4강]
메인 코드
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenCvSharp;
namespace Project
{
class OpenCV : IDisposable
{
IplImage snake;
public IplImage SnakeImage(IplImage src)
{
IplImage snake_calc = new IplImage(src.Size, BitDepth.U8, 1);
snake = new IplImage(src.Size, BitDepth.U8, 3);
Cv.CvtColor(src, snake_calc, ColorConversion.BgrToGray);
Cv.Threshold(snake_calc, snake_calc, 150, 255, ThresholdType.Binary);
Cv.Smooth(snake_calc, snake_calc, SmoothType.Gaussian, 9);
int contour_num = 2000;
CvPoint[] contour = new CvPoint[contour_num];
CvPoint center = new CvPoint(snake_calc.Width / 2, snake_calc.Height / 2);
for (int i = 0; i < contour.Length; i++)
{
contour[i].X = (int)(center.X * Math.Cos(2 * Math.PI * i / contour.Length) + center.X);
contour[i].Y = (int)(center.Y * Math.Sin(2 * Math.PI * i / contour.Length) + center.Y);
}
CvWindow window = null;
int k = 0;
while ( k < contour_num / 2)
{
k++;
window = new CvWindow("SnakeImage", WindowMode.StretchImage);
window.Resize(640, 480);
Cv.SnakeImage(snake_calc, contour, 0.50f, 0.40f, 0.30f, new CvSize(15, 15), new CvTermCriteria(1), true);
Cv.Copy(src, snake);
for (int i = 0; i < contour.Length - 1; i++)
{
Cv.Line(snake, contour[i], contour[i + 1], CvColor.Red, 5);
}
Cv.Line(snake, contour[contour.Length - 1], contour[0], CvColor.Red, 5);
window.Image = snake;
Application.DoEvents();
}
window.Close();
return snake;
}
public void Dispose()
{
if (snake != null) Cv.ReleaseImage(snake);
}
}
}
세부 코드
IplImage snake_calc = new IplImage(src.Size, BitDepth.U8, 1);
snake = new IplImage(src.Size, BitDepth.U8, 3);
계산에 사용할 snake_calc
와 결과에 사용할 snake
를 생성합니다.
Cv.CvtColor(src, snake_calc, ColorConversion.BgrToGray);
Cv.Threshold(snake_calc, snake_calc, 150, 255, ThresholdType.Binary);
Cv.Smooth(snake_calc, snake_calc, SmoothType.Gaussian, 9);
snake_calc
를 그레이스케일
로 변환 후, 이진화
를 적용합니다.
이 후 가우시안 블러
를 적용하여 이미지를 단순화합니다.
int contour_num = 2000;
CvPoint[] contour = new CvPoint[contour_num];
CvPoint center = new CvPoint(snake_calc.Width / 2, snake_calc.Height / 2);
윤곽의 개수로 사용할 contour_num
을 생성합니다.
contour
를 생성하여 contour_num
의 개수만큼 생성합니다.
center
를 생성하여 윤곽 추적을 위한 이미지의 중심점
을 생성합니다.
for (int i = 0; i < contour.Length; i++)
{
contour[i].X = (int)(center.X * Math.Cos(2 * Math.PI * i / contour.Length) + center.X);
contour[i].Y = (int)(center.Y * Math.Sin(2 * Math.PI * i / contour.Length) + center.Y);
}
for
문을 사용하여 중심점을 기준으로 coutour_num
개수만큼 둘러싸게 합니다.
윤곽의 X 좌표
와 Y 좌표
를 저장합니다.
- Tip : 초기 윤곽은 중심점(center)을 기준으로 둥글게 생성됩니다.
CvWindow window = null;
윤곽 추적을 보여줄 window
를 생성합니다.
int k = 0;
while ( k < contour_num / 2)
{
k++;
...
}
윤곽 추적을 위하여 contour_num
의 절반만큼 반복합니다.
window = new CvWindow("SnakeImage", WindowMode.StretchImage);
window.Resize(640, 480);
window
를 생성하고 크기 모드를 StretchImage
로 사용하며 크기를 적절하게 변경합니다.
Cv.SnakeImage(snake_calc, contour, 0.50f, 0.40f, 0.30f, new CvSize(15, 15), new CvTermCriteria(1), true);
Cv.SnakeImage
를 사용하여 윤곽을 추적합니다.
Cv.SnakeImage(이미지, 윤곽선, 알파, 베타, 감마, 이웃 크기, 종료 기준, 그라디언트 플래그)
입니다.
-
알파
: 연속성의 가중치입니다. -
베타
: 곡률의 가중치입니다. -
감마
: 이미지의 가중치입니다. -
이웃크기
: 최솟값을 검색하는데 사용되는 모든 이웃 점의 크기입니다. -
종료 기준
: 반복 알고리즘의 종료 기준입니다. 최대 반복 횟수를 의미합니다. -
그라디언트 플래그
: 모든 이미지 픽셀에 대한 그래디언트 크기를 계산하고이를 에너지 필드로 간주 유/무 입니다.
Cv.Copy(src, snake);
그려진 윤곽선을 지우고 새롭게 그리기 위하여 원본을 덧씌웁니다.
for (int i = 0; i < contour.Length - 1; i++)
{
Cv.Line(snake, contour[i], contour[i + 1], CvColor.Red, 5);
}
Cv.Line(snake, contour[contour.Length - 1], contour[0], CvColor.Red, 5);
for
문을 이용하여 윤곽점을 이어 윤곽선으로 그립니다.
for
문에서는 첫 번째 윤곽점과 마지막 윤곽점을 잇지 못하므로 for
문이 모두 반복된 후 남은 점을 잇습니다.
window.Image = snake;
Application.DoEvents();
window
에 윤곽 추적 결과를 표시합니다.
Application.DoEvents()
를 사용하여 while
문이 반복중에도 윈도우 창이 업데이트
되도록 합니다.
- Tip : 네임스페이스에
using System.Windows.Forms;
이 포함되어야 합니다.
window.Close();
추적이 완료되면 window
를 닫습니다.
출력 결과
공유하기


댓글 남기기