生活随笔
收集整理的這篇文章主要介紹了
orb 算法源码实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
代碼在git
link
├──
1.png
├──
2.png
├── build
├── CMakeLists
.txt
└── orb_self
.cpp
cd build
cmake
..
make
./orb_cv
../1.png
../2.png
#include <opencv2/opencv.hpp>
#include <string>
#include <nmmintrin.h>
#include <chrono>using namespace std
;
string first_file
= "/home/ledi/桌面/clion/makfile_learn/slambook2/ch7/orb_self/1.png";
string second_file
= "/home/ledi/桌面/clion/makfile_learn/slambook2/ch7/orb_self/2.png";
typedef vector
<uint32_t> DescType
;
void ComputeORB(const cv
::Mat
&img
, vector
<cv
::KeyPoint
> &keypoints
, vector
<DescType
> &descriptors
);
void BfMatch(const vector
<DescType
> &desc1
, const vector
<DescType
> &desc2
, vector
<cv
::DMatch
> &matches
);int main(int argc
, char **argv
){cv
::Mat first_image
= cv
::imread(first_file
, CV_LOAD_IMAGE_COLOR
);cv
::Mat second_image
= cv
::imread(second_file
, CV_LOAD_IMAGE_COLOR
);assert(first_image
.data
!= nullptr && second_image
.data
!= nullptr );chrono
::steady_clock
::time_point t1
= chrono
::steady_clock
::now();vector
<cv
::KeyPoint
> keypoints1
;cv
::FAST(first_image
, keypoints1
, 40);vector
<DescType
> descriptor1
;ComputeORB(first_image
, keypoints1
, descriptor1
);vector
<cv
::KeyPoint
> keypoints2
;cv
::FAST(second_image
, keypoints2
, 40);vector
<DescType
> descriptor2
;ComputeORB(second_image
, keypoints2
, descriptor2
);chrono
::steady_clock
::time_point t2
= chrono
::steady_clock
::now();chrono
::duration
<double> time_used_extract
= chrono
::duration_cast
<chrono
::duration
<double>>(t2
- t1
);cout
<< " extract ORB cost = " << time_used_extract
.count() << " seconds. "<< endl
;vector
<cv
::DMatch
> matches
;chrono
::steady_clock
::time_point t3
= chrono
::steady_clock
::now();BfMatch(descriptor1
, descriptor2
, matches
);chrono
::steady_clock
::time_point t4
= chrono
::steady_clock
::now();chrono
::duration
<double> time_used_match
= chrono
::duration_cast
<chrono
::duration
<double>>(t4
- t3
);cout
<< " match ORB cost " << time_used_match
.count() << " seconds" <<endl
;chrono
::duration
<double> ORB_total_time_used
= chrono
::duration_cast
<chrono
::duration
<double>>(time_used_extract
+ time_used_match
);cout
<< " extract and match ORB cost = " << ORB_total_time_used
.count() << " seconds" <<endl
;cout
<< " matches: " << matches
.size() <<endl
;cv
::Mat image_show
;cv
::drawMatches(first_image
, keypoints1
, second_image
, keypoints2
, matches
, image_show
);cv
::imshow("matches", image_show
);cv
::imwrite("matches.png", image_show
);cv
::waitKey(0);cout
<<" done. "<<endl
;return 0;
}
int ORB_pattern
[256 * 4] = {8, -3, 9, 5,4, 2, 7, -12,-11, 9, -8, 2,7, -12, 12, -13,2, -13, 2, 12,1, -7, 1, 6,-2, -10, -2, -4,-13, -13, -11, -8,-13, -3, -12, -9,10, 4, 11, 9,-13, -8, -8, -9,-11, 7, -9, 12,7, 7, 12, 6,-4, -5, -3, 0,-13, 2, -12, -3,-9, 0, -7, 5,12, -6, 12, -1,-3, 6, -2, 12,-6, -13, -4, -8,11, -13, 12, -8,4, 7, 5, 1,5, -3, 10, -3,3, -7, 6, 12,-8, -7, -6, -2,-2, 11, -1, -10,-13, 12, -8, 10,-7, 3, -5, -3,-4, 2, -3, 7,-10, -12, -6, 11,5, -12, 6, -7,5, -6, 7, -1,1, 0, 4, -5,9, 11, 11, -13,4, 7, 4, 12,2, -1, 4, 4,-4, -12, -2, 7,-8, -5, -7, -10,4, 11, 9, 12,0, -8, 1, -13,-13, -2, -8, 2,-3, -2, -2, 3,-6, 9, -4, -9,8, 12, 10, 7,0, 9, 1, 3,7, -5, 11, -10,-13, -6, -11, 0,10, 7, 12, 1,-6, -3, -6, 12,10, -9, 12, -4,-13, 8, -8, -12,-13, 0, -8, -4,3, 3, 7, 8,5, 7, 10, -7,-1, 7, 1, -12,3, -10, 5, 6,2, -4, 3, -10,-13, 0, -13, 5,-13, -7, -12, 12,-13, 3, -11, 8,-7, 12, -4, 7,6, -10, 12, 8,-9, -1, -7, -6,-2, -5, 0, 12,-12, 5, -7, 5,3, -10, 8, -13,-7, -7, -4, 5,-3, -2, -1, -7,2, 9, 5, -11,-11, -13, -5, -13,-1, 6, 0, -1,5, -3, 5, 2,-4, -13, -4, 12,-9, -6, -9, 6,-12, -10, -8, -4,10, 2, 12, -3,7, 12, 12, 12,-7, -13, -6, 5,-4, 9, -3, 4,7, -1, 12, 2,-7, 6, -5, 1,-13, 11, -12, 5,-3, 7, -2, -6,7, -8, 12, -7,-13, -7, -11, -12,1, -3, 12, 12,2, -6, 3, 0,-4, 3, -2, -13,-1, -13, 1, 9,7, 1, 8, -6,1, -1, 3, 12,9, 1, 12, 6,-1, -9, -1, 3,-13, -13, -10, 5,7, 7, 10, 12,12, -5, 12, 9,6, 3, 7, 11,5, -13, 6, 10,2, -12, 2, 3,3, 8, 4, -6,2, 6, 12, -13,9, -12, 10, 3,-8, 4, -7, 9,-11, 12, -4, -6,1, 12, 2, -8,6, -9, 7, -4,2, 3, 3, -2,6, 3, 11, 0,3, -3, 8, -8,7, 8, 9, 3,-11, -5, -6, -4,-10, 11, -5, 10,-5, -8, -3, 12,-10, 5, -9, 0,8, -1, 12, -6,4, -6, 6, -11,-10, 12, -8, 7,4, -2, 6, 7,-2, 0, -2, 12,-5, -8, -5, 2,7, -6, 10, 12,-9, -13, -8, -8,-5, -13, -5, -2,8, -8, 9, -13,-9, -11, -9, 0,1, -8, 1, -2,7, -4, 9, 1,-2, 1, -1, -4,11, -6, 12, -11,-12, -9, -6, 4,3, 7, 7, 12,5, 5, 10, 8,0, -4, 2, 8,-9, 12, -5, -13,0, 7, 2, 12,-1, 2, 1, 7,5, 11, 7, -9,3, 5, 6, -8,-13, -4, -8, 9,-5, 9, -3, -3,-4, -7, -3, -12,6, 5, 8, 0,-7, 6, -6, 12,-13, 6, -5, -2,1, -10, 3, 10,4, 1, 8, -4,-2, -2, 2, -13,2, -12, 12, 12,-2, -13, 0, -6,4, 1, 9, 3,-6, -10, -3, -5,-3, -13, -1, 1,7, 5, 12, -11,4, -2, 5, -7,-13, 9, -9, -5,7, 1, 8, 6,7, -8, 7, 6,-7, -4, -7, 1,-8, 11, -7, -8,-13, 6, -12, -8,2, 4, 3, 9,10, -5, 12, 3,-6, -5, -6, 7,8, -3, 9, -8,2, -12, 2, 8,-11, -2, -10, 3,-12, -13, -7, -9,-11, 0, -10, -5,5, -3, 11, 8,-2, -13, -1, 12,-1, -8, 0, 9,-13, -11, -12, -5,-10, -2, -10, 11,-3, 9, -2, -13,2, -3, 3, 2,-9, -13, -4, 0,-4, 6, -3, -10,-4, 12, -2, -7,-6, -11, -4, 9,6, -3, 6, 11,-13, 11, -5, 5,11, 11, 12, 6,7, -5, 12, -2,-1, 12, 0, 7,-4, -8, -3, -2,-7, 1, -6, 7,-13, -12, -8, -13,-7, -2, -6, -8,-8, 5, -6, -9,-5, -1, -4, 5,-13, 7, -8, 10,1, 5, 5, -13,1, 0, 10, -13,9, 12, 10, -1,5, -8, 10, -9,-1, 11, 1, -13,-9, -3, -6, 2,-1, -10, 1, 12,-13, 1, -8, -10,8, -11, 10, -6,2, -13, 3, -6,7, -13, 12, -9,-10, -10, -5, -7,-10, -8, -8, -13,4, -6, 8, 5,3, 12, 8, -13,-4, 2, -3, -3,5, -13, 10, -12,4, -13, 5, -1,-9, 9, -4, 3,0, 3, 3, -9,-12, 1, -6, 1,3, 2, 4, -8,-10, -10, -10, 9,8, -13, 12, 12,-8, -12, -6, -5,2, 2, 3, 7,10, 6, 11, -8,6, 8, 8, -12,-7, 10, -6, 5,-3, -9, -3, 9,-1, -13, -1, 5,-3, -7, -3, 4,-8, -2, -8, 3,4, 2, 12, 12,2, -5, 3, 11,6, -9, 11, -13,3, -1, 7, 12,11, -1, 12, 4,-3, 0, -3, 6,4, -11, 4, 12,2, -4, 2, 1,-10, -6, -8, 1,-13, 7, -11, 1,-13, 12, -11, -13,6, 0, 11, -13,0, -1, 1, 4,-13, 3, -9, -2,-9, 8, -6, -3,-13, -6, -8, -2,5, -9, 8, 10,2, 7, 3, -9,-1, -6, -1, -1,9, 5, 11, -2,11, -3, 12, -8,3, 0, 3, 5,-1, 4, 0, 10,3, -6, 4, 5,-13, 0, -10, 5,5, 8, 12, 11,8, 9, 9, -6,7, -4, 8, -12,-10, 4, -10, 9,7, 3, 12, 4,9, -7, 10, -2,7, 0, 12, -2,-1, -6, 0, -11
};
void ComputeORB (const cv
::Mat
&img
, vector
<cv
::KeyPoint
> &keypoints
, vector
<DescType
> &descriptors
) {const int half_patch_size
= 8;const int half_boundary
= 16;int bad_points
= 0;for (auto &kp
: keypoints
) { if (kp
.pt
.x
< half_boundary
|| kp
.pt
.y
< half_boundary
||kp
.pt
.x
>= img
.cols
- half_boundary
|| kp
.pt
.y
>= img
.rows
- half_boundary
) {bad_points
++;descriptors
.push_back({});continue;}float m01
= 0, m10
= 0;for (int dx
= -half_patch_size
; dx
< half_patch_size
; ++dx
) {for (int dy
= -half_patch_size
; dy
< half_patch_size
; ++dy
) {uchar pixel
= img
.at
<uchar
>(kp
.pt
.y
+ dy
, kp
.pt
.x
+ dx
);m10
+= dx
* pixel
;m01
+= dy
* pixel
;}}float m_sqrt
= sqrt(m01
* m01
+ m10
* m10
) + 1e-18;float sin_theta
= m01
/ m_sqrt
;float cos_theta
= m10
/ m_sqrt
;DescType
desc(8, 0);for (int i
= 0; i
< 8; i
++) {uint32_t d
= 0;for (int k
= 0; k
< 32; k
++) {int idx_pq
= i
* 32 + k
;cv
::Point2f
p(ORB_pattern
[idx_pq
* 4], ORB_pattern
[idx_pq
* 4 + 1]);cv
::Point2f
q(ORB_pattern
[idx_pq
* 4 + 2], ORB_pattern
[idx_pq
* 4 + 3]);cv
::Point2f pp
= cv
::Point2f(cos_theta
* p
.x
- sin_theta
* p
.y
,sin_theta
* p
.x
+ cos_theta
* p
.y
) + kp
.pt
;cv
::Point2f qq
= cv
::Point2f(cos_theta
* q
.x
- sin_theta
* q
.y
,sin_theta
* q
.y
+ cos_theta
* q
.y
) + kp
.pt
;if (img
.at
<uchar
>(pp
.y
, pp
.x
) < img
.at
<uchar
>(qq
.y
, qq
.x
)) {d
|= 1 << k
;}}desc
[i
] = d
;}descriptors
.push_back(desc
);}cout
<< " bad/total: " << bad_points
<< " / " << keypoints
.size() << endl
;
}void BfMatch(const vector
<DescType
> &desc1
, const vector
<DescType
> &desc2
, vector
<cv
::DMatch
> &matches
) {const int d_max
= 20;for(size_t i1
= 0; i1
< desc1
.size(); ++i1
){if (desc1
[i1
].empty()) continue;cv
::DMatch m
{int(i1
), 0, 256};for (size_t i2
= 0; i2
< desc2
.size(); ++i2
){if (desc2
[i2
].empty()) continue;int distance
= 0;for (int k
= 0; k
< 8; k
++){distance
+= _mm_popcnt_u32(desc1
[i1
][k
] ^ desc2
[i2
][k
]);}if (distance
< d_max
&& distance
< m
.distance
){m
.distance
= distance
;m
.trainIdx
= i2
;}}if (m
.distance
< d_max
){matches
.push_back(m
);}}
}
總結
以上是生活随笔為你收集整理的orb 算法源码实现的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。