2013-02-16 3 views
0

원본 이미지의 템플릿을 식별하고 해당 템플릿과 일치하는 영역을 복사하여 이미지를 opencv로 여러 하위 이미지로 분할하려고합니다. 나는 opencv의 새로운 초보자입니다! 나는 사용하여 서브 이미지를 확인했습니다opencv 및 python에서 이미지의 일부를 복사하십시오.

result = cv2.matchTemplate(img, template, cv2.TM_CCORR_NORMED) 

몇 가지 정리 후 나는 튜플의 목록 내가 사각형을 보여 반복하는 점이라고 얻는다. tw와 th는 각각 템플리트의 폭과 높이입니다. 무엇을 달성 할 싶습니다

for pt in points: 
    re = cv2.rectangle(img, pt, (pt[0] + tw, pt[1] + th), 0, 2) 
    print('%s, %s' % (str(pt[0]), str(pt[1]))) 
    count+=1 

분리 파일로 팔각형 (https://dl.dropbox.com/u/239592/region01.png)를 저장하는 것입니다.

어떻게하면됩니까? 윤곽선에 대해 읽은 적이 있지만 사용 방법을 잘 모르겠습니다. 이상적으로 팔각형을 등고선화하고 싶습니다.

도움을 주셔서 감사합니다.

답변

4

템플릿 일치가 제대로 작동하는 경우 계속 사용하세요.

enter image description here

그런 다음, 우리가 진 하나하고 작은 부품을 폐기하기 위해 입력을 사전 처리 할 수 ​​있습니다 : 예를 들어, 나는 다음과 같은 템플릿을 고려했다. 이 단계 후에 템플릿 일치가 수행됩니다. 그렇다면 가까운 것들을 버리는 방법으로 경기를 필터링하는 문제입니다. (나는 더미 방법을 사용했습니다. 너무 많은 경기가 있다면 시간이 좀 걸릴 것입니다.)어느 점이 떨어져 있는지를 결정한 후 (따라서 다른 육각형을 식별하는 경우), 다음과 같은 방법으로 조금씩 조정할 수 있습니다.

  • y 좌표로 정렬;
  • 인접한 두 항목이 너무 가까운 y 좌표에서 시작하면 둘 다 같은 y 좌표로 설정하십시오.

이제 작곡이 래스터 순서로 완료되도록 적절한 순서로이 포인트 목록을 정렬 할 수 있습니다. 자르기 부분은 numpy에 의해 제공되는 슬라이싱을 사용하여 쉽게 달성됩니다.

import sys 
import cv2 
import numpy 

outbasename = 'hexagon_%02d.png' 

img = cv2.imread(sys.argv[1]) 
template = cv2.cvtColor(cv2.imread(sys.argv[2]), cv2.COLOR_BGR2GRAY) 
theight, twidth = template.shape[:2] 

# Binarize the input based on the saturation and value. 
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) 
saturation = hsv[:,:,1] 
value = hsv[:,:,2] 
value[saturation > 35] = 255 
value = cv2.threshold(value, 0, 255, cv2.THRESH_OTSU)[1] 
# Pad the image. 
value = cv2.copyMakeBorder(255 - value, 3, 3, 3, 3, cv2.BORDER_CONSTANT, value=0) 

# Discard small components. 
img_clean = numpy.zeros(value.shape, dtype=numpy.uint8) 
contours, _ = cv2.findContours(value, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) 
for i, c in enumerate(contours): 
    area = cv2.contourArea(c) 
    if area > 500: 
     cv2.drawContours(img_clean, contours, i, 255, 2) 


def closest_pt(a, pt): 
    if not len(a): 
     return (float('inf'), float('inf')) 
    d = a - pt 
    return a[numpy.argmin((d * d).sum(1))] 

match = cv2.matchTemplate(img_clean, template, cv2.TM_CCORR_NORMED) 

# Filter matches. 
threshold = 0.8 
dist_threshold = twidth/1.5 
loc = numpy.where(match > threshold) 
ptlist = numpy.zeros((len(loc[0]), 2), dtype=int) 
count = 0 
print "%d matches" % len(loc[0]) 
for pt in zip(*loc[::-1]): 
    cpt = closest_pt(ptlist[:count], pt) 
    dist = ((cpt[0] - pt[0]) ** 2 + (cpt[1] - pt[1]) ** 2) ** 0.5 
    if dist > dist_threshold: 
     ptlist[count] = pt 
     count += 1 

# Adjust points (could do for the x coords too). 
ptlist = ptlist[:count] 
view = ptlist.ravel().view([('x', int), ('y', int)]) 
view.sort(order=['y', 'x']) 
for i in xrange(1, ptlist.shape[0]): 
    prev, curr = ptlist[i - 1], ptlist[i] 
    if abs(curr[1] - prev[1]) < 5: 
     y = min(curr[1], prev[1]) 
     curr[1], prev[1] = y, y 

# Crop in raster order. 
view.sort(order=['y', 'x']) 
for i, pt in enumerate(ptlist, start=1): 
    cv2.imwrite(outbasename % i, 
      img[pt[1]-2:pt[1]+theight-2, pt[0]-2:pt[0]+twidth-2]) 
    print 'Wrote %s' % (outbasename % i) 

당신은 육각형의 윤곽을 원한다면, img_clean 대신 img에 자르 (그러나 다음 래스터 순서로 육각형을 정렬하는 데 의미가있다).

enter image description hereenter image description here

+0

답변 해 주셔서 감사합니다. 다음과 같은 오류가 발생했습니다 : _l [i] = cv2.threshold (cv2.cvtColor (l [i], cv2.COLOR_BGR2GRAY), 오류 :/home/abuild/rpmbuild/BUILD/OpenCV -2.4.1/modules/imgproc/src/color.cpp : 3205 : 오류 : (-215) scn == 3 || scn == 4 함수 cvtColor에서. 솔직히 고칠 방법에 대한 단서가 없습니다. ... 문제의 원인에 대해 알고 계신가요? –

+0

@AlbertVonpupp 템플릿 또는 입력에 이미 하나의 채널이 있기 때문에 발생합니다. 템플릿의 이미지에 단일 채널이 있고 이미 이진 파일 인 경우 추가 할 수 있습니다. '_, l [i] = cv2.threshold (...)'바로 다음에'break' 문을 쓰면 입력 만 처리하게됩니다. – mmgp

+0

바보 같은 실수 였는데, 잘못된 파일 이름을 사용하고있었습니다. 첫 번째 루프 이후에 50 번째 줄에 중단 점을 지정하여 실행했습니다. 그 ptlist 뭔가가 있어야하지만 비어 있습니다. 임계 값을 0.95로 설정하면 팔각형의 두 번째 열에 대해서만 작동하는 것 같습니다. 이 이미지를 https://github.com/vonpupp/opencv-learning/blob/master/test01.jpeg와 함께 실행하면 threshold = 0.99로 출력이 생성되지 않고 threshold = 0.95로 정지 한 것처럼 보입니다. . 나중에 코드를 git repo에 업로드하고 링크를 게시합니다. –

1

미안하지만 matchTemplate 및 Contours와 어떻게 관련이 있는지 궁금한 점이 많습니다.

어쨌든, 다음은 윤곽선을 사용하는 작은 기술입니다. 귀하의 다른 이미지도 귀하가 제공 한 이미지와 같다고 가정합니다. 다른 이미지와 잘 작동하는지 확신 할 수 없습니다. 그러나 그것이 시작을 얻는 것을 도울 것이라고 생각합니다. 이것을 직접 시도하고 필요한 조정과 수정을하십시오.

내가 무슨 짓을 :

1 - 나는 팔각형의 가장자리를 필요로했다. 따라서 Thresholded Image는 오츠 (Otsu)를 사용하고 팽창과 부식을 적용합니다 (또는 모든 이미지에서 잘 작동하는 방법을 사용하십시오, beware of the edges in left edge of image). 들어 -, 볼록 선체를 찾아 그 영역 (A) & 경계선 (P)

4 찾을 각 윤곽 용 - http://goo.gl/r0ID0

3 -

2 나서 윤곽에 대해 자세히 등고선 (발견 완벽한 팔각형, P*P/A = 13.25 approximately 내가 여기에 그것을 사용하고 그것을 잘라 그것을 저장

5 -.... 당신은 또한 팔각형의 일부 가장자리를 제거 자르기 참조 당신이 그것을 원한다면, 자르기 크기를 조정할 수 있습니다

코드 :

import cv2 
import numpy as np 

img = cv2.imread('region01.png') 
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 
ret,thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) 
thresh = cv2.dilate(thresh,None,iterations = 2) 
thresh = cv2.erode(thresh,None) 

contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) 
number = 0 

for cnt in contours: 
    hull = cv2.convexHull(cnt) 
    area = cv2.contourArea(hull) 
    P = cv2.arcLength(hull,True) 

    if ((area != 0) and (13<= P**2/area <= 14)): 
     #cv2.drawContours(img,[hull],0,255,3) 
     x,y,w,h = cv2.boundingRect(hull) 
     number = number + 1 
     roi = img[y:y+h,x:x+w] 
     cv2.imshow(str(number),roi) 
     cv2.imwrite("1"+str(number)+".jpg",roi) 

cv2.imshow('img',img) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 

그 6 각형

는 별도의 파일로 저장됩니다.

희망이 있습니다. !!!

+0

주셔서 감사합니다 신속한 답변 아비드에 대한 많은 : 여기

위의 코드를 수정하지 않고 두 개의 예제를 잘라 것 다른 지역의 표현이다. 템플릿 https://github.com/vonpupp/opencv-learning/blob/master/multimatch02.py와 일치시키기 위해이 코드를 사용했습니다. 귀하의 코드는 대단하며 많은 도움이 될 것입니다. 당신이 볼 수 있듯이 윤곽선은 (피 하여야만하는) 맨 아래 정보의 일부와도 일치하므로 팔각형에 일치시키기 위해 matchtemplate 접근법을 사용했습니다. 나는 끝에 35 개의 이미지 (8 각진에서 오는 것)를 얻을 필요가 있습니다. 큰 도움을 주셔서 다시 한 번 감사드립니다. matchTemplate 내에서 윤곽선을 사용하여 코드를 조정하려고합니다. –

+0

나는 팔각형이 규칙적인 방법 (위에서 아래로, 왼쪽에서 오른쪽으로)을 얻는 것도 잊는다. 가장 빠를 이미지를 빠르고 더러운 방식으로 필터링 할 수 있습니다. 코드 : https://github.com/vonpupp/opencv-learning/blob/master/contour01.py –

+0

cv2.moments()를 사용하여이 팔각형의 중심을 찾을 수 있습니다. 그런 다음 해당 윤곽선을 해당 (x, y) 좌표에 따라 정렬합니다. 당신이 그걸 할 수 있기를 바랍니다. 순간을 찾으려면이 기사를 읽어보세요. http://goo.gl/tvy9r –

관련 문제