2012-10-25 32 views
15

Tôi có 2 hình ảnh thử nghiệm tại đây. Câu hỏi của tôi là, làm thế nào để ánh xạ hình vuông trong hình ảnh đầu tiên đến tứ giác trong hình ảnh thứ hai mà không cắt xén hình ảnh.Cách hiển thị toàn bộ hình ảnh khi sử dụng OpenCV warpPerspective

Hình 1: image 1

Hình 2: image 2

Đây là mã hiện tại của tôi sử dụng OpenCV warpPerspective chức năng.

import cv2 
import numpy as np 

img1_square_corners = np.float32([[253,211], [563,211], [563,519],[253,519]]) 
img2_quad_corners = np.float32([[234,197], [520,169], [715,483], [81,472]]) 

h, mask = cv2.findHomography(img1_square_corners, img2_quad_corners) 
im = cv2.imread("image1.png") 
out = cv2.warpPerspective(im, h, (800,800)) 
cv2.imwrite("result.png", out) 

Kết quả: result

Như bạn có thể thấy, vì dsize = (800.800) tham số trong hàm warpPerspective, tôi không thể có được cái nhìn đầy đủ của hình ảnh 1. Nếu tôi điều chỉnh dsize, hình vuông sẽ không bản đồ chính xác. Có cách nào để thay đổi kích thước hình ảnh đầu ra để tôi có thể nhận được toàn bộ hình ảnh của hình ảnh 1?

+0

bạn có thể xây dựng o n "Nếu tôi điều chỉnh dsize, hình vuông sẽ không ánh xạ chính xác"? Nó bị biến dạng? được dịch? thu nhỏ? ect. Một hình ảnh khác sẽ hữu ích – Hammer

Trả lời

8

Có, nhưng bạn nên nhận ra rằng hình ảnh đầu ra có thể là rất lớn. Tôi đã nhanh chóng viết mã Python sau, nhưng ngay cả một hình ảnh 3000 x 3000 không thể phù hợp với đầu ra, nó chỉ là cách quá lớn do sự chuyển đổi. Mặc dù, đây là mã của tôi, tôi hy vọng nó sẽ được sử dụng cho bạn.

import cv2 
import numpy as np 
import cv   #the old cv interface 

img1_square_corners = np.float32([[253,211], [563,211], [563,519],[253,519]]) 
img2_quad_corners = np.float32([[234,197], [520,169], [715,483], [81,472]]) 

h, mask = cv2.findHomography(img1_square_corners, img2_quad_corners) 
im = cv2.imread("image1.png") 

Tạo hình ảnh đầu ra ở đây, tôi đã sử dụng (3000, 3000) làm ví dụ.

out_2 = cv.fromarray(np.zeros((3000,3000,3),np.uint8)) 

Bằng cách sử dụng giao diện cũ cv, tôi đã viết trực tiếp vào đầu ra và do đó không bị cắt. Tôi đã thử điều này bằng cách sử dụng giao diện cv2, nhưng vì một lý do nào đó nó không hoạt động ... Có lẽ ai đó có thể làm sáng tỏ điều đó?

cv.WarpPerspective(cv.fromarray(im), out_2, cv.fromarray(h)) 
cv.ShowImage("test", out_2) 
cv.SaveImage("result.png", out_2) 
cv2.waitKey() 

Dù sao, điều này mang lại một hình ảnh rất lớn, chứa hình ảnh gốc của bạn 1, bị biến dạng. Toàn bộ hình ảnh sẽ hiển thị nếu bạn chỉ định hình ảnh đầu ra đủ lớn. (Trong đó có thể là rất lớn thực sự!)

Tôi hy vọng rằng mã này có thể giúp bạn.

+0

Lúc đầu, tôi sẽ thêm yếu tố dịch vào homography, có được các khung nhìn của các vùng khác nhau của hình ảnh được chuyển đổi và sau đó kết hợp các khung nhìn hoàn toàn. Nhưng giải pháp của bạn có vẻ tốt hơn! Cảm ơn bạn! –

+0

Không sao cả, tôi vui vì giải pháp của tôi đã giúp bạn. – casper

28

Giải pháp của tôi là để tính toán kích thước hình ảnh kết quả, và sau đó làm một bản dịch.

def warpTwoImages(img1, img2, H): 
    '''warp img2 to img1 with homograph H''' 
    h1,w1 = img1.shape[:2] 
    h2,w2 = img2.shape[:2] 
    pts1 = float32([[0,0],[0,h1],[w1,h1],[w1,0]]).reshape(-1,1,2) 
    pts2 = float32([[0,0],[0,h2],[w2,h2],[w2,0]]).reshape(-1,1,2) 
    pts2_ = cv2.perspectiveTransform(pts2, H) 
    pts = concatenate((pts1, pts2_), axis=0) 
    [xmin, ymin] = int32(pts.min(axis=0).ravel() - 0.5) 
    [xmax, ymax] = int32(pts.max(axis=0).ravel() + 0.5) 
    t = [-xmin,-ymin] 
    Ht = array([[1,0,t[0]],[0,1,t[1]],[0,0,1]]) # translate 

    result = cv2.warpPerspective(img2, Ht.dot(H), (xmax-xmin, ymax-ymin)) 
    result[t[1]:h1+t[1],t[0]:w1+t[0]] = img1 
    return result 

dst_pts = float32([kp1[m.queryIdx].pt for m in good]).reshape(-1,1,2) 
src_pts = float32([kp2[m.trainIdx].pt for m in good]).reshape(-1,1,2) 
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) 

result = warpTwoImages(img1_color, img2_color, M) 

enter image description here

1

Đầu tiên, hãy làm theo các giải pháp trước đó để tính toán ma trận homography. Sau khi bạn có ma trận homography, bạn cần phải làm cong hình ảnh đối với ma trận Homography. Cuối cùng, hợp nhất hình ảnh bị biến dạng.

Ở đây, tôi sẽ chia sẻ một ý tưởng mà có thể được sử dụng để kết hợp những hình ảnh méo mó. (Câu trả lời trước đó, sử dụng một loạt các chỉ mục để phủ lên, ở đây tôi đang sử dụng mặt nạ ROI)

Mặt nạ Vùng quan tâm (ROI) và Hình ảnh có màu đen. Sau đó, thêm hình ảnh với ROI.(Xem OpenCV Bitmask Tutorial)

def copyOver(source, destination): 
    result_grey = cv2.cvtColor(source, cv2.COLOR_BGR2GRAY) 
    ret, mask = cv2.threshold(result_grey, 10, 255, cv2.THRESH_BINARY) 
    mask_inv = cv2.bitwise_not(mask) 
    roi = cv2.bitwise_and(source, source, mask=mask) 
    im2 = cv2.bitwise_and(destination, destination, mask=mask_inv) 
    result = cv2.add(im2, roi) 
    return result 


warpedImageB = cv2.warpPerspective(imageB, H, (imageA.shape[1], imageA.shape[0])) 
result = copyOver(imageA, warpedImageB) 

Hình ảnh đầu tiên:

First

Thứ hai hình ảnh:

Second

khâu hình ảnh: Stitched

Các vấn đề liên quan