summaryrefslogtreecommitdiffstats
path: root/modules/image/src/img_orb.cpp
blob: 58d7a4e27c3428fac1872ff76ee40c5d4329c385 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/******************************************************************************
 *	Copyright (C) 2018	Alejandro Colomar Andrés		      *
 ******************************************************************************/


/******************************************************************************
 ******* headers **************************************************************
 ******************************************************************************/
/* Standard C++ --------------------------------------------------------------*/
		/* std::vector */
	#include <vector>

/* Standard C ----------------------------------------------------------------*/
		/* snprintf() */
	#include <cstdio>

/* Packages ------------------------------------------------------------------*/
		/* opencv */
	#include <opencv2/opencv.hpp>
	#include <opencv2/features2d/features2d.hpp>

/* Module -------------------------------------------------------------------*/
	#include "img_orb.hpp"


/******************************************************************************
 ******* macros ***************************************************************
 ******************************************************************************/
	# define	MAX_FEATURES	(50000)
	# define	GOOD_MATCH_P	(0.25)


/******************************************************************************
 ******* static functions *****************************************************
 ******************************************************************************/
static	void	img_orb_align	(class cv::Mat  *img_0,
				class cv::Mat  *img_1);


/******************************************************************************
 ******* main *****************************************************************
 ******************************************************************************/
void	img_orb_act	(class cv::Mat  *img_ref,
			class cv::Mat  *imgptr, int action)
{
	switch (action) {
	case IMG_ORB_ACT_ALIGN:
		img_orb_align(img_ref, imgptr);
		break;
	}
}


/******************************************************************************
 ******* static functions *****************************************************
 ******************************************************************************/
static	void	img_orb_align	(class cv::Mat  *img_0,
				class cv::Mat  *img_1)
{
	/* Variables to store keypoints & descriptors */
	std::vector <class cv::KeyPoint>	keypoints_0;
	std::vector <class cv::KeyPoint>	keypoints_1;
	class cv::Mat				descriptors_0;
	class cv::Mat				descriptors_1;

	/* Detect ORB features & compute descriptors */
#if 1
	/* OpenCV 2.x */
	class cv::ORB	orb;
	orb(*img_0, cv::Mat(), keypoints_0, descriptors_0);
	orb(*img_1, cv::Mat(), keypoints_1, descriptors_1);
#else
	/* OpenCV 3.x */
	class cv::Ptr <class cv::Feature2D>	orb;
	orb	= cv::ORB::create(MAX_FEATURES);
	orb->detectAndCompute(*img_0, cv::Mat(), keypoints_0, descriptors_0);
	orb->detectAndCompute(*img_1, cv::Mat(), keypoints_1, descriptors_1);
#endif


	/* Match structures */
	std::vector <struct cv::DMatch>		matches;
	cv::Ptr <class cv::DescriptorMatcher>	matcher;
	matcher	= cv::DescriptorMatcher::create("BruteForce-Hamming");
	matcher->match(descriptors_1, descriptors_0, matches, cv::Mat());

	/* Sort matches by score */
	std::sort(matches.begin(), matches.end());

	/* Remove not so good matches */
	int	good_matches;
	good_matches	= GOOD_MATCH_P * matches.size();
	matches.erase(matches.begin() + good_matches, matches.end());

	/* Draw top matches */
	class cv::Mat	img_matches;
	cv::drawMatches(*img_1, keypoints_1, *img_0, keypoints_0, matches,
								img_matches);
	cv::imwrite("matches.jpg", img_matches);

	/* Extract location of good matches */
	std::vector <class cv::Point_ <float>>	points_0;
	std::vector <class cv::Point_ <float>>	points_1;
	int	i;
	for (i = 0; i < matches.size(); i++) {
		points_1.push_back(keypoints_1[matches[i].queryIdx].pt);
		points_0.push_back(keypoints_0[matches[i].trainIdx].pt);
	}

	/* Find homography */
	class cv::Mat	img_hg;
	img_hg	= cv::findHomography(points_1, points_0, CV_RANSAC);

	/* Use homography to warp image */
	class cv::Mat	img_align;
	cv::warpPerspective(*img_1, img_align, img_hg, img_0->size());

	/* Write img_align into img_1 */
	*img_1	= img_align;
	img_align.release();
}


/******************************************************************************
 ******* end of file **********************************************************
 ******************************************************************************/