c++ 허프변환 opencv로 견고한(색상 및 크기 불변) 원 검출 작성(Hough 변환 또는 기타 기능 기반)




허프변환 원 검출 (5)

이미지에서 원을 찾기 위해 다음과 같은 매우 간단한 파이썬 코드를 작성했습니다.

import cv
import numpy as np

WAITKEY_DELAY_MS = 10
STOP_KEY = 'q'

cv.NamedWindow("image - press 'q' to quit", cv.CV_WINDOW_AUTOSIZE);
cv.NamedWindow("post-process", cv.CV_WINDOW_AUTOSIZE);

key_pressed = False
while key_pressed != STOP_KEY:

    # grab image
    orig = cv.LoadImage('circles3.jpg')

    # create tmp images
    grey_scale = cv.CreateImage(cv.GetSize(orig), 8, 1)
    processed = cv.CreateImage(cv.GetSize(orig), 8, 1)


    cv.Smooth(orig, orig, cv.CV_GAUSSIAN, 3, 3)

    cv.CvtColor(orig, grey_scale, cv.CV_RGB2GRAY)

    # do some processing on the grey scale image
    cv.Erode(grey_scale, processed, None, 10)
    cv.Dilate(processed, processed, None, 10)
    cv.Canny(processed, processed, 5, 70, 3)
    cv.Smooth(processed, processed, cv.CV_GAUSSIAN, 15, 15)

    storage = cv.CreateMat(orig.width, 1, cv.CV_32FC3)

    # these parameters need to be adjusted for every single image
    HIGH = 50
    LOW = 140

    try: 
        # extract circles
        cv.HoughCircles(processed, storage, cv.CV_HOUGH_GRADIENT, 2, 32.0, HIGH, LOW)

        for i in range(0, len(np.asarray(storage))):
            print "circle #%d" %i
            Radius = int(np.asarray(storage)[i][0][2])
            x = int(np.asarray(storage)[i][0][0])
            y = int(np.asarray(storage)[i][0][1])
            center = (x, y)

            # green dot on center and red circle around
            cv.Circle(orig, center, 1, cv.CV_RGB(0, 255, 0), -1, 8, 0)
            cv.Circle(orig, center, Radius, cv.CV_RGB(255, 0, 0), 3, 8, 0)

            cv.Circle(processed, center, 1, cv.CV_RGB(0, 255, 0), -1, 8, 0)
            cv.Circle(processed, center, Radius, cv.CV_RGB(255, 0, 0), 3, 8, 0)

    except:
        print "nothing found"
        pass

    # show images
    cv.ShowImage("image - press 'q' to quit", orig)
    cv.ShowImage("post-process", processed)

    cv_key = cv.WaitKey(WAITKEY_DELAY_MS)
    key_pressed = chr(cv_key & 255)

다음 두 가지 예에서 알 수 있듯이 '원 찾기 품질'은 매우 다양합니다.

사례 1 :

사례 2 :

Case1과 Case2는 기본적으로 동일한 이미지이지만 여전히 알고리즘이 다른 원을 감지합니다. 알고리즘에 다른 크기의 원이있는 이미지를 표시하면 원 검출이 완전히 실패 할 수도 있습니다. 이는 주로 각각의 새 사진에 대해 개별적으로 조정해야하는 HIGHLOW 매개 변수 때문입니다.

따라서 내 질문 : 이 알고리즘을보다 강력하게 만들 수있는 다양한 가능성은 무엇입니까? 크기와 색상이 일정하지 않아야 서로 다른 색상과 크기의 서로 다른 원이 감지됩니다. 어쩌면 Hough 변환을 사용하는 것이 최선의 방법이 아닌가? 더 나은 접근법이 있습니까?


Hough 변환은 "모델"을 사용하여 모서리가 감지 된 이미지에서 특정 피쳐를 찾습니다. HoughCircles 의 경우 모델은 완벽한 원입니다. 즉, 오탐 (false positive)의 수를 늘리지 않고도 사진에서 더 이상하지 않고 타원 모양의 원을 감지 할 수있는 매개 변수 조합이 존재하지 않을 수도 있습니다. 다른 한편으로, 기본 투표 메커니즘으로 인해, "닫힌 (dent)"이있는 닫히지 않은 완전한 원 또는 완전한 원이 계속 나타날 수 있습니다. 따라서 예상 출력에 따라이 방법을 사용하거나 사용하지 않을 수도 있습니다.

즉,이 기능을 통해 내가 도울 수있는 몇 가지 사항이 있습니다.

  1. HoughCirclesCanny 내부적으로 전화를합니다. 그래서 당신은 그 전화를 끊을 수 있습니다.
  2. param1 (당신이 HIGH 라고 부름)은 전형적으로 200 의 값으로 초기화된다. 이것은 Canny 에 대한 내부 호출에 대한 매개 변수로 사용됩니다 : cv.Canny(processed, cannied, HIGH, HIGH/2) . 이처럼 Canny 직접 실행하면 Hough 설정이 Hough 변환에 사용 된 이미지에 어떻게 영향을 주는지 확인할 수 있습니다.
  3. param2 ( LOW )는 일반적으로 값 100 주위에서 초기화됩니다. Hough 변환의 누산기에 대한 투표 임계 값입니다. 이 값을 높게 설정하면 위양성이 많아지고 위양성이 낮아집니다. 나는 이것이 당신이 주변을 조롱하기 시작하려는 첫 번째 것이라고 믿습니다.

참고 : http://docs.opencv.org/3.0-beta/modules/imgproc/doc/feature_detection.html#houghcircles

업데이트 된 원 : 채워진 원 : Hough 변환을 사용하여 원 모양을 찾으면 경계 색을 샘플링하고이를 예상 원 안의 하나 이상의 점과 비교하여 채워지는지 테스트 할 수 있습니다. 또는 추정 원 안의 하나 이상의 점을 주어진 배경색과 비교할 수 있습니다. 이전 비교가 성공하면 원이 채워지고, 실패하면 대체 비교의 경우 원이 채워집니다.


이것은 훌륭한 모델링 문제입니다. 나는 다음의 추천 / 아이디어를 가지고있다 :

  1. 이미지를 RGB로 분할 한 다음 처리하십시오.
  2. 사전 처리.
  3. 동적 매개 변수 검색.
  4. 제약 조건을 추가하십시오.
  5. 당신이 탐지하려고 시도하고있는 것을 확실하게하십시오.

더 자세하게:

1 : 다른 답변에서 언급했듯이, 회색 음영으로 변환하면 너무 많은 정보가 삭제되므로 배경과 비슷한 밝기의 원은 모두 손실됩니다. 색상 채널을 격리되어 있거나 다른 색상 공간에서 고려하는 것이 훨씬 좋습니다. 여기에는 거의 두 가지 방법이 있습니다 : HoughCircles 된 각 채널에서 HoughCirclesHoughCircles 으로 수행 한 다음 결과를 결합하거나 채널을 처리 한 다음 결합하여 HoughCircles 를 조작 HoughCircles . 아래의 제 시도에서 두 번째 방법을 시도했습니다. RGB 채널로 분할하고 처리 한 다음 결합합니다. 결합 할 때 이미지를 포화시키는 것에주의하십시오.이 이미지를 사용하지 cv.And 려면이 단계를 사용하십시오.이 단계에서 내 서클은 항상 흰색 배경에 검은 색 고리 / 디스크입니다.

2 : 전처리는 매우 까다 롭습니다. AdaptiveThreshold 는 로컬 평균을 기준으로 픽셀을 임계 값으로 설정하여 이미지의 가장자리를 향상시킬 수있는 강력한 회선 방법입니다 (유사한 프로세스가 포유류 시각 시스템의 초기 경로에서도 발생 함). 이것은 약간의 잡음을 줄이기 때문에 유용합니다. 나는 단 한 번의 통과로 dilate/erode 을 사용했습니다. 그리고 나는 다른 매개 변수를 어떻게 유지했는지 알았습니다. HoughCircles 가 '채워진 원'을 찾는 데 많은 도움이되기 전에 Canny 를 사용하는 것 같습니다.이 사전 처리는 상당히 무겁고 다소 더 많은 'blobby circle'을 포함하는 오 탐지로 이어질 수 있지만, 우리의 경우 이것은 아마도 바람직 할 것인가?

3 : 최적의 솔루션을 얻으려면 각 이미지에 대해 HoughCircles 매개 변수 param2 (매개 변수 LOW )를 조정해야합니다. 실제로는 docs 에서 확인하십시오.

크기가 작을수록 더 많은 거짓 서클이 감지 될 수 있습니다.

문제는 모든 이미지에서 달콤한 부분이 달라질 것입니다. 여기서 가장 좋은 방법은 조건을 설정하고이 조건이 충족 될 때까지 다른 param2 값을 검색하는 것입니다. 이미지에 중첩되지 않는 서클이 표시되며 param2 가 너무 낮 으면 일반적으로 겹치는 서클이 많이 param2 . 그래서 나는 다음을 찾도록 제안한다 :

비 중첩 및 포함되지 않은 서클의 최대 수

그래서 우리는 이것이 충족 될 때까지 param2 값이 다른 HoughCircles를 계속 호출합니다. 아래 예제에서 param2 임계 값 가정에 도달 할 때까지 증가시킵니다. 이것이 언제 충족되는지를 찾기 위해서 바이너리 검색을 수행하는 것이 더 빠르며 (그리고 상당히 쉽다), opencv는 종종 무해한 param2 값을위한 에러를 throw하기 때문에 예외 처리에주의를 기울여야한다. 내 설치). 일치하는 데 매우 유용한 다른 조건은 서클의 수입니다.

4 : 모델에 추가 할 수있는 제약이 더 있습니까? 우리가 우리 모델에 서클을 탐지하기 위해 할 수있는 일을 쉽게 말할 수있는 물건이 많을수록. 예를 들어, 우리는 다음을 알고 있습니까?

  • 서클의 수입니다. - 상한선 또는 하한선이 도움이됩니다.
  • 원 또는 배경 또는 '비 원'의 가능한 색상입니다.
  • 그들의 크기.
  • 그들이 이미지에있을 수있는 곳.

5 : 이미지의 얼룩 중 일부는 느슨하게 동그라미라고 할 수 있습니다! 두 번째 이미지에서 두 개의 '원형이 아닌 얼룩 (blob)'을 생각해 보겠습니다. 코드에서 찾을 수 없습니다 (좋음). 그러나 ... 포토샵을 사용하면 더 원형이되고, 코드에서 찾을 수 있습니다. 어쩌면 원이 아닌 것을 탐지하고 싶다면 Tim Lukins 와 같은 다른 접근법이 더 좋을 수 있습니다.

문제들

무거운 전처리 AdaptiveThresholding 과`Canny '를 수행함으로써 이미지의 특징에 많은 왜곡이 생길 수 있습니다. 이로 인해 잘못된 서클 감지 또는 잘못된 반경보고가 발생할 수 있습니다. 예를 들어 처리 후 대형 솔리드 디스크가 링으로 나타날 수 있으므로 HughesCircles에서 내부 링을 찾을 수 있습니다. 심지어 문서는 다음과 같이 기록합니다.

... 일반적으로이 함수는 원의 중심을 잘 감지하지만 올바른 반경을 찾지 못할 수 있습니다.

보다 정확한 반지름 감지가 필요하면 다음 방법을 제안합니다 (구현되지 않음).

  • 원본 이미지에서 확대 된 교차점 (4 개의 광선 : 위 / 아래 / 왼쪽 / 오른쪽)에서보고 된 원 중심에서의 광선 추적
  • 각 RGB 채널에서이 작업을 별도로 수행하십시오.
  • 현명한 방식으로 각 광선의 각 채널에 대해이 정보를 결합하십시오 (즉, 필요에 따라 뒤집기, 오프셋, 크기 조절 등)
  • 각 광선의 처음 몇 픽셀에 대해 평균을 취하고 광선의 중요한 편차가 발생하는 곳을 감지하려면이 값을 사용하십시오.
  • 이 4 점은 둘레의 점을 추정 한 것입니다.
  • 이 네 가지 추정치를 사용하여보다 정확한 반지름과 중심 위치 (!)를 결정하십시오.
  • 이것은 네 개의 광선 대신 확장 고리를 사용하여 일반화 할 수 있습니다.

결과

끝에있는 코드는 꽤 좋은 시간을 꽤 많이줍니다.이 예제는 다음과 같이 코드로 수행되었습니다.

첫 번째 이미지의 모든 서클을 감지합니다.

캐니 필터 (canny filter)가 적용되기 전에 사전 처리 된 이미지가 어떻게 보이는지 (다른 색 원이 크게 보임) :

두 번째 이미지에서 두 개 (방울)를 제외한 모든 것을 감지합니다.

변경된 두 번째 이미지 (얼룩이 원형으로 흐려지고 큰 타원형이 원형으로 만들어 감지가 향상됨)

이 Kandinsky 그림 (나는 경계 조건 때문에 동심원 고리를 찾을 수 없음)의 중심을 탐지하는데 꽤 잘 맞 읍니다.

암호:

import cv
import numpy as np

output = cv.LoadImage('case1.jpg')
orig = cv.LoadImage('case1.jpg')

# create tmp images
rrr=cv.CreateImage((orig.width,orig.height), cv.IPL_DEPTH_8U, 1)
ggg=cv.CreateImage((orig.width,orig.height), cv.IPL_DEPTH_8U, 1)
bbb=cv.CreateImage((orig.width,orig.height), cv.IPL_DEPTH_8U, 1)
processed = cv.CreateImage((orig.width,orig.height), cv.IPL_DEPTH_8U, 1)
storage = cv.CreateMat(orig.width, 1, cv.CV_32FC3)

def channel_processing(channel):
    pass
    cv.AdaptiveThreshold(channel, channel, 255, adaptive_method=cv.CV_ADAPTIVE_THRESH_MEAN_C, thresholdType=cv.CV_THRESH_BINARY, blockSize=55, param1=7)
    #mop up the dirt
    cv.Dilate(channel, channel, None, 1)
    cv.Erode(channel, channel, None, 1)

def inter_centre_distance(x1,y1,x2,y2):
    return ((x1-x2)**2 + (y1-y2)**2)**0.5

def colliding_circles(circles):
    for index1, circle1 in enumerate(circles):
        for circle2 in circles[index1+1:]:
            x1, y1, Radius1 = circle1[0]
            x2, y2, Radius2 = circle2[0]
            #collision or containment:
            if inter_centre_distance(x1,y1,x2,y2) < Radius1 + Radius2:
                return True

def find_circles(processed, storage, LOW):
    try:
        cv.HoughCircles(processed, storage, cv.CV_HOUGH_GRADIENT, 2, 32.0, 30, LOW)#, 0, 100) great to add circle constraint sizes.
    except:
        LOW += 1
        print 'try'
        find_circles(processed, storage, LOW)
    circles = np.asarray(storage)
    print 'number of circles:', len(circles)
    if colliding_circles(circles):
        LOW += 1
        storage = find_circles(processed, storage, LOW)
    print 'c', LOW
    return storage

def draw_circles(storage, output):
    circles = np.asarray(storage)
    print len(circles), 'circles found'
    for circle in circles:
        Radius, x, y = int(circle[0][2]), int(circle[0][0]), int(circle[0][1])
        cv.Circle(output, (x, y), 1, cv.CV_RGB(0, 255, 0), -1, 8, 0)
        cv.Circle(output, (x, y), Radius, cv.CV_RGB(255, 0, 0), 3, 8, 0)

#split image into RGB components
cv.Split(orig,rrr,ggg,bbb,None)
#process each component
channel_processing(rrr)
channel_processing(ggg)
channel_processing(bbb)
#combine images using logical 'And' to avoid saturation
cv.And(rrr, ggg, rrr)
cv.And(rrr, bbb, processed)
cv.ShowImage('before canny', processed)
# cv.SaveImage('case3_processed.jpg',processed)
#use canny, as HoughCircles seems to prefer ring like circles to filled ones.
cv.Canny(processed, processed, 5, 70, 3)
#smooth to reduce noise a bit more
cv.Smooth(processed, processed, cv.CV_GAUSSIAN, 7, 7)
cv.ShowImage('processed', processed)
#find circles, with parameter search
storage = find_circles(processed, storage, 100)
draw_circles(storage, output)
# show images
cv.ShowImage("original with circles", output)
cv.SaveImage('case1.jpg',output)

cv.WaitKey(0)

아, 예 ... 원의 색 / 크기 불변 변수 문제 (일명 Hough 변환은 너무 구체적이고 강력하지 않습니다) ...

과거에는 OpenCV의 구조 및 모양 분석 기능에 훨씬 더 많이 의존했습니다. 가능한 "샘플"폴더에서 아주 좋은 아이디어를 얻을 수 있습니다 - 특히 fitellipse.pysquares.py .

당신의 설명을 위해서, 나는이 예제의 하이브리드 버전을 제시하고 원래 소스를 기반으로합니다. 감지 된 윤곽선은 초록색이고 맞춰진 타원은 빨간색으로 표시됩니다.

그것은 아직 거기에 :

  • 전처리 단계에서는 더 희미한 원을 감지하기 위해 미세 조정이 필요합니다.
  • 윤곽을 테스트하여 원인지 아닌지를 결정할 수 있습니다.

행운을 빕니다!

import cv
import numpy as np

# grab image
orig = cv.LoadImage('circles3.jpg')

# create tmp images
grey_scale = cv.CreateImage(cv.GetSize(orig), 8, 1)
processed = cv.CreateImage(cv.GetSize(orig), 8, 1)

cv.Smooth(orig, orig, cv.CV_GAUSSIAN, 3, 3)

cv.CvtColor(orig, grey_scale, cv.CV_RGB2GRAY)

# do some processing on the grey scale image
cv.Erode(grey_scale, processed, None, 10)
cv.Dilate(processed, processed, None, 10)
cv.Canny(processed, processed, 5, 70, 3)
cv.Smooth(processed, processed, cv.CV_GAUSSIAN, 15, 15)

#storage = cv.CreateMat(orig.width, 1, cv.CV_32FC3)
storage = cv.CreateMemStorage(0)

contours = cv.FindContours(processed, storage, cv.CV_RETR_EXTERNAL)
# N.B. 'processed' image is modified by this!

#contours = cv.ApproxPoly (contours, storage, cv.CV_POLY_APPROX_DP, 3, 1) 
# If you wanted to reduce the number of points...

cv.DrawContours (orig, contours, cv.RGB(0,255,0), cv.RGB(255,0,0), 2, 3, cv.CV_AA, (0, 0)) 

def contour_iterator(contour):
  while contour:
    yield contour
    contour = contour.h_next()

for c in contour_iterator(contours):
  # Number of points must be more than or equal to 6 for cv.FitEllipse2
  if len(c) >= 6:
    # Copy the contour into an array of (x,y)s
    PointArray2D32f = cv.CreateMat(1, len(c), cv.CV_32FC2)

    for (i, (x, y)) in enumerate(c):
      PointArray2D32f[0, i] = (x, y)

    # Fits ellipse to current contour.
    (center, size, angle) = cv.FitEllipse2(PointArray2D32f)

    # Convert ellipse data from float to integer representation.
    center = (cv.Round(center[0]), cv.Round(center[1]))
    size = (cv.Round(size[0] * 0.5), cv.Round(size[1] * 0.5))

    # Draw ellipse
    cv.Ellipse(orig, center, size, angle, 0, 360, cv.RGB(255,0,0), 2,cv.CV_AA, 0)

# show images
cv.ShowImage("image - press 'q' to quit", orig)
#cv.ShowImage("post-process", processed)
cv.WaitKey(-1)

편집하다:

이 모든 대답에 대한 주요 주제가 있다고 생각하는 업데이트는 원형 으로 인식하려는 것에 적용 할 수있는 많은 가정과 제약 조건이 있다는 것입니다. 내 자신의 대답은 낮은 수준의 전처리 또는 높은 수준의 기하학적 인 피팅에서도 마찬가지입니다. 많은 서클이 그려지는 방식이나 이미지의 비 아핀 / 사영 변환, 렌더링 / 캡처 방식 (색상, 노이즈, 조명, 기타 등등)에있어 다른 속성과 함께 실제로 많은 원이 둥근 것이 아니며, 가장자리 두께) - 하나의 이미지 내에서 가능한 모든 후보 동그라미 수입니다.

훨씬 더 정교한 기술이 있습니다. 그러나 그들은 당신에게 돈을 줄 것입니다. 개인적으로 나는 가용 임계 값을 사용하는 @fraxel 아이디어를 좋아합니다. 그것은 빠르고 안정적이며 합리적입니다. 그런 다음 타원 축의 간단한 비율 테스트 (예 : if ((min (size) / max (size))> 0.7)를 사용하여 최종 윤곽 (예 : Hu 순간 사용) 또는 피팅을 추가로 테스트 할 수 있습니다.

컴퓨터 비젼과 마찬가지로 실용주의, 원칙, 파소 모스 사이에는 긴장이 있습니다. 내가 이력서가 쉽다고 생각하는 사람들에게 말하기를 좋아하기 때문에 실제로는 그렇지 않습니다. 그것은 사실 AI의 완전한 문제입니다. 이 밖에서 자주 할 수있는 최선은 대부분의 경우에 효과가있는 것입니다.


코드를 살펴보면 다음과 같은 사실을 알게되었습니다.

  • 그레이 스케일 변환. 나는 당신이 그것을하고있는 이유를 이해하지만, 당신이 정보를 버리고 있다는 것을 깨닫습니다. "후 처리 (post-process)"이미지에서 볼 수 있듯이 노란색 원은 배경과 같은 강도로 다른 색상으로 나타납니다.

  • 노이즈 제거 후의 에지 검출 (erae / dilate). 이것은 필요하지 않아야합니다. 대니가이 일을 처리해야합니다.

  • 캐니 에지 감지. 너의 "열린"원에는 2 개의 가장자리, 안 가장자리 및 바깥 가장자리가있다. 그들은 꽤 가깝기 때문에, Canny gauss 필터가 그들을 더할 수도 있습니다. 그렇지 않으면 두 가장자리가 서로 가깝게됩니다. 예전에 Canny 앞에, 당신은 열리고 채워진 원이 있습니다. 그 후에는 각각 0/2 및 1 가장자리가 있습니다. Hough가 Canny를 다시 호출 한 이후 첫 번째 경우 두 가장자리가 함께 매끄럽게 될 수 있습니다 (초기 너비에 따라 다름). 따라서 코어 허프 알고리즘이 열과 채워진 원을 동일하게 처리 할 수 ​​있습니다.

그래서, 저의 첫 번째 권고는 그레이 스케일 매핑을 변경하는 것입니다. 강도는 사용하지 말고 색조 / 채도 / 값을 사용하십시오. 또한 차별화 된 접근 방식을 사용하십시오. 즉, 가장자리를 찾고 있습니다. 따라서 HSV 변환을 계산하고 복사본을 매끄럽게 한 다음 원래 복사본과 매끄러운 복사본의 차이를 가져옵니다. 그러면 각 점에 대해 dH, dS, dV 값 (색조, 채도, 값의 로컬 변형)이 표시됩니다. Square와 add를 사용하여 1 차원 이미지를 얻고 모든 가장자리 (내부 및 외부) 근처의 피크를 얻습니다.

내 두 번째 권장 사항은 로컬 정규화가 될 것이지만 필요한 경우 확실하지 않습니다. 아이디어는 당신이 꺼내는 엣지 신호의 정확한 값에 대해별로 신경 쓰지 않는다는 것입니다. 어쨌든 (바이너리이거나 엣지가 아닌) 바이너리이어야합니다. 따라서 각 값을 지역 평균으로 나누어 각 값을 정규화 할 수 있습니다 (로컬 크기는 가장자리 크기의 크기 순서 임).


좋아, 이미지를보고. **Active Contours** 사용을 권장합니다.

  • 활성 윤곽 활성 윤곽에 대한 좋은 점은 어떤 주어진 모양에도 거의 완벽하게 들어 맞습니다. 정사각형이나 삼각형이어야하며 귀하의 경우에는 완벽한 후보자가되어야합니다.
  • 원의 중심을 추출 할 수 있다면 좋습니다. 활성 윤곽선은 항상 시작점을 지정해야합니다. 시작점부터 시작하여 점차 커지거나 축소 될 수 있습니다. 센터가 항상 센터에 정렬 될 필요는 없습니다. 약간의 오프셋은 여전히 ​​괜찮을 것입니다.
  • 그리고 당신의 경우에 윤곽선이 중심에서 바깥쪽으로 자라게한다면, 그들은 원의 경계를 쉬게됩니다.
  • 확대 또는 축소되는 활성 윤곽선은 풍선 에너지 를 사용하므로 윤곽선, 안쪽 또는 바깥 쪽 방향을 설정할 수 있습니다.
  • 아마도 그레이 스케일로 그래디언트 이미지를 사용해야 할 것입니다. 그러나 여전히 색상으로 시도 할 수 있습니다. 작동한다면!
  • 그리고 센터를 제공하지 않으면 많은 액티브 컨투어를 버리고 성장시키고 축소하십시오. 안정된 컨투어는 유지되고, 불안정한 컨투어는 버려집니다. 이것은 무차별 적 접근입니다. CPU 사용률이 높을 것입니다. 그러나 올바른 윤곽선을 남기고 나쁜 윤곽선을 버리기 위해보다 신중한 작업이 필요합니다.

나는 당신이 문제를 해결할 수 있기를 희망합니다.





computer-vision