상위 목록: 하위 목록: 작성 날짜: 읽는 데 27 분 소요

코너(Corner)

영상이나 이미지의 모서리(코너)를 검출하기 위해 사용합니다.

영상이나 이미지에서 Good Feature to Track 방법과 Harris Corner Detector 방법을 이용하여 검출 할 수 있습니다.

원본(Source, src)은 영상이나 이미지를 사용합니다.



Good Feature to Track

클래스 코드

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

namespace Project
{
    class OpenCV : IDisposable
    {  
        IplImage gray;    
        IplImage corner;        
        
        public IplImage GrayScale(IplImage src)
        {
            gray = new IplImage(src.Size, BitDepth.U8, 1);
            Cv.CvtColor(src, gray, ColorConversion.BgrToGray);
            return gray;
        }
                
        public IplImage GoodFeaturesToTrack(IplImage src)
        {
            corner = new IplImage(src.Size, BitDepth.U8, 3);   
            gray = new IplImage(src.Size, BitDepth.U8, 1);
            IplImage eigImg = new IplImage(src.Size, BitDepth.U8, 1);
            IplImage tempImg = new IplImage(src.Size, BitDepth.U8, 1);
            
            Cv.Copy(src, corner);        
            gray = this.GrayScale(src);
            
            CvPoint2D32f[] corners;
            int cornerCount = 150;

            Cv.GoodFeaturesToTrack(gray, eigImg, tempImg, out corners, ref cornerCount, 0.01, 5);
            
            Cv.FindCornerSubPix(gray, corners, cornerCount, new CvSize(3, 3), new CvSize(-1, -1), new CvTermCriteria(20, 0.03));                 

            for (int i = 0; i < cornerCount; i++)
            {        
                Cv.Circle(corner, corners[i], 3, CvColor.Black, 2);       
            } 
                          
            return corner;
        }
            
        public void Dispose()
        {
            if (gray != null) Cv.ReleaseImage(gray);        
            if (corner != null) Cv.ReleaseImage(corner);        
        }
    }
}


세부 코드

corner = new IplImage(src.Size, BitDepth.U8, 3);   
gray = new IplImage(src.Size, BitDepth.U8, 1);
IplImage eigImg = new IplImage(src.Size, BitDepth.U8, 1);
IplImage tempImg = new IplImage(src.Size, BitDepth.U8, 1);

코너는 8Bit 단일 채널, GrayScale 영상으로 검출합니다.

출력할 이미지인 corner와 검색할 이미지인 gray를 만듭니다.

또한, GoodFeaturesToTrack에 사용하기 위한 매개변수 이미지 eigImg, tempImg를 만들어줍니다.


Cv.Copy(src, corner);        
gray = this.GrayScale(src);

corner에 원본 이미지를 복사하여 덮어씌웁니다. grayGrayScale을 적용시킵니다.


CvPoint2D32f[] corners;
int cornerCount = 150;

corners는 검색된 코너의 벡터 값이며, cornerCount는 반환할 코너의 최대 개수입니다.

이 값 보다 더 많은 코너가 검출되면 가장 값이 높은 코너가 반환됩니다.


 Cv.GoodFeaturesToTrack(gray, eigImg, tempImg, out corners, ref cornerCount, 0.01, 5);

Cv.GoodFeaturesToTrack()를 이용하여 코너들을 검출합니다.

Cv.GoodFeaturesToTrack(그레이스케일, eigImg, tempImg, 코너점, 코너의 개수, 퀄리티 레벨, 최소 거리)입니다.

qualityLevel(퀄리티 레벨)은 코너 품질을 설정하는 데 사용됩니다.

가장 좋은 코너의 측정 값에 퀄리티 레벨 수치를 곱한 값 보다 낮은 값이면 그 코너들은 무시됩니다.

만약, 가장 좋은 코너의 측정 값이 1000에 퀄리티레벨이 0.01이라면 10이하의 코너 측정값은 검출하지 않습니다.

minDistance(최소 거리)는 검출된 코너들의 최소거리입니다.

최소거리의 이상의 값만 검출합니다.

만약 최소거리가 5라면, 최소거리가 5 이하인 값은 코너로 검출하지 않습니다.


Cv.FindCornerSubPix(gray, corners, cornerCount, new CvSize(3, 3), new CvSize(-1, -1), new CvTermCriteria(20, 0.03));

Cv.FindCornerSubPix()를 이용하여 코너점들의 위치를 수정합니다.

Cv.FindCornerSubPix(그레이스케일, 코너점, 코너의 개수, win Size, zeroZone Size, 기준)입니다.

win Size는 검출하려는 부분의 절반 크기입니다.

만약, (3, 3) 일 경우 (3 * 2 + 1) x (3 * 2 + 1) = 7x7 의 부분을 검색합니다.

zeroZone Size는 검출에서 제외하려는 부분의 절반 크기입니다.

win과 동일한 계산방법을 사용합니다. (-1, -1)은 검출에서 제외하려는 부분이 없음을 의미합니다.

Criteria(기준)은 코너 정밀화 반복작업입니다.

new CvTermCriteria(maxlter, epsilon)입니다.

maxlter는 입력된 수치 만큼 반복작업하며, epsilon보다 값이 낮아지면 종료합니다.


for (int i = 0; i < cornerCount; i++)
{        
    Cv.Circle(corner, corners[i], 3, CvColor.Black, 2);       
} 

for문과 Cv.Circle을 이용하여 검출된 코너점들을 corner이미지에 그립니다.



Good Feature to Track - Harris Corner Detector

클래스 코드

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

namespace Project
{
    class OpenCV : IDisposable
    {  
        IplImage gray;    
        IplImage corner;        
        
        public IplImage GrayScale(IplImage src)
        {
            gray = new IplImage(src.Size, BitDepth.U8, 1);
            Cv.CvtColor(src, gray, ColorConversion.BgrToGray);
            return gray;
        }
                
        public IplImage GoodFeaturesToTrack(IplImage src)
        {
            corner = new IplImage(src.Size, BitDepth.U8, 3);   
            gray = new IplImage(src.Size, BitDepth.U8, 1);
            IplImage eigImg = new IplImage(src.Size, BitDepth.U8, 1);
            IplImage tempImg = new IplImage(src.Size, BitDepth.U8, 1);
            
            Cv.Copy(src, corner);
            gray = this.GrayScale(src);
            
            CvPoint2D32f[] corners;
            int cornerCount = 150;

            Cv.GoodFeaturesToTrack(gray, eigImg, tempImg, out corners, ref cornerCount, 0.01, 5, null, 3, true, 0.01);
                    
            Cv.FindCornerSubPix(gray, corners, cornerCount, new CvSize(3, 3), new CvSize(-1, -1), new CvTermCriteria(20, 0.03));                 

            for (int i = 0; i < cornerCount; i++)
            {        
                Cv.Circle(corner, corners[i], 3, CvColor.Black, 2);       
            } 
                          
            return corner;
        }
            
        public void Dispose()
        {
            if (gray != null) Cv.ReleaseImage(gray);        
            if (corner != null) Cv.ReleaseImage(corner);        
        }
    }
}


세부 코드

Cv.GoodFeaturesToTrack(gray, eigImg, tempImg, out corners, ref cornerCount, 0.01, 5, null, 3, true, 0.01);

Cv.GoodFeaturesToTrack()를 그대로 이용하여 Harris Corner Detector를 적용할 수 있습니다.

Cv.GoodFeaturesToTrack()를 이용하여 코너들을 검출합니다.

Cv.GoodFeaturesToTrack(그레이스케일, eigImg, tempImg, 코너점, 코너의 개수, 퀄리티 레벨, 최소 거리, 마스크, 블록 크기, Harris 방법 사용 유/무, ksize)입니다.

mask(마스크)는 코너가 감지되는 영역을 지정합니다.

blockSize(블록 크기)는 코너 계산을 위한 평균 블록의 크기입니다.

useHarrisDetector(Haris 방법 사용 유/무)는 Harris 방법을 사용할지에 대한 bool값 입니다.

ksize는 Harris 방법의 매개 변수입니다.



Harris Corner Detector

클래스 코드

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

namespace Project
{
    class OpenCV : IDisposable
    {  
        IplImage gray;    
        IplImage corner;        
                
        public IplImage GrayScale(IplImage src)
        {
            gray = new IplImage(src.Size, BitDepth.U8, 1);
            Cv.CvtColor(src, gray, ColorConversion.BgrToGray);
            return gray;
        }

        public IplImage HarrisCorner(IplImage src)
        {
            gray = new IplImage(src.Size, BitDepth.U8, 1);
            corner = new IplImage(src.Size, BitDepth.F32, 1);

            gray = this.GrayScale(src);

            Cv.CornerHarris(gray, corner, 3, ApertureSize.Size3, 0.05);

            Cv.Dilate(corner, corner);
                    
            return corner;
        }
            
        public void Dispose()
        {
            if (gray != null) Cv.ReleaseImage(gray);        
            if (corner != null) Cv.ReleaseImage(corner);        
        }
    }
}


세부 코드

Cv.CornerHarris(gray, corner, 3, ApertureSize.Size3, 0.05);

Cv.CornerHarris()를 이용하여 Harris 방법을 적용합니다.

CvCornerHarris(그레이스케일, 반환이미지, ApertureSize, kisze)를 사용합니다.


Cv.Dilate(corner, corner);

Cv.Dilate(corner, corner)를 이용하여 이미지에서 이웃한 화소들 중 최대 화소값으로 대체하여 선명하게 만듭니다.



출력 결과

Good Feature to Track


Good Feature to Track - Harris Corner Detector


Harris Corner Detector

댓글 남기기