2012-06-20 2 views
8

python으로 opencv를 사용하려고합니다. opencv 2.4의 C++ 버전에서 설명 자 (SIFT, SURF 또는 ORB)와 일치하는 코드를 작성했습니다. 이 코드를 python으로 opencv로 변환하고 싶습니다. C++에서 opencv 함수를 사용하는 방법에 대한 문서를 찾았지만 많은 pycript의 opencv 함수를 사용하는 방법을 찾을 수 없었습니다. 여기 내 파이썬 코드입니다, 그리고 내 현재 문제는 "drawMatches"opencv C++ 파이썬에서 사용하는 방법을 모른다. cv2.DRAW_MATCHES_FLAGS_DEFAULT를 찾았지만 사용 방법을 모릅니다. 여기에 일치하여 ORB 기술자의 내 파이썬 코드 : 라인 "img_matches = cv2.DRAW_MATCHES_FLAGS_DEFAULT (IM2, keypoints2, IM4, keypoints4, raw_matches)"의python에서 opencv 모듈을 사용하여 설명자 일치를 시각화하는 방법

im1 = cv2.imread(r'C:\boldt.jpg') 
im2 = cv2.cvtColor(im1, cv2.COLOR_BGR2GRAY) 
im3 = cv2.imread(r'C:\boldt_resize50.jpg') 
im4 = cv2.cvtColor(im3, cv2.COLOR_BGR2GRAY) 

orbDetector2 = cv2.FeatureDetector_create("ORB") 
orbDescriptorExtractor2 = cv2.DescriptorExtractor_create("ORB") 
orbDetector4 = cv2.FeatureDetector_create("ORB") 
orbDescriptorExtractor4 = cv2.DescriptorExtractor_create("ORB") 

keypoints2 = orbDetector2.detect(im2) 
(keypoints2, descriptors2) = orbDescriptorExtractor2.compute(im2,keypoints2) 
keypoints4 = orbDetector4.detect(im4) 
(keypoints4, descriptors4) = orbDescriptorExtractor4.compute(im4,keypoints4) 
matcher = cv2.DescriptorMatcher_create('BruteForce-Hamming') 
raw_matches = matcher.match(descriptors2, descriptors4) 
img_matches = cv2.DRAW_MATCHES_FLAGS_DEFAULT(im2, keypoints2, im4, keypoints4, raw_matches) 
cv2.namedWindow("Match") 
cv2.imshow("Match", img_matches); 

오류 메시지가

Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
TypeError: 'long' object is not callable 

나는 보냈다 많은 시간 검색 문서와 파이썬에서 opencv 함수를 사용하는 예제. 그러나 python에서 opencv 함수를 사용하는 정보가 거의 없기 때문에 매우 좌절했습니다. 파이썬에서 opencv 모듈의 모든 기능을 사용하는 방법에 대한 문서를 어디서 찾을 수 있는지 가르쳐 주시면 매우 도움이 될 것입니다. 시간과 도움에 감사드립니다.

답변

2

오류 메시지에 나와 있듯이 DRAW_MATCHES_FLAGS_DEFAULT의 유형은 'long'입니다. 함수가 아닌 cv2 모듈에 의해 정의 된 상수입니다. 불행하게도, 당신이 원하는 함수 인 'drawMatches'는 OpenCV의 C++ 인터페이스에만 존재합니다.

+0

감사합니다! – user1433201

14

다음과 같이 Python에서 일치하는 기능을 시각화 할 수 있습니다. scipy 라이브러리 사용에 유의하십시오. 나는 또한 단지 OpenCV의 파이썬 인터페이스를 사용하고 내가 scipy를 사용하지 않았다 뭔가 나 자신을 서면으로 작성했습니다

# matching features of two images 
import cv2 
import sys 
import scipy as sp 

if len(sys.argv) < 3: 
    print 'usage: %s img1 img2' % sys.argv[0] 
    sys.exit(1) 

img1_path = sys.argv[1] 
img2_path = sys.argv[2] 

img1 = cv2.imread(img1_path, cv2.CV_LOAD_IMAGE_GRAYSCALE) 
img2 = cv2.imread(img2_path, cv2.CV_LOAD_IMAGE_GRAYSCALE) 

detector = cv2.FeatureDetector_create("SURF") 
descriptor = cv2.DescriptorExtractor_create("BRIEF") 
matcher = cv2.DescriptorMatcher_create("BruteForce-Hamming") 

# detect keypoints 
kp1 = detector.detect(img1) 
kp2 = detector.detect(img2) 

print '#keypoints in image1: %d, image2: %d' % (len(kp1), len(kp2)) 

# descriptors 
k1, d1 = descriptor.compute(img1, kp1) 
k2, d2 = descriptor.compute(img2, kp2) 

print '#keypoints in image1: %d, image2: %d' % (len(d1), len(d2)) 

# match the keypoints 
matches = matcher.match(d1, d2) 

# visualize the matches 
print '#matches:', len(matches) 
dist = [m.distance for m in matches] 

print 'distance: min: %.3f' % min(dist) 
print 'distance: mean: %.3f' % (sum(dist)/len(dist)) 
print 'distance: max: %.3f' % max(dist) 

# threshold: half the mean 
thres_dist = (sum(dist)/len(dist)) * 0.5 

# keep only the reasonable matches 
sel_matches = [m for m in matches if m.distance < thres_dist] 

print '#selected matches:', len(sel_matches) 

# ##################################### 
# visualization of the matches 
h1, w1 = img1.shape[:2] 
h2, w2 = img2.shape[:2] 
view = sp.zeros((max(h1, h2), w1 + w2, 3), sp.uint8) 
view[:h1, :w1, :] = img1 
view[:h2, w1:, :] = img2 
view[:, :, 1] = view[:, :, 0] 
view[:, :, 2] = view[:, :, 0] 

for m in sel_matches: 
    # draw the keypoints 
    # print m.queryIdx, m.trainIdx, m.distance 
    color = tuple([sp.random.randint(0, 255) for _ in xrange(3)]) 
    cv2.line(view, (int(k1[m.queryIdx].pt[0]), int(k1[m.queryIdx].pt[1])) , (int(k2[m.trainIdx].pt[0] + w1), int(k2[m.trainIdx].pt[1])), color) 


cv2.imshow("view", view) 
cv2.waitKey() 
+0

코드를 실행할 때 66 행에 오류가 발생합니다.'''TypeError : integer argument expected, got float''' – gilbertbw

+0

@ wall-e 익명 사용자가 귀하의 게시물을 편집 한 직후에 그것을 깨뜨리지 않았 으면 좋겠습니까? – OGHaza

+0

보기 [: h1, : w1, :] = img1 ValueError : 입력 배열을 모양 (322,518)에서 브로드 캐스팅 할 수 없습니다. (322,518,3) – Giuseppe

9

. drawMatches은 OpenCV 3.0.0의 일부이며 현재 OpenCV 2에 포함되어 있지 않습니다. 비록 내가 파티에 늦었을지라도, 나의 능력을 최대한 발휘하여 drawMatches을 모방 한 나의 구현이있다.

하나는 카메라 맨이고 다른 하나는 같은 이미지이지만 반 시계 방향으로 55도 회전 한 내 이미지를 제공했습니다.

내가 작성한 내용의 기본 전제는 출력 RGB 이미지를 할당한다는 것입니다. 행의 양이 출력 이미지에 이미지 두 개를 배치 할 수 있도록 수용 할 수있는 두 이미지의 최대 값이고 열은 단순히 합계입니다 두 열을 함께. 각 이미지를 해당 지점에 배치 한 다음 일치하는 모든 키포인트의 루프를 실행합니다. 두 이미지간에 일치하는 키포인트를 추출한 다음 (x,y) 좌표를 추출합니다. 그런 다음 각 감지 된 위치에 원을 그린 다음이 원을 연결하는 선을 그립니다.

두 번째 이미지에서 검출 된 키포인트는 자체 좌표계와 관련된다는 점에 유의하십시오. 이를 최종 출력 이미지에 배치하려면, 열 좌표가 출력 이미지의 좌표 시스템과 관련되도록 열 좌표를 첫 번째 이미지의 열 수만큼 오프셋해야합니다 .내가 OpenCV의의의를 사용

enter image description here

enter image description here

:

import numpy as np 
import cv2 

def drawMatches(img1, kp1, img2, kp2, matches): 
    """ 
    My own implementation of cv2.drawMatches as OpenCV 2.4.9 
    does not have this function available but it's supported in 
    OpenCV 3.0.0 

    This function takes in two images with their associated 
    keypoints, as well as a list of DMatch data structure (matches) 
    that contains which keypoints matched in which images. 

    An image will be produced where a montage is shown with 
    the first image followed by the second image beside it. 

    Keypoints are delineated with circles, while lines are connected 
    between matching keypoints. 

    img1,img2 - Grayscale images 
    kp1,kp2 - Detected list of keypoints through any of the OpenCV keypoint 
       detection algorithms 
    matches - A list of matches of corresponding keypoints through any 
       OpenCV keypoint matching algorithm 
    """ 

    # Create a new output image that concatenates the two images together 
    # (a.k.a) a montage 
    rows1 = img1.shape[0] 
    cols1 = img1.shape[1] 
    rows2 = img2.shape[0] 
    cols2 = img2.shape[1] 

    out = np.zeros((max([rows1,rows2]),cols1+cols2,3), dtype='uint8') 

    # Place the first image to the left 
    out[:rows1,:cols1,:] = np.dstack([img1, img1, img1]) 

    # Place the next image to the right of it 
    out[:rows2,cols1:cols1+cols2,:] = np.dstack([img2, img2, img2]) 

    # For each pair of points we have between both images 
    # draw circles, then connect a line between them 
    for mat in matches: 

     # Get the matching keypoints for each of the images 
     img1_idx = mat.queryIdx 
     img2_idx = mat.trainIdx 

     # x - columns 
     # y - rows 
     (x1,y1) = kp1[img1_idx].pt 
     (x2,y2) = kp2[img2_idx].pt 

     # Draw a small circle at both co-ordinates 
     # radius 4 
     # colour blue 
     # thickness = 1 
     cv2.circle(out, (int(x1),int(y1)), 4, (255, 0, 0), 1) 
     cv2.circle(out, (int(x2)+cols1,int(y2)), 4, (255, 0, 0), 1) 

     # Draw a line in between the two points 
     # thickness = 1 
     # colour blue 
     cv2.line(out, (int(x1),int(y1)), (int(x2)+cols1,int(y2)), (255, 0, 0), 1) 


    # Show the image 
    cv2.imshow('Matched Features', out) 
    cv2.waitKey(0) 
    cv2.destroyAllWindows() 

이 여기 내가 사용하는 두 개의 이미지가, 작동하는지 설명하기 : 속히

ORB 탐지기가 키포인트를 탐지하고, 이것이 바이너리 서술자이기 때문에 유사화를위한 거리 척도로서 정규화 된 해밍 거리를 사용했다. 예를 들면 :

import numpy as np 
import cv2 

img1 = cv2.imread('cameraman.png') # Original image 
img2 = cv2.imread('cameraman_rot55.png') # Rotated image 

# Create ORB detector with 1000 keypoints with a scaling pyramid factor 
# of 1.2 
orb = cv2.ORB(1000, 1.2) 

# Detect keypoints of original image 
(kp1,des1) = orb.detectAndCompute(img1, None) 

# Detect keypoints of rotated image 
(kp2,des2) = orb.detectAndCompute(img2, None) 

# Create matcher 
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) 

# Do matching 
matches = bf.match(des1,des2) 

# Sort the matches based on distance. Least distance 
# is better 
matches = sorted(matches, key=lambda val: val.distance) 

# Show only the top 10 matches 
drawMatches(img1, kp1, img2, kp2, matches[:10]) 

이것은 내가 얻을 이미지 : 답장을 보내

enter image description here

+0

Hii @rayryeng 위의 코드를 실행하려고 할 때, 나는 얻는다. Traceback (최근 호출 마지막) : 파일 "orb1.py", 줄 33, out [: rows1, : cols1 ,:] = np.dstack ([img1, img1, img1]) ValueError : 입력 배열을 모양에서 방송 할 수 없음 (900 , 1440,9) shape (900,1440,3) –

+2

@BhushanPatil - 함수의 문서화 문자열을주의 깊게 읽어보십시오 **. 그레이 스케일 이미지가 필요합니다. ** RGB ** 이미지를 사용 중입니다. 이 기능을 사용하려면 이미지를 그레이 스케일로 변환해야합니다. 간단한 호출'cv2.cvtColor'만으로 충분합니다 :'img = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY)'가 작동합니다. 다음 번에 사용하기 전에 기능에 대한 문서를 실제로 읽으십시오. 이것은 다른 개발자의 코드를 사용할 때 모든 개발자가 배워야하는 표준 기술입니다. – rayryeng

관련 문제