2014-06-27 22 views
10

OpenCV không cung cấp một RANSAC chức năng cho mỗi gia nhập hoặc ít nhất là trong một hình thức như vậy mà bạn chỉ có thể gọi nó và được thực hiện với nó (ví dụ cv::ransac(...)). Tất cả các hàm/phương thức có thể sử dụng RANSAC đều có một cờ cho phép nó. Tuy nhiên, điều này không phải lúc nào cũng hữu ích nếu bạn thực sự muốn làm điều gì đó khác với các tính toán RANSAC tính toán sau khi bạn đã ước tính ma trận homography/cơ bản ví dụ như tạo một âm mưu tốt trong Octave hoặc phần mềm/thư viện tương tự của các điểm, áp dụng các thuật toán bổ sung trên còn lại thiết lập các trận đấu được lọc, vvOpenCV: Làm thế nào để nhận được điểm inlier sử dụng findHomography()/findFundamental() và RANSAC

Sau khi phù hợp với hai hình ảnh một được một vector của trận đấu. Cùng với đó, chúng tôi có tất nhiên 2 bộ keypoints (một cho mỗi hình ảnh) được sử dụng trong quá trình phù hợp. Sử dụng kết quả phù hợp và điểm chính chúng tôi tạo hai vectơ điểm (ví dụ: cv::Point2f points) và chuyển các số này đến findHomography(). Từ thisthis bài đăng tôi đã khám phá cách chính xác các ký tự được đánh dấu bằng mặt nạ, chúng tôi chuyển đến hàm đó. Mỗi hàng bên trong mặt nạ liên quan đến một inlier/outlier. Tuy nhiên tôi không thể tìm ra cách sử dụng thông tin chỉ mục hàng từ hai bộ điểm của tôi. Nhìn vào mã nguồn của OpenCV không làm tôi quá xa. Trong findFundamental() (tương tự như findHomography() khi nói đến chữ ký của nó và mặt nạ phần) họ sử dụng compressPoints(), mà dường như bằng cách nào đó kết hợp hai bộ chúng tôi có như là đầu vào (nguồn và điểm đích) thành một. Trong khi thử nghiệm để xác định bản chất của mặt nạ, tôi đã thử 2 bộ điểm phù hợp (được chuyển đổi cv::Keypoints thành cv::Point2f - một quy trình chuẩn). Mỗi bộ chứa 300 điểm nên tổng cộng chúng ta có 600 điểm. Mặt nạ trả về chứa 300 hàng (giá trị không quan trọng đối với chủ đề này trong tầm tay).

EDIT: Trong khi viết những dòng này tôi đã khám phá ra câu trả lời (xem bên dưới) nhưng quyết định gửi câu hỏi này anyway trong trường hợp ai đó cần thông tin này càng sớm càng tốt và ở dạng nhỏ gọn. Lưu ý rằng chúng ta vẫn cần một hàm OpenCV, có hỗ trợ RANSAC. Vì vậy, nếu bạn có một tập hợp các điểm nhưng không có ý định tính toán ma trận cơ bản hoặc ma trận cơ bản, điều này rõ ràng không phải là cách và tôi dám nói rằng tôi không thể tìm thấy bất kỳ thứ gì hữu ích trong API của OpenCV có thể giúp tránh chướng ngại vật này do đó bạn cần sử dụng một thư viện bên ngoài.

Trả lời

10

Các giải pháp thực sự là khá tầm thường. Như chúng ta biết mỗi hàng trong mặt nạ của chúng ta cung cấp thông tin nếu chúng ta có một inlier hoặc outlier. Tuy nhiên chúng tôi có 2 bộ điểm làm đầu vào sao cho chính xác một hàng chứa một giá trị đại diện cho hai điểm? Bản chất của kiểu lập chỉ mục này xuất hiện trong tâm trí của tôi trong khi suy nghĩ về cách hai tập hợp các điểm xuất hiện trong findHomography() (trong trường hợp của tôi, tôi đã tính toán tính đồng bộ giữa hai hình ảnh). Cả hai bộ đều có số điểm bằng nhau trong số đó vì thực tế đơn giản là chúng được trích xuất từ ​​các kết quả trùng khớp giữa cặp hình ảnh của chúng tôi. Điều này có nghĩa rằng một hàng trong mặt nạ của chúng tôi là chỉ số thực tế của các điểm trong hai bộ và cũng là chỉ mục trong vectơ của các kết quả phù hợp cho hai hình ảnh. Tôi đã quản lý thành công theo cách thủ công tham chiếu đến một tập nhỏ các điểm phù hợp dựa trên điều này và kết quả như mong đợi. Điều quan trọng là bạn không thay đổi thứ tự của các kết quả trùng khớp và điểm 2D mà bạn đã trích xuất từ ​​chúng bằng cách sử dụng các điểm tham chiếu trong mỗi cv::DMatch. Dưới đây bạn có thể thấy một ví dụ đơn giản cho một cặp nội bộ duy nhất.

for(int i = 0; i < matchesObjectScene.size(); ++i) 
{ 
    // extract points from keypoints based on matches 
    pointsObject.push_back(keypointsObject.at(matchesObjectScene.at(i).queryIdx).pt); 
    pointsScene.push_back(keypointsScene.at(matchesObjectScene.at(i).trainIdx).pt); 
} 
// compute homography using RANSAC 
cv::Mat mask; 
cv::Mat H = cv::findHomography(pointsObject, pointsScene, CV_RANSAC, ransacThreshold, mask); 

Trong ví dụ trên, nếu chúng ta in một số inlier

int maskRow = 10; 
std::cout << "POINTS: object(" << pointsObject.at(maskRow).x << "," << pointsObject.at(maskRow).y << ") - scene(" << pointsScene.at(maskRow).x << "," << pointsScene.at(maskRow).y << ")" << std::endl; 

và sau đó một lần nữa nhưng lần này sử dụng keypoint của chúng tôi (cũng có thể được thực hiện với những điểm 2D chiết xuất)

std::cout << "POINTS (via match-set): object(" << keypointsObject.at(matchesCurrentObject.at(maskRow).queryIdx).pt.x << "," << keypointsObject.at(matchesCurrentObject.at(maskRow).queryIdx).pt.y << ") - scene(" << keypointsScene.at(matchesCurrentObject.at(maskRow).trainIdx).pt.x << "," << keypointsScene.at(matchesCurrentObject.at(maskRow).trainIdx).pt.y << ")" << std::endl; 

chúng tôi thực sự có được kết quả tương tự:

POINTS: object(462,199) - sscene(485,49) 
POINTS (via match-set): object(462,199) - scene(485,49) 

Để có được inlier thực tế chúng tôi chỉ đơn giản là phải kiểm tra xem hàng hiện tại trong mặt nạ thực sự chứa một 0 hoặc khác không có giá trị:

if((unsigned int)mask.at<uchar>(maskRow)) 
    // store match or keypoints or points somewhere where you can access them later 
+1

Đối với câu đầu tiên, thực sự là hàng trong mặt nạ không đại diện cho một inlier. Hàng đại diện cho trạng thái của inlier hoặc outlier. Tham khảo bài đăng này [link] (http://stackoverflow.com/questions/15815304/opencv-c-findhomography-mask-values-meaning) để giải thích thêm. –

+0

Có, đó là chính xác và đây là những gì tôi có nghĩa là nhưng bây giờ mà tôi đọc lại câu này tôi thấy làm thế nào nó có thể được hiểu sai. Tôi sẽ thay đổi điều đó. – rbaleksandar

+0

Nhưng hàng đại diện cho trạng thái của inlier hoặc outliers nhưng không có điểm chính trên mỗi trạng thái inlier hoặc outliers. các điểm chính được lưu trữ trong vectơ. Vậy làm thế nào chúng ta có thể nhận được điểm quan trọng tương ứng của inlier trong mặt nạ? – Abc

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