Tôi đang làm việc trên ứng dụng Panography/Panorama trong OpenCV và tôi đã gặp phải một vấn đề mà tôi thực sự không thể hiểu được. Để biết ý tưởng về bức ảnh toàn cảnh trông như thế nào, hãy xem tại bài viết trên Panography Wikipedia: http://en.wikipedia.org/wiki/PanographyOpenCV findHomography Vấn đề
Cho đến nay, tôi có thể chụp nhiều ảnh và ghép chúng lại với nhau trong khi tạo bất kỳ hình ảnh nào tôi thích ảnh tham chiếu; đây là một chút taster của những gì tôi có ý nghĩa.
Tuy nhiên, như bạn thấy - có nhiều vấn đề. Cái chính tôi đang phải đối mặt là hình ảnh đang bị cắt (hình ảnh bên phải: hình ảnh xa bên phải, đầu hình ảnh). Để làm nổi bật lý do tại sao điều này xảy ra, tôi sẽ rút ra những điểm đã được phù hợp, và vẽ đường cho nơi việc chuyển đổi sẽ kết thúc:
Trong trường hợp hình ảnh bên trái là hình ảnh tham khảo, và bên phải hình ảnh là hình ảnh sau khi nó được dịch (bản gốc dưới đây) - Tôi đã vẽ các đường màu xanh lá cây để làm nổi bật hình ảnh. Những hình ảnh có những điểm góc sau:
TL: [234.759, -117.696]
TR: [852.226, -38.9487]
BR: [764.368, 374.84]
BL: [176.381, 259.953]
Vì vậy, vấn đề chính tôi có là sau khi quan điểm đã được thay đổi hình ảnh:
bị lỗ như vậy:
Bây giờ đủ hình ảnh, một số mã.
Tôi đang sử dụng một cv::SurfFeatureDetector
, cv::SurfDescriptorExtractor
và cv::FlannBasedMatcher
để có được tất cả những điểm, và tôi có thể tính các trận đấu và các trận đấu quan trọng hơn tốt bằng cách làm như sau:
/* calculate the matches */
for(int i = 0; i < descriptors_thisImage.rows; i++) {
double dist = matches[i].distance;
if(dist < min_dist) min_dist = dist;
if(dist > max_dist) max_dist = dist;
}
/* calculate the good matches */
for(int i = 0; i < descriptors_thisImage.rows; i++) {
if(matches[i].distance < 3*min_dist) {
good_matches.push_back(matches[i]);
}
}
này là khá chuẩn, và làm điều này tôi làm theo các hướng dẫn tìm thấy ở đây: http://opencv.itseez.com/trunk/doc/tutorials/features2d/feature_homography/feature_homography.html
Để sao chép hình ảnh trên đỉnh của nhau, tôi sử dụng các phương pháp sau đây (nơi img1
và img2
là std::vector<cv::Point2f>
)
/* set the keypoints from the good matches */
for(int i = 0; i < good_matches.size(); i++) {
img1.push_back(keypoints_thisImage[ good_matches[i].queryIdx ].pt);
img2.push_back(keypoints_referenceImage[ good_matches[i].trainIdx ].pt);
}
/* calculate the homography */
cv::Mat H = cv::findHomography(cv::Mat(img1), cv::Mat(img2), CV_RANSAC);
/* warp the image */
cv::warpPerspective(thisImage, thisTransformed, H, cv::Size(thisImage.cols * 2, thisImage.rows * 2), cv::INTER_CUBIC);
/* place the contents of thisImage in gsThisImage */
thisImage.copyTo(gsThisImage);
/* set the values of gsThisImage to 255 */
for(int i = 0; i < gsThisImage.rows; i++) {
cv::Vec3b *p = gsThisImage.ptr<cv::Vec3b>(i);
for(int j = 0; j < gsThisImage.cols; j++) {
for(int grb=0; grb < 3; grb++) {
p[j][grb] = cv::saturate_cast<uchar>(255.0f);
}
}
}
/* convert the colour to greyscale */
cv::cvtColor(gsThisImage, gsThisImage, CV_BGR2GRAY);
/* warp the greyscale image to create an image mask */
cv::warpPerspective(gsThisImage, thisMask, H, cv::Size(thisImage.cols * 2, thisImage.rows * 2), cv::INTER_CUBIC);
/* stitch the transformed image to the reference image */
thisTransformed.copyTo(referenceImage, thisMask);
Vì vậy, tôi có tọa độ nơi hình ảnh bị biến dạng sẽ kết thúc, tôi có các điểm tạo ma trận đồng nhất được sử dụng cho các phép biến đổi này - nhưng tôi không thể biết được dịch những hình ảnh này để chúng không bị cắt. Bất kỳ trợ giúp hoặc con trỏ được đánh giá cao!
Ahh, tôi hiểu - vì vậy trước khi tôi chạy cv :: warpPerspective tôi chỉnh sửa các giá trị trong ảnh nổi ba chiều? Nó rất rõ ràng bây giờ! Cảm ơn nhiều! Ngoài ra, tôi sẽ xem xét các mô-đun khâu hình ảnh và thêm nó như là một lựa chọn (cũng sử dụng GPU và CPU để so sánh sự khác biệt) - chỉ cần cố gắng tìm hiểu OpenCV. :-) – krslynx
Cảm ơn bạn một lần nữa! http://krslynx.com/images/ – krslynx
Vui mừng khi thấy kết quả tốt đẹp của bạn! – Sam