2013-10-30 20 views
6

Tôi đang phát hiện các điểm đánh dấu trên hình ảnh được chụp bởi iPad của tôi. Do đó tôi muốn tính toán các phép dịch và phép quay giữa chúng, tôi muốn thay đổi quan điểm thay đổi trên hình ảnh những hình ảnh này, vì vậy nó sẽ giống như tôi đang chụp chúng trực tiếp trên các điểm đánh dấu.OpenCV: wrapPerspective trên toàn bộ hình ảnh

Ngay bây giờ tôi đang sử dụng

points2D.push_back(cv::Point2f(0, 0)); 
points2D.push_back(cv::Point2f(50, 0)); 
points2D.push_back(cv::Point2f(50, 50)); 
points2D.push_back(cv::Point2f(0, 50)); 

Mat perspectiveMat = cv::getPerspectiveTransform(points2D, imagePoints); 
cv::warpPerspective(*_image, *_undistortedImage, M, cv::Size(_image->cols, _image->rows)); 

Mà cho những kết quả của tôi (nhìn vào góc bên phải phía dưới cho kết quả của warpPerspective):

photo 1 photo 2 photo 3

Như bạn có thể thấy hình ảnh kết quả chứa điểm đánh dấu được công nhận ở góc trên cùng bên trái của hình ảnh kết quả. Vấn đề của tôi là tôi muốn chụp toàn bộ hình ảnh (không cắt xén) để tôi có thể phát hiện các dấu hiệu khác trên hình ảnh đó sau này.

Tôi có thể làm như thế nào? Có lẽ tôi nên sử dụng các vectơ xoay/dịch từ hàm solvePnP?

EDIT:

Unfortunatelly thay đổi kích thước của hình ảnh bị biến dạng không giúp được gì nhiều, bởi vì hình ảnh vẫn được dịch nên trái đầu ngõ ngách của marker là ở góc trên cùng bên trái của hình ảnh.

Ví dụ khi tôi đã tăng gấp đôi kích thước sử dụng:

cv::warpPerspective(*_image, *_undistortedImage, M, cv::Size(2*_image->cols, 2*_image->rows)); 

Tôi đã nhận được những hình ảnh này:

photo 4 photo 5

Trả lời

3

Mã của bạn dường như không được hoàn thành, vì vậy rất khó để nói vấn đề là gì.

Trong mọi trường hợp, hình ảnh bị biến dạng có thể có kích thước hoàn toàn khác so với hình ảnh đầu vào, do đó bạn sẽ phải điều chỉnh tham số kích thước bạn đang sử dụng cho warpPerspective.

Ví dụ cố gắng tăng gấp đôi kích thước:

cv::warpPerspective(*_image, *_undistortedImage, M, 2*cv::Size(_image->cols, _image->rows)); 

Edit:

Để đảm bảo toàn bộ hình ảnh bên trong hình ảnh này, tất cả các góc của hình ảnh ban đầu của bạn phải được biến dạng là bên trong kết quả hình ảnh. Vì vậy, chỉ cần tính toán điểm đến bị biến dạng cho mỗi điểm trong góc và điều chỉnh điểm đích tương ứng.

Để làm cho nó thêm rõ ràng một số mẫu mã:

// calculate transformation 
cv::Matx33f M = cv::getPerspectiveTransform(points2D, imagePoints); 

// calculate warped position of all corners 

cv::Point3f a = M.inv() * cv::Point3f(0, 0, 1); 
a = a * (1.0/a.z); 

cv::Point3f b = M.inv() * cv::Point3f(0, _image->rows, 1); 
b = b * (1.0/b.z); 

cv::Point3f c = M.inv() * cv::Point3f(_image->cols, _image->rows, 1); 
c = c * (1.0/c.z); 

cv::Point3f d = M.inv() * cv::Point3f(_image->cols, 0, 1); 
d = d * (1.0/d.z); 

// to make sure all corners are in the image, every position must be > (0, 0) 
float x = ceil(abs(min(min(a.x, b.x), min(c.x, d.x)))); 
float y = ceil(abs(min(min(a.y, b.y), min(c.y, d.y)))); 

// and also < (width, height) 
float width = ceil(abs(max(max(a.x, b.x), max(c.x, d.x)))) + x; 
float height = ceil(abs(max(max(a.y, b.y), max(c.y, d.y)))) + y; 

// adjust target points accordingly 
for (int i=0; i<4; i++) { 
    points2D[i] += cv::Point2f(x,y); 
} 

// recalculate transformation 
M = cv::getPerspectiveTransform(points2D, imagePoints); 

// get result 
cv::Mat result; 
cv::warpPerspective(*_image, result, M, cv::Size(width, height), cv::WARP_INVERSE_MAP); 
+0

Tôi biết rằng hình ảnh đầu ra có thể có dimenstions khác nhau, tôi đã thử với gấp đôi họ (nhìn vào câu hỏi đã chỉnh sửa cho kết quả), nhưng nó không đã cho tôi kết quả hữu ích. Bạn nói rằng mã của tôi chưa hoàn thành - tôi nên thêm gì? Tôi đang sử dụng 'getPerspectiveTransform' để lấy ma trận chuyển đổi, và tôi đang sử dụng tọa độ các góc của điểm đánh dấu được phát hiện có ma trận' dst' (theo tài liệu OpenCV - http://docs.opencv.org/modules/imgproc /doc/geometric_transformations.html#getperspectivetransform). – Axadiw

+0

Vâng, tôi nghĩ rằng tọa độ mục tiêu của bạn (-6, -6) vv là một chút lạ. Bởi vì điều đó có nghĩa là hình chữ nhật mục tiêu của bạn sẽ ở các tọa độ này trong hình ảnh kết quả. Để di chuyển chúng, chỉ cần di chuyển hình chữ nhật đích đến giữa hình ảnh đích. – littleimp

+0

Cảm ơn - Tôi đã tìm ra rằng tôi đã đăng sai mảng points2D (Tôi đã chỉnh sửa nó trong câu hỏi ngay bây giờ). Chuyển các điểm này một chút đã di chuyển toàn bộ hình ảnh đầu ra, nhưng tôi vẫn đang cắt xén một số phần của nó. – Axadiw

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