C# OpenCV 강좌 : 제 46강 - 피라미드 평균 이동 분할

   

피라미드 평균 이동 분할(Pyramid Mean Shift Filtering)


1 PyrMeanShiftFiltering 함수를 이용하여 이미지 피라미드에 의한 평균 이동 분할을 진행합니다. 레벨을 지정하여 이미지 피라미드를 만들고 이 정보를 이용하여 이미지 분할을 실행합니다. 공간 윈도우 반경색상 윈도우 반경을 사용하여 평균 공간 값평균 색 벡터로 최종 값이 설정됩니다.


  • Tip : 피라미드 평균 이동 분할은 매우 높은 계산 시간을 요구합니다. 적절한 이미지의 크기와 매개 변수 값을 사용해야합니다.


Main Code


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

namespace test
{
    class OpenCV : IDisposable
    {  
        IplImage pyrmean;
        
        public IplImage PyrMeanShiftFiltering(IplImage src)
        {
            IplImage srcROI = src.Clone();
            pyrmean = new IplImage(src.Size, BitDepth.U8, 3);

            int level = 2;
            double spatial_radius = 30.0;
            double color_radius = 30.0;
            
            CvRect roi = new CvRect
            {
                X = 0,
                Y = 0,
                Width = srcROI.Width & -(1 << level),
                Height = srcROI.Height & -(1 << level)
            };
            
            srcROI.ROI = roi;
            pyrmean = srcROI.Clone();        
                    
            Cv.PyrMeanShiftFiltering(srcROI, pyrmean, space_radius, color_radius, level, new CvTermCriteria(3, 1));

            return pyrmean;
        }
                  
        public void Dispose()
        {
            if (pyrmean != null) Cv.ReleaseImage(pyrmean);
        }
    }
}


Class Code


IplImage srcROI = src.Clone();
pyrmean = new IplImage(src.Size, BitDepth.U8, 3);

계산에 사용할 srcROI를 생성하여 src를 복사하여 저장합니다.

결과에 사용할 pyrmean를 생성합니다.


int level = 2;
double space_radius = 30.0;
double color_radius = 30.0;

주요 매개변수인 레벨공간 윈도우 반경, 색상 윈도우 반경을 선언합니다.

레벨은 비트 연산시 사용할 값입니다. 레벨값이 높을 수록 보여지는 이미지가 일부 누락될 수 있습니다.

공간 윈도우 반경은 각각의 픽셀(X, Y)에서 계산될 픽셀(x, y)의 범위를 설정합니다.

색상 윈도우 반경은 픽셀의 성분 벡터(R, G, B)에서 공간 윈도우 반경의 픽셀 성분 벡터(r, g, b)를 뺏을 때의 허용치입니다.


공간색상
(X, Y)(R, G, B)
(x, y)(r, g, b)


공간계산식
xX - spatial radius ≤ x ≤ X + spatial radius
yY - spatial radius ≤ y ≤ Y + spatial radius


색상
││(R,G,B) - (r, g, b)││ ≤ color_radius



CvRect roi = new CvRect()
{
    X = 0,
    Y = 0,
    Width = srcROI.Width & -(1 << (level + 1)),
    Height = srcROI.Height & -(1 << (level + 1))
};

관심 영역으로 사용할 roi를 생성합니다.

너비높이AND연산을 통하여 좌측으로 쉬프트 시킵니다. 2의 보수법을 사용합니다.


srcROI.ROI = roi;
pyrmean = srcROI.Clone();

srcROI관심 영역을 적용합니다. 관심 영역이 적용된 srcROI를 pyrmean에 복사합니다.


Cv.PyrMeanShiftFiltering(srcROI, pyrmean, space_radius, color_radius, level, new CvTermCriteria(3, 1));

Cv.PyrMeanShiftFiltering()을 적용합니다. Cv.PyrMeanShiftFiltering(원본, 결과, 공간 윈도우 반경, 공간 색상 반경, 레벨, 종결기준)을 사용합니다.

종결기준new CvTermCriteria(최대반복횟수, 정확성)을 사용합니다.


Result


level 2, space_radius 30.0, color_radius 30.0

2

level 2, space_radius 60.0, color_radius 30.0

3

level 2, space_radius 30.0, color_radius 60.0

4

level 2, space_radius 60.0, color_radius 60.0

5

level 2, space_radius 30.0, color_radius 60.0, CvTermCriteria(7, 3)

5



도움이 되셨다면 광고 클릭 부탁드립니다.

⤧  Next post C# OpenCV 강좌 : 제 47강 - 2D 필터링 ⤧  Previous post C# OpenCV 강좌 : 제 45강 - 피라미드 화상 분할