C# OpenCV 강좌 : 제 24강 - 중심점

C# OpenCV Moments

C# OpenCV 강좌 : 제 24강 - 중심점
[ C#-OpenCvSharp2 ] - 윤대희

중심점(Moments)


1 영상이나 이미지의 중심점을 찾기 위해 사용합니다. 영상이나 이미지에서 ContourMoments를 이용해 물체(덩어리)의 중심점을 찾을 수 있습니다.


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

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

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



Class


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

namespace test
{
    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);        
        }
    }
}



Class Code


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를 선언하여 중심점에 관한 정보를 포함하고 있습니다.

cXcY를 선언하여 중심점의 좌표(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, M30
  • Central Moments : Mu02, Mu03, Mu11, Mu12, Mu20, Mu21, Mu30
  • Central Normalized Moments : Nu02, Nu03, Nu11, Nu12, Nu20, Nu21, Nu30
  • Mu00 = M00, Mu01 = 0, Mu10 = 0
  • Nu00 = 1, Nu01 = 0, Nu10 = 0


질량 중심 공식

2



Central Normalized Moments 공식

3



위의 공식을 이용하여 중심점Central Normalized Moments를 구할 수 있습니다.



Result


2



Book Image

개정판이 출간됐습니다!

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

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

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

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

    후원하기


    ⤧  Previous post C# OpenCV 강좌 : 제 23강 - 블록 껍질 ⤧  Next post C# OpenCV 강좌 : 제 25강 - 직선 검출
    C#-OpenCvSharp2 Category