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 **********************************************************
******************************************************************************/
|