2016-08-11 1 views
5

현재이 이미지와 같은 원 감지를하고 있지만 일부 얼룩이 병합되어 불규칙한 모양 (원본 이미지의 빨간색 표시)을 형성합니다. opencv에서 원을 감지하기 위해 houghcircle 함수를 사용하고 있습니다. 이러한 불규칙한 모양의 경우 함수는 여러 개의 작은 원으로 만 감지 할 수 있지만 프로그램에서 불규칙한 모양을 전체 큰 모양으로 간주하여 출력 이미지에서 그리는 것처럼 큰 원을 얻길 원합니다. houghcircle 함수를 사용하여 불규칙한 모양을 감지했습니다. opencv python

Original image

Output image

내 코드는 모든 원을 감지하고 그 직경을 얻을 것이다. 여전히 HoughCircles 기능을 사용하려면, 당신은 단지 두 개의 원이 겹쳐 있는지 확인하고 밖으로 새로운 원을 만들 수

def circles(filename, p1, p2, minR, maxR): 
# print(filename) 
img = cv2.imread(filename, 0) 
img = img[0:1000, 0:1360] 
l = len(img) 
w = len(img[1]) 

cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR) 

circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 25, 
          param1 = int(p1) ,param2 = int(p2), minRadius = int(minR), maxRadius = int(maxR)) 

diameter = open(filename[:-4] + "_diamater.txt", "w") 
diameter.write("Diameters(um)\n") 
for i in circles[0,:]: 
    diameter.write(str(i[2] * 1.29 * 2) + "\n") 

count = 0 
d = [] 
area = [] 
for i in circles[0,:]: 
    cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2) 
    cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3) 
    count += 1 
    d += [i[2]*2] 
    area += [i[2]*i[2]*pi*1.286*1.286] 

f = filename.split("/")[-1] 
cv2.imwrite(filename[:-4] + "_circle.jpg", cimg) 

# cv2.imwrite("test3/edge.jpg", edges) 
print "Number of Circles is %d" % count 

diaM = [] 
for i in d: 
    diaM += [i*1.286] 

bWidth = range(int(min(diaM)) - 10, int(max(diaM)) + 10, 2) 

txt = ''' 
Sample name: %s 
Average diameter(um): %f  std: %f 
Drop counts: %d 
Average coverage per drop(um^2): %f  std: %f 
''' % (f, np.mean(diaM), np.std(diaM), count, np.mean(area), np.std(area)) 

fig = plt.figure() 
fig.suptitle('Histogram of Diameters', fontsize=14, fontweight='bold') 
ax1 = fig.add_axes((.1,.4,.8,.5)) 
ax1.hist(diaM, bins = bWidth) 
ax1.set_xlabel('Diameter(um)') 
ax1.set_ylabel('Frequency') 
fig.text(.1,.1,txt) 
plt.savefig(filename[:-4] + '_histogram.jpg') 
plt.clf() 

print "Total area is %d" % (w*l) 
print "Total covered area is %d" % (np.sum(area)) 

rt = "Number of Circles is " + str(count) + "\n" + "Coverage percent is " + str(np.divide(np.sum(area), (w*l))) + "\n" 
return rt 

답변

1

:

여기 내 코드입니다.

+0

직경에 의해

  • 적자
  • 확장 모튼의 확산,하지만이 서로 바로 옆에 많은 다른 서클들이 있습니다. 그래서 그것은 잘 작동하지 않습니다. 어쨌든 고마워. –

  • 1

    이 경우 minEnclosingCircle을 사용할 수 있습니다. 이미지의 윤곽선을 찾은 다음이 기능을 적용하여 모양을 원으로 감지합니다.

    다음은 C++ 코드의 간단한 예입니다. 당신의 경우에는, 이미지의 일부 원이 서로 매우 가깝기 때문에 Hough-circle과 minEnclosingCircle의 조합을 사용해야한다고 생각합니다. 단일 윤곽으로 감지 될 수 있습니다.

    입력 이미지 :

    input

    원 : 당신은 아름다운 잘 분리 대조 패턴이있을 때

    output

    Mat im = imread("circ.jpg"); 
    Mat gr; 
    cvtColor(im, gr, CV_BGR2GRAY); 
    Mat bw; 
    threshold(gr, bw, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU); 
    
    vector<vector<Point>> contours; 
    vector<Vec4i> hierarchy; 
    findContours(bw, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); 
    for(int idx = 0; idx >= 0; idx = hierarchy[idx][0]) 
    { 
        Point2f center; 
        float radius; 
        minEnclosingCircle(contours[idx], center, radius); 
    
        circle(im, Point(center.x, center.y), radius, Scalar(0, 255, 255), 2); 
    } 
    
    0

    , 가장 쉬운 방법은 모양 인덱스를 사용하는 것 . this paper 또는 this poster을 참조하십시오. 두 경우 모두 쉐이프 색인 목록이 있습니다.

    덕분에 인덱스를 형성하기 위해, 당신은 무엇을 따를 수 :

    • 바이너리 이미지
    • 각 패턴을
    • 컴퓨팅 모양 인덱스를 분리하기 위해 (그들 중 대부분은 기본적인 조치를 사용)
    • 에서
    • 연결 구성 요소 라벨링
    • 은 모양 색인 값에 따라 패턴을 분류합니다. 둥근 모양이 완벽하게 둥근 특정 경우와 마찬가지로

    , 나는 다음과 같은 모양 인덱스를 사용합니다 :

    • 원형도를 => 단지 반경, 그래서 가장 쉬운 계산하고 귀하의 경우 완벽하게 사용.
    • 반지름으로 연장/연신/신축 => 귀하의 경우에는 완벽하지만 모든 라이브러리에서 미니 공 계산을 사용할 수있는 것은 아닙니다.
    • Iso-perimetric deficit => 실제로 계산하기는 쉽지만 둘레 때문에 원형보다 약간 안정적입니다.

    또한 귀하의 경우 일 :

    • 간격 새겨 디스크
    • 내가 그 방법을 시도
    관련 문제