int method = 0;
std::vector<cv::KeyPoint> keypoints_object, keypoints_scene;
cv::Mat descriptors_object, descriptors_scene;
cv::ORB orb;
int minHessian = 500;
//cv::OrbFeatureDetector detector(500);
//ORB orb(25, 1.0f, 2, 10, 0, 2, 0, 10);
cv::OrbFeatureDetector detector(25, 1.0f, 2, 10, 0, 2, 0, 10);
//cv::OrbFeatureDetector detector(500,1.20000004768,8,31,0,2,ORB::HARRIS_SCORE,31);
cv::OrbDescriptorExtractor extractor;
//-- object
if(method == 0) { //-- ORB
orb.detect(img_object, keypoints_object);
//cv::drawKeypoints(img_object, keypoints_object, img_object, cv::Scalar(0,255,255));
//cv::imshow("template", img_object);
orb.compute(img_object, keypoints_object, descriptors_object);
} else { //-- SURF test
detector.detect(img_object, keypoints_object);
extractor.compute(img_object, keypoints_object, descriptors_object);
}
// http://stackoverflow.com/a/11798593
//if(descriptors_object.type() != CV_32F)
// descriptors_object.convertTo(descriptors_object, CV_32F);
//for(;;) {
cv::Mat frame = cv::imread("E:\\Projects\\Images\\2-134-2.bmp", 1);
cv::Mat img_scene = cv::Mat(frame.size(), CV_8UC1);
cv::cvtColor(frame, img_scene, cv::COLOR_RGB2GRAY);
//frame.copyTo(img_scene);
if(method == 0) { //-- ORB
orb.detect(img_scene, keypoints_scene);
orb.compute(img_scene, keypoints_scene, descriptors_scene);
} else { //-- SURF
detector.detect(img_scene, keypoints_scene);
extractor.compute(img_scene, keypoints_scene, descriptors_scene);
}
//-- matching descriptor vectors using FLANN matcher
cv::BFMatcher matcher;
std::vector<cv::DMatch> matches;
cv::Mat img_matches;
if(!descriptors_object.empty() && !descriptors_scene.empty()) {
matcher.match (descriptors_object, descriptors_scene, matches);
double max_dist = 0; double min_dist = 100;
//-- Quick calculation of max and min idstance between keypoints
for(int i = 0; i < descriptors_object.rows; i++)
{ double dist = matches[i].distance;
if(dist < min_dist) min_dist = dist;
if(dist > max_dist) max_dist = dist;
}
//printf("-- Max dist : %f \n", max_dist);
//printf("-- Min dist : %f \n", min_dist);
//-- Draw only good matches (i.e. whose distance is less than 3*min_dist)
std::vector<cv::DMatch>good_matches;
for(int i = 0; i < descriptors_object.rows; i++)
{ if(matches[i].distance < (max_dist/1.6))
{ good_matches.push_back(matches[i]); }
}
cv::drawMatches(img_object, keypoints_object, img_scene, keypoints_scene, \
good_matches, img_matches, cv::Scalar::all(-1), cv::Scalar::all(-1),
std::vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
//-- localize the object
std::vector<cv::Point2f> obj;
std::vector<cv::Point2f> scene;
for(size_t i = 0; i < good_matches.size(); i++) {
//-- get the keypoints from the good matches
obj.push_back(keypoints_object[ good_matches[i].queryIdx ].pt);
scene.push_back(keypoints_scene[ good_matches[i].trainIdx ].pt);
}
if(!obj.empty() && !scene.empty() && good_matches.size() >= 4) {
cv::Mat H = cv::findHomography(obj, scene, cv::RANSAC);
//-- get the corners from the object to be detected
std::vector<cv::Point2f> obj_corners(4);
obj_corners[0] = cv::Point(0,0);
obj_corners[1] = cv::Point(img_object.cols,0);
obj_corners[2] = cv::Point(img_object.cols,img_object.rows);
obj_corners[3] = cv::Point(0,img_object.rows);
std::vector<cv::Point2f> scene_corners(4);
cv::perspectiveTransform(obj_corners, scene_corners, H);
//-- Draw lines between the corners (the mapped object in the scene - image_2)
cv::line(img_matches, \
scene_corners[0] + cv::Point2f(img_object.cols, 0), \
scene_corners[1] + cv::Point2f(img_object.cols, 0), \
cv::Scalar(0,255,0), 4);
cv::line(img_matches, \
scene_corners[1] + cv::Point2f(img_object.cols, 0), \
scene_corners[2] + cv::Point2f(img_object.cols, 0), \
cv::Scalar(0,255,0), 4);
cv::line(img_matches, \
scene_corners[2] + cv::Point2f(img_object.cols, 0), \
scene_corners[3] + cv::Point2f(img_object.cols, 0), \
cv::Scalar(0,255,0), 4);
cv::line(img_matches, \
scene_corners[3] + cv::Point2f(img_object.cols, 0), \
scene_corners[0] + cv::Point2f(img_object.cols, 0), \
cv::Scalar(0,255,0), 4);
}
}
t =(double) getTickCount() - t;
printf("Time :%f",(double)(t*1000./getTickFrequency()));
cv::imshow("match result", img_matches);
cv::waitKey();
return 0;
여기서는 두 이미지간에 템플릿 매칭을 수행하고 있습니다. 여기서 ORB 알고리즘을 사용하여 핵심 포인트를 추출하고 BF Matcher와 일치 시키지만 좋은 결과를 얻지는 못합니다. 여기에 문제를 이해하기위한 이미지를 추가하고 있습니다 효율적으로 얻는 방법 opencv 2.4.9를 사용하여 ORB에서 결과를 얻으려면?
여기에 일치하는 키 포인트로 객체가 인식 될 때 프레임 이미지에서 객체 주위에 실제로 그려지는 사각형 인 테디의 진한 파란색 선을 볼 수 있습니다. 여기 Opencv 2.4.9를 사용하고 있는데, 좋은 결과를 얻으려면 어떻게해야합니까?
"효율적"에 대한 기준을 정하십시오. – rayryeng
빠르고 신뢰성이 높습니다. 나는 좋은 결과를 얻지 못하고 있습니다. 일치 효율은 30 %입니다. –
정확히 무엇을 탐지하려고하는지에 대한 설명도 제공해야합니다. 간단히 코드 덤핑과 우리가 당신의 코드를 통과 할 것으로 기대하는 것은 아무런 관심을 끌지 않을 것입니다 ... 누군가 (그러나 나)로부터 아무런 의견도없이 질문을 올린 지 4 일이 지났음을 알 수 있습니다. – rayryeng