1. 程式人生 > >C++ Opencv——影象特徵工程(1) AKAZE(opencv3.3.0)

C++ Opencv——影象特徵工程(1) AKAZE(opencv3.3.0)

特徵檢測

第一步:檢測器

Ptr<AKAZE> detector = AKAZE::create();

第二步:檢測器子類—檢測

detector->detect(img, keypoints, Mat());

計算檢測時間(通用):

double t1 = getTickCount();

/*加入你要計算時間的程式碼段*/

double t2 = getTickCount();
double tkaze =  (t2 - t1) / getTickFrequency();
printf("Time consume(s) : %f\n", tkaze);

第三步:畫出特徵點圖

drawKeypoints(img, keypoints, keypointImg, Scalar::all(-1), DrawMatchesFlags::DEFAULT);

總體程式 

// Demo_Feature.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	Mat img1 = imread("C:\\Users\\Administrator\\Desktop\\樣品\\瓷磚\\方格.bmp", IMREAD_GRAYSCALE);
	Mat img2 = imread("C:\\Users\\Administrator\\Desktop\\樣品\\瓷磚\\方格.bmp", IMREAD_GRAYSCALE);
	if (img1.empty() && img2.empty()) {
		printf("could not load image...\n");
		return -1;
	} 
	imshow("input image", img1);

	// kaze detection
	Ptr<AKAZE> detector = AKAZE::create();
	vector<KeyPoint> keypoints;
	double t1 = getTickCount();
	detector->detect(img1, keypoints, Mat());
	double t2 = getTickCount();
	double tkaze = 1000 * (t2 - t1) / getTickFrequency();
	printf("KAZE Time consume(ms) : %f", tkaze);

	Mat keypointImg;
	drawKeypoints(img1, keypoints, keypointImg, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
	imshow("kaze key points", keypointImg);

	waitKey(0);
	return 0;
}

特徵匹配

第一步:檢測器

Ptr<AKAZE> detector = AKAZE::create();

第二步: 檢測器子類—檢測和計算

detector->detectAndCompute(img1, Mat(), keypoints_obj, descriptor_obj);
detector->detectAndCompute(img2, Mat(), keypoints_scene, descriptor_scene);

第三步: 計算結果匹配

// 構建匹配器
FlannBasedMatcher matcher(new flann::LshIndexParams(20, 10, 2));
// 進行匹配
matcher.match(descriptor_obj, descriptor_scene, matches);

 第四步:匹配結果畫出

drawMatches(img1, keypoints_obj, img2, keypoints_scene, matches, akazeMatchesImg);

第五步:最佳匹配選取

vector<DMatch> goodMatches;
double minDist = 100000, maxDist = 0;
for (int i = 0; i < descriptor_obj.rows; i++) {
	double dist = matches[i].distance;
	if (dist < minDist) {
		minDist = dist;
	}
	if (dist > maxDist) {
		maxDist = dist;
	}
}
printf("min distance : %f", minDist);

for (int i = 0; i < descriptor_obj.rows; i++) {
	double dist = matches[i].distance;
	if (dist < max(1.5*minDist, 0.02)) {
		goodMatches.push_back(matches[i]);
	}
}

第六步:最佳匹配結果畫出

drawMatches(img1, keypoints_obj, img2, keypoints_scene, goodMatches, akazeMatchesImg, Scalar::all(-1),Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

 總體程式

// Demo_Feature.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	Mat img1 = imread("C:\\Users\\Administrator\\Desktop\\樣品\\瓷磚\\方格.bmp", IMREAD_GRAYSCALE);
	Mat img2 = imread("C:\\Users\\Administrator\\Desktop\\樣品\\瓷磚\\方格.bmp", IMREAD_GRAYSCALE);
	if (img1.empty() && img2.empty()) {
		printf("could not load image...\n");
		return -1;
	}

	imshow("box image", img1);
	imshow("scene image", img2);

	// extract akaze features
	Ptr<AKAZE> detector = AKAZE::create();
	vector<KeyPoint> keypoints_obj;
	vector<KeyPoint> keypoints_scene;
	Mat descriptor_obj, descriptor_scene;
	double t1 = getTickCount();
	detector->detectAndCompute(img1, Mat(), keypoints_obj, descriptor_obj);
	detector->detectAndCompute(img2, Mat(), keypoints_scene, descriptor_scene);
	double t2 = getTickCount();
	double tkaze = 1000 * (t2 - t1) / getTickFrequency();
	printf("AKAZE Time consume(ms) : %f\n", tkaze);

	// matching
	FlannBasedMatcher matcher(new flann::LshIndexParams(20, 10, 2));
	//FlannBasedMatcher matcher;
	vector<DMatch> matches;
	matcher.match(descriptor_obj, descriptor_scene, matches);

	// draw matches(key points)
	Mat akazeMatchesImg;
	drawMatches(img1, keypoints_obj, img2, keypoints_scene, matches, akazeMatchesImg);
	imshow("akaze match result", akazeMatchesImg);

	vector<DMatch> goodMatches;
	double minDist = 100000, maxDist = 0;
	for (int i = 0; i < descriptor_obj.rows; i++) {
		double dist = matches[i].distance;
		if (dist < minDist) {
			minDist = dist;
		}
		if (dist > maxDist) {
			maxDist = dist;
		}
	}
	printf("min distance : %f", minDist);

	for (int i = 0; i < descriptor_obj.rows; i++) {
		double dist = matches[i].distance;
		if (dist < max(1.5*minDist, 0.02)) {
			goodMatches.push_back(matches[i]);
		}
	}

	drawMatches(img1, keypoints_obj, img2, keypoints_scene, goodMatches, akazeMatchesImg, Scalar::all(-1),
		Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
	imshow("good match result", akazeMatchesImg);

	waitKey(0);
	return 0;
}