C# OpenCV 강좌 : 제 24강 - 중심점
중심점(Moments)
영상이나 이미지의 중심점을 찾기
위해 사용합니다.
영상이나 이미지에서 Contour
와 Moments
를 이용해 물체(덩어리)의 중심점을 찾을 수 있습니다.
원본(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 bin;
IplImage mom;
public IplImage Binary(IplImage src)
{
bin = new IplImage(src.Size, BitDepth.U8, 1);
Cv.CvtColor(src, bin, ColorConversion.RgbToGray);
Cv.Threshold(bin, bin, 150, 255, ThresholdType.Binary);
return bin;
}
public IplImage Moment(IplImage src)
{
mom = new IplImage(src.Size, BitDepth.U8, 3);
bin = new IplImage(src.Size, BitDepth.U8, 1);
Cv.Copy(src, mom);
bin = this.Binary(src);
CvMemStorage Storage = new CvMemStorage();
CvSeq<CvPoint> contours;
Cv.FindContours(bin, Storage, out contours, CvContour.SizeOf, ContourRetrieval.List, ContourChain.ApproxNone);
CvSeq<CvPoint> apcon_seq = Cv.ApproxPoly(contours, CvContour.SizeOf, Storage, ApproxPolyMethod.DP , 3, true);
CvMoments moments;
int cX = 0, cY = 0;
for (CvSeq<CvPoint> c = apcon_seq; c != null; c = c.HNext)
{
if (c.Total > 4)
{
Cv.Moments(c, out moments, true);
cX = Convert.ToInt32(moments.M10 / moments.M00);
cY = Convert.ToInt32(moments.M01 / moments.M00);
Cv.Circle(mom, new CvPoint(cX, cY), 5, CvColor.Red, -1);
}
}
return mom;
}
public void Dispose()
{
if (bin != null) Cv.ReleaseImage(bin);
if (mom != null) Cv.ReleaseImage(mom);
}
}
}
세부 코드
mom = new IplImage(src.Size, BitDepth.U8, 3);
bin = new IplImage(src.Size, BitDepth.U8, 1);
Cv.Copy(src, mom);
bin = this.Binary(src);
원본 이미지를 복사한 mom
과 Binary 이미지인 bin
을 선언하고 적용시킵니다.
CvMemStorage Storage = new CvMemStorage();
CvSeq<CvPoint> contours;
Cv.FindContours(bin, Storage, out contours, CvContour.SizeOf, ContourRetrieval.List, ContourChain.ApproxNone);
윤곽(Contour)을 검출하기 위하여 Storage
, contours
를 선언하고 Cv.FindContours()
를 적용합니다.
Contour 알아보기
: 20강 바로가기
CvSeq<CvPoint> apcon_seq = Cv.ApproxPoly(contours, CvContour.SizeOf, Storage, ApproxPolyMethod.DP, 3, true);
다각형 곡선을 근사화 하기 위해 Cv.ApproxPoly()
를 사용하여 근사합니다.
ApproxPoly 알아보기
: 22강 바로가기
CvMoments moments;
int cX = 0, cY = 0;
moments
를 선언하여 중심점에 관한 정보
를 포함하고 있습니다.
cX
와 cY
를 선언하여 중심점의 좌표(center_x, center_y)로 사용합니다.
for (CvSeq<CvPoint> c = apcon_seq; c != null; c = c.HNext)
{
if (c.Total > 4)
{
Cv.Moments(c, out moments, true);
cX = Convert.ToInt32(moments.M10 / moments.M00);
cY = Convert.ToInt32(moments.M01 / moments.M00);
Cv.Circle(mom, new CvPoint(cX, cY), 5, CvColor.Red, -1);
}
}
if
문 까지는 22강
과 흡사합니다. 코너를 검출하기 위해 사용합니다. 자세한 사항은 22강
의 설명을 참고하시기 바랍니다.
Cv.Moments()
를 이용하여 중심점에 대한 정보를 받아옵니다. Cv.Moments(물체의 코너점들, 중심점 데이터, Binary조건)
입니다.
out moments
를 통하여 검출된 moments
를 저장하며, Binary조건
은 참일 경우 0의 값이 아닌 이미지 픽셀은 1의 값으로 처리하게됩니다.
cX
, cY
에 중심점을 계산하여 저장합니다. moments.*
은 double
형이기 때문에 int
형식으로 변환합니다.
moments.*
에는 Spatial Moments
, Central Moments
가 저장되어 있으며, 계산을 통하여 Central Normalized Moments
를 얻을 수 있습니다.
Spatial Moments
: M00, M01, M02, M03, M10, M11, M12, M20, M21, M30Central Moments
: Mu02, Mu03, Mu11, Mu12, Mu20, Mu21, Mu30Central Normalized Moments
: Nu02, Nu03, Nu11, Nu12, Nu20, Nu21, Nu30- Mu00 = M00, Mu01 = 0, Mu10 = 0
- Nu00 = 1, Nu01 = 0, Nu10 = 0
질량 중심 공식
Central Normalized Moments 공식
위의 공식을 이용하여 중심점
과 Central Normalized Moments
를 구할 수 있습니다.
출력 결과
공유하기


댓글 남기기