특징점 검출하고 매칭하는 방법중에서
실시간으로 물체를 감시하는데에는 어떤 것이 가장 좋을지 알아보기 위해
하나씩 결과를 보는 중이다.
실시간으로 사용하기에는 SURF가 가장 적합할 것이라는 건 알지만
얼마나 차이가 나는지 확인해보고 싶어졌기 때문에 구현했다.
먼저 SIFT먼저 소스를 찾아 구현해보았는데,
읽어보고 있던 책을 촬영해 DB로 사용했고,
실시간 캠 영상에서 책을 촬영해 어느정도 되는지 확인했다.
OpenCV 안의 SIFT 속도는 실시간으로는 적합해 보이지 않는다.
SURF를 구현하려면
FeatureDetector와 DescriptororExtractor 구조체 앞의 Sift를 Surf로 변경해주면 된다.
예제는 다음과 같다.
#include "stdafx.h"
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <iostream>
#include <cstdlib>
int _tmain(int argc, _TCHAR* argv[])
{
// webcam routine
cv::VideoCapture capture(0);
if (!capture.isOpened()) {
std::cerr << "Could not open camera" << std::endl;
return 0;
}
// create a window
cv::namedWindow("webcam", 1);
// SIFT configuration
/*if (argc != 2) {
std::cerr << "usage: ocv_cam_sift filename" << std::endl;
return 0;
}*/
cv::Mat db_original = cv::imread("book.png", CV_LOAD_IMAGE_GRAYSCALE);
cv::Mat db;
cv::resize(db_original, db, cv::Size(db_original.cols / 2, db_original.rows / 2), 0, 0, CV_INTER_NN);
// SIFT feature detector and feature extractor
cv::SiftFeatureDetector detector(0.05, 5.0);
cv::SiftDescriptorExtractor extractor(3.0);
// Feature detection
std::vector<cv::KeyPoint> kps_db;
detector.detect(db, kps_db);
// Feature description
cv::Mat dscr_db;
extractor.compute(db, kps_db, dscr_db);
while (true) {
bool frame_valid = true;
cv::Mat frame_original;
cv::Mat frame;
try {
capture >> frame_original; // get a new frame from webcam
// downsample 1/2x
cv::resize(frame_original, frame, cv::Size(frame_original.cols / 2, frame_original.rows / 2), 0, 0, CV_INTER_NN);
}
catch (cv::Exception& e) {
std::cerr << "Exception occurred. Ignoring frame... " << e.err << std::endl;
frame_valid = false;
}
if (frame_valid) {
try {
// convert captured frame to grayscale & equlize
cv::Mat grayframe;
cv::cvtColor(frame, grayframe, CV_BGR2GRAY);
cv::equalizeHist(grayframe, grayframe);
// detection routine
// keypoint detection
std::vector<cv::KeyPoint> kps_frame;
detector.detect(grayframe, kps_frame);
// keypoint description
cv::Mat dscr_frame;
extractor.compute(grayframe, kps_frame, dscr_frame);
// matching using FLANN matcher
cv::FlannBasedMatcher matcher;
std::vector<cv::DMatch> matches;
matcher.match(dscr_db, dscr_frame, matches);
double max_dist = 0.0, min_dist = 100.0;
for (int i = 0; i < matches.size(); i++) {
double dist = matches[i].distance;
if (dist < min_dist) min_dist = dist;
if (dist > max_dist) max_dist = dist;
}
// drawing only good matches (dist less than 2*min_dist)
std::vector<cv::DMatch> good_matches;
for (int i = 0; i < matches.size(); i++) {
if (matches[i].distance <= 2 * min_dist) {
good_matches.push_back(matches[i]);
}
}
cv::Mat img_matches;
cv::drawMatches(db, kps_db, frame, kps_frame, good_matches, img_matches, cv::Scalar::all(-1), cv::Scalar::all(-1), std::vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
// print the output
cv::imshow("webcam", img_matches);
}
catch (cv::Exception& e) {
std::cerr << "Exception occurred. Ignoring frame... " << e.err << std::endl;
}
}
if (cv::waitKey(30) >= 0) break;
}
return 0;
}
'Computer VIsion > 영상처리' 카테고리의 다른 글
[OpenCV] IplImage -> Mat, Mat -> IplImage 변환 코드 (0) | 2017.06.27 |
---|---|
[영상처리] SIFT(Scale-Invariant Feature Transform) Algorithm (0) | 2017.05.08 |
[영상처리] 이미지 특징점(Feature) 검출 방법 (0) | 2017.04.11 |
[OpenCV] 이미지 와핑(Warping) (0) | 2017.04.10 |
[OpenCV] 얼굴 검출 (Face Detection) (0) | 2017.03.30 |