大家好,欢迎来到IT知识分享网。
ORB的全称是ORiented Brief,采用FAST(features from accelerated segment test)算法来检测特征点。与Brisk,AKAZE类似,ORB也分两部分,即特征点提取和特征点描述。特征提取是由FAST(Features from Accelerated Segment Test)算法发展来的,它基于特征点周围的图像灰度值,检测候选特征点周围一圈的像素值,如果候选点周围领域内有足够多的像素点与该候选点的灰度值差别够大,则认为该候选点为一个特征点。而特征点描述是根据BRIEF(Binary Robust Independent Elementary Features)特征描述算法改进的。
FAST
ORB
算法解析
准备的两张不同视角的图片
1.jpg
2.jpg
1、读取图像(灰度图)
cv::Mat first_image = cv::imread(argv[1], 0); cv::Mat second_image = cv::imread(argv[2], 0);
2、使用FAST算法检测出特征点
pt:关键点的位置 size:关键点的范围 angle:关键点角度 response:能够给某个关键点更强烈响应的检测器,有时能够被理解为特性实际存在的概率 octave:标示了关键点被找到的层级,总是希望在相同的层级找到对应的关键点 class_id:标示关键点来自于哪一个目标
DescType表示的是vector<unit32_t>,每个元素是32位(BRIEF算法)
vector<cv::KeyPoint> keypoints1; cv::FAST(first_image, keypoints1, 40); vector<DescType> descriptor1; ComputeORB(first_image, keypoints1, descriptor1);
3、选出描述子
ComputeORB用于计算图像中的 ORB(Oriented FAST and Rotated BRIEF)特征点及其描述子,具体过程为:
输入参数: img: 输入的灰度图像,类型为 cv::Mat。 keypoints: 存储检测到的关键点的向量。 descriptors: 存储与每个关键点对应的描述子的向量。 边界检查: 函数首先定义了一些常量,如 half_patch_size 和 half_boundary。这些值用于确保计算关键点描述子时不会越界。 对于每个关键点,如果其坐标超出了图像的有效范围(即距离边界小于 half_boundary),则将其视为无效(bad points),并在描述子中添加一个空的描述子。 计算中心矩: 对于有效的关键点,函数计算其周围区域的第一中心矩 m10 和 m01,这两个值用于后续计算关键点的方向。 计算方向: 根据 m01 和 m10 的值,计算出关键点的方向(角度),通过归一化得到正弦和余弦值 (sin_theta 和 cos_theta)。 计算描述子: 函数初始化了一个大小为 8 的描述子向量,每个元素对应 8 个方向。 在每个方向上,使用 32 个采样点来比较关键点周围的像素值。 通过旋转采样点坐标以匹配关键点的方向,判断相应的像素值,并根据比较结果生成二进制描述子。 存储描述子: 将计算得到的描述子添加到 descriptors 向量中。
注:灰度质心法
当我们在图像中选中一个点进行观测(我们可以以水平方向为x轴),此时将图像进行旋转一个角度,观测点跟随图像进行旋转。旋转后的观测点在原坐标系下已经丢失,因此我们想要观测点跟随图像旋转后的坐标。在灰度图中,图像的每个像素被表示为0~255的值,将它看成是此像素的质量(显然每个像素的质量是不同的),我们可以用灰度质心法求出这片区域的质心。
既然对图像进行旋转,必然需要用到二维旋转矩阵:
//ORB_pattern是自定义的一个256*4的数组,在计算同一张图片的两个坐标点像素时会使用到 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;//FAST检测出的特征点中超出边界范围的点 //保证所有计算都不会超限 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; } //求出m10和m01 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; } } // angle should be arc tan(m01/m10); 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++){
//corresponding to 8 different directions 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]); //rotate with theta 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 = cv::Point2f(cos_theta * q.x - sin_theta * q.y, sin_theta * q.x + cos_theta * q.y) + kp.pt; //如果pp点的亮度小于点的亮度,将d的第k位置为1,最终形成32位的二进制串 if(img.at<uchar>(pp.y, pp.x) < img.at<uchar>(.y, .x)){
d |= 1 << k; } } desc[i] = d; } descriptors.push_back(desc); } cout << "bad/total: " << bad_points << "/" << keypoints.size() <<endl; }
4、计算匹配的特征点
Dmatch对象保存的是上一步计算出的两个descriptors匹配成功的结果,
vector<cv::DMatch> matches; BfMatch(descriptor1, descriptor2, matches);
cv::DMatch参数说明: queryIdx : 查询点的索引(当前要寻找匹配结果的点在它所在图片上的索引) trainIdx : 被查询到的点的索引(存储库中的点的在存储库上的索引) distance: 为两个描述子之间的距离
void BfMatch(const vector<DescType> &desc1, const vector<DescType> &desc2, vector<cv::DMatch> &matches) {
const int d_max = 40; for (size_t i1=0; i1 < desc1.size(); ++i1) {
//以descriptor1位基准,按顺序与descriptor2进行匹配 if(desc1[i1].empty()) continue; cv::DMatch m{
(int)i1, 0, 256}; //distance初始化为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++) {
//calculate the number of 1s in the 32-bit integer passed in(hamming weight) distance += _mm_popcnt_u32(desc1[i1][k] ^ desc2[i2][k]);//简单说就是两个32位2进制串中有多少位是相同的 } if(distance < d_max && distance < m.distance) {
m.distance = distance; m.trainIdx = i2; } } if( m.distance < d_max) {
matches.push_back(m); } } }
5、画出匹配的特征图
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);
完整代码
#include <opencv2/opencv.hpp> #include <string> #include <nmmintrin.h> #include <chrono> using namespace std; // 32 bit unsigned int, will have 8, 8x32=256 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) {
if (argc != 3) {
cout << "usage: feature_extraction img1 img2" << endl; return 1; } //-- 读取图像 cv::Mat first_image = cv::imread(argv[1], 0); cv::Mat second_image = cv::imread(argv[2], 0); assert(first_image.data != nullptr && second_image.data != nullptr); //detect FAST keypoints1 using threshold=40 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; vector<DescType> descriptor2; cv::FAST(second_image, keypoints2, 40); ComputeORB(second_image, keypoints2, descriptor2); chrono::steady_clock::time_point t2 = chrono::steady_clock::now(); chrono::duration<double> time_used = chrono::duration_cast<chrono::duration<double>>(t2 - t1); cout << "extract ORB cost = " << time_used.count() << " seconds. " << endl; // find matches vector<cv::DMatch> matches; t1 = chrono::steady_clock::now(); BfMatch(descriptor1, descriptor2, matches); t2 = chrono::steady_clock::now(); time_used = chrono::duration_cast<chrono::duration<double>>(t2 - t1); cout << "match ORB cost = " << 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); } int ORB_pattern[256 * 4] = {
8, -3, 9, 5/*mean (0), correlation (0)*/, 4, 2, 7, -12/*mean (1.12461e-05), correlation (0.0)*/, -11, 9, -8, 2/*mean (3.37382e-05), correlation (0.0)*/, 7, -12, 12, -13/*mean (5.62303e-05), correlation (0.0)*/, 2, -13, 2, 12/*mean (0.000), correlation (0.085099)*/, 1, -7, 1, 6/*mean (0.000), correlation (0.0)*/, -2, -10, -2, -4/*mean (0.0), correlation (0.0)*/, -13, -13, -11, -8/*mean (0.0), correlation (0.0)*/, -13, -3, -12, -9/*mean (0.), correlation (0.099849)*/, 10, 4, 11, 9/*mean (0.), correlation (0.093285)*/, -13, -8, -8, -9/*mean (0.), correlation (0.0)*/, -11, 7, -9, 12/*mean (0.21561), correlation (0.0)*/, 7, 7, 12, 6/*mean (0.), correlation (0.)*/, -4, -5, -3, 0/*mean (0.), correlation (0.)*/, -13, 2, -12, -3/*mean (0.00), correlation (0.)*/, -9, 0, -7, 5/*mean (0.), correlation (0.)*/, 12, -6, 12, -1/*mean (0.0), correlation (0.16689)*/, -3, 6, -2, 12/*mean (0.), correlation (0.)*/, -6, -13, -4, -8/*mean (0.), correlation (0.)*/, 11, -13, 12, -8/*mean (0.), correlation (0.)*/, 4, 7, 5, 1/*mean (0.), correlation (0.)*/, 5, -3, 10, -3/*mean (0.), correlation (0.)*/, 3, -7, 6, 12/*mean (0.0), correlation (0.)*/, -8, -7, -6, -2/*mean (0.0), correlation (0.)*/, -2, 11, -1, -10/*mean (0.), correlation (0.20866)*/, -13, 12, -8, 10/*mean (0.14783), correlation (0.)*/, -7, 3, -5, -3/*mean (0.), correlation (0.)*/, -4, 2, -3, 7/*mean (0.), correlation (0.21384)*/, -10, -12, -6, 11/*mean (0.14865), correlation (0.23571)*/, 5, -12, 6, -7/*mean (0.), correlation (0.23324)*/, 5, -6, 7, -1/*mean (0.), correlation (0.23389)*/, 1, 0, 4, -5/*mean (0.), correlation (0.)*/, 9, 11, 11, -13/*mean (0.00), correlation (0.)*/, 4, 7, 4, 12/*mean (0.), correlation (0.)*/, 2, -1, 4, 4/*mean (0.), correlation (0.)*/, -4, -12, -2, 7/*mean (0.), correlation (0.)*/, -8, -5, -7, -10/*mean (0.), correlation (0.23901)*/, 4, 11, 9, 12/*mean (0.), correlation (0.)*/, 0, -8, 1, -13/*mean (0.0), correlation (0.)*/, -13, -2, -8, 2/*mean (0.), correlation (0.28065)*/, -3, -2, -2, 3/*mean (0.), correlation (0.)*/, -6, 9, -4, -9/*mean (0.), correlation (0.)*/, 8, 12, 10, 7/*mean (0.), correlation (0.)*/, 0, 9, 1, 3/*mean (0.), correlation (0.)*/, 7, -5, 11, -10/*mean (0.00), correlation (0.)*/, -13, -6, -11, 0/*mean (0.0), correlation (0.)*/, 10, 7, 12, 1/*mean (0.), correlation (0.31089)*/, -6, -3, -6, 12/*mean (0.), correlation (0.)*/, 10, -9, 12, -4/*mean (0.), correlation (0.)*/, -13, 8, -8, -12/*mean (0.), correlation (0.)*/, -13, 0, -8, -4/*mean (0.), correlation (0.)*/, 3, 3, 7, 8/*mean (0.), correlation (0.)*/, 5, 7, 10, -7/*mean (0.), correlation (0.)*/, -1, 7, 1, -12/*mean (0.), correlation (0.)*/, 3, -10, 5, 6/*mean (0.), correlation (0.)*/, 2, -4, 3, -10/*mean (0.00), correlation (0.)*/, -13, 0, -13, 5/*mean (0.0), correlation (0.)*/, -13, -7, -12, 12/*mean (0.), correlation (0.)*/, -13, 3, -11, 8/*mean (0.), correlation (0.)*/, -7, 12, -4, 7/*mean (0.), correlation (0.)*/, 6, -10, 12, 8/*mean (0.), correlation (0.)*/, -9, -1, -7, -6/*mean (0.), correlation (0.33312)*/, -2, -5, 0, 12/*mean (0.), correlation (0.)*/, -12, 5, -7, 5/*mean (0.), correlation (0.)*/, 3, -10, 8, -13/*mean (0.), correlation (0.34504)*/, -7, -7, -4, 5/*mean (0.), correlation (0.)*/, -3, -2, -1, -7/*mean (0.), correlation (0.)*/, 2, 9, 5, -11/*mean (0.), correlation (0.34145)*/, -11, -13, -5, -13/*mean (0.), correlation (0.)*/, -1, 6, 0, -1/*mean (0.), correlation (0.)*/, 5, -3, 5, 2/*mean (0.000), correlation (0.)*/, -4, -13, -4, 12/*mean (0.00), correlation (0.)*/, -9, -6, -9, 6/*mean (0.0), correlation (0.)*/, -12, -10, -8, -4/*mean (0.0), correlation (0.)*/, 10, 2, 12, -3/*mean (0.0), correlation (0.)*/, 7, 12, 12, 12/*mean (0.0), correlation (0.)*/, -7, -13, -6, 5/*mean (0.0), correlation (0.)*/, -4, 9, -3, 4/*mean (0.099865), correlation (0.)*/, 7, -1, 12, 2/*mean (0.), correlation (0.)*/, -7, 6, -5, 1/*mean (0.), correlation (0.)*/, -13, 11, -12, 5/*mean (0.), correlation (0.)*/, -3, 7, -2, -6/*mean (0.), correlation (0.)*/, 7, -8, 12, -7/*mean (0.), correlation (0.)*/, -13, -7, -11, -12/*mean (0.), correlation (0.)*/, 1, -3, 12, 12/*mean (0.), correlation (0.)*/, 2, -6, 3, 0/*mean (0.), correlation (0.)*/, -4, 3, -2, -13/*mean (0.), correlation (0.)*/, -1, -13, 1, 9/*mean (0.), correlation (0.)*/, 7, 1, 8, -6/*mean (0.000), correlation (0.)*/, 1, -1, 3, 12/*mean (0.00), correlation (0.)*/, 9, 1, 12, 6/*mean (0.0), correlation (0.)*/, -1, -9, -1, 3/*mean (0.0), correlation (0.)*/, -13, -13, -10, 5/*mean (0.0), correlation (0.)*/, 7, 7, 10, 12/*mean (0.0), correlation (0.)*/, 12, -5, 12, 9/*mean (0.0), correlation (0.)*/, 6, 3, 7, 11/*mean (0.1074), correlation (0.)*/, 5, -13, 6, 10/*mean (0.), correlation (0.)*/, 2, -12, 2, 3/*mean (0.), correlation (0.)*/, 3, 8, 4, -6/*mean (0.), correlation (0.)*/, 2, 6, 12, -13/*mean (0.), correlation (0.)*/, 9, -12, 10, 3/*mean (0.), correlation (0.41296)*/, -8, 4, -7, 9/*mean (0.), correlation (0.)*/, -11, 12, -4, -6/*mean (0.), correlation (0.)*/, 1, 12, 2, -8/*mean (0.), correlation (0.)*/, 6, -9, 7, -4/*mean (0.), correlation (0.)*/, 2, 3, 3, -2/*mean (0.), correlation (0.)*/, 6, 3, 11, 0/*mean (0.), correlation (0.)*/, 3, -3, 8, -8/*mean (0.), correlation (0.)*/, 7, 8, 9, 3/*mean (0.), correlation (0.)*/, -11, -5, -6, -4/*mean (0.), correlation (0.)*/, -10, 11, -5, 10/*mean (0.), correlation (0.)*/, -5, -8, -3, 12/*mean (0.24774), correlation (0.)*/, -10, 5, -9, 0/*mean (0.00), correlation (0.)*/, 8, -1, 12, -6/*mean (0.0), correlation (0.)*/, 4, -6, 6, -11/*mean (0.0), correlation (0.)*/, -10, 12, -8, 7/*mean (0.0), correlation (0.)*/, 4, -2, 6, 7/*mean (0.050641), correlation (0.)*/, -2, 0, -2, 12/*mean (0.0), correlation (0.44338)*/, -5, -8, -5, 2/*mean (0.0), correlation (0.)*/, 7, -6, 10, 12/*mean (0.0), correlation (0.)*/, -9, -13, -8, -8/*mean (0.0), correlation (0.)*/, -5, -13, -5, -2/*mean (0.), correlation (0.)*/, 8, -8, 9, -13/*mean (0.), correlation (0.)*/, -9, -11, -9, 0/*mean (0.), correlation (0.)*/, 1, -8, 1, -2/*mean (0.), correlation (0.)*/, 7, -4, 9, 1/*mean (0.), correlation (0.454)*/, -2, 1, -1, -4/*mean (0.), correlation (0.)*/, 11, -6, 12, -11/*mean (0.), correlation (0.)*/, -12, -9, -6, 4/*mean (0.), correlation (0.)*/, 3, 7, 7, 12/*mean (0.), correlation (0.)*/, 5, 5, 10, 8/*mean (0.), correlation (0.)*/, 0, -4, 2, 8/*mean (0.), correlation (0.)*/, -9, 12, -5, -13/*mean (0.), correlation (0.)*/, 0, 7, 2, 12/*mean (0.18312), correlation (0.)*/, -1, 2, 1, 7/*mean (0.), correlation (0.)*/, 5, 11, 7, -9/*mean (0.), correlation (0.)*/, 3, 5, 6, -8/*mean (0.), correlation (0.)*/, -13, -4, -8, 9/*mean (0.), correlation (0.)*/, -5, 9, -3, -3/*mean (0.), correlation (0.)*/, -4, -7, -3, -12/*mean (0.), correlation (0.)*/, 6, 5, 8, 0/*mean (0.1972), correlation (0.)*/, -7, 6, -6, 12/*mean (0.), correlation (0.)*/, -13, 6, -5, -2/*mean (0.), correlation (0.)*/, 1, -10, 3, 10/*mean (0.), correlation (0.)*/, 4, 1, 8, -4/*mean (0.), correlation (0.)*/, -2, -2, 2, -13/*mean (0.), correlation (0.)*/, 2, -12, 12, 12/*mean (0.), correlation (0.)*/, -2, -13, 0, -6/*mean (0.), correlation (0.)*/, 4, 1, 9, 3/*mean (0.23962), correlation (0.)*/, -6, -10, -3, -5/*mean (0.), correlation (0.)*/, -3, -13, -1, 1/*mean (0.), correlation (0.)*/, 7, 5, 12, -11/*mean (0.00), correlation (0.)*/, 4, -2, 5, -7/*mean (0.00), correlation (0.)*/, -13, 9, -9, -5/*mean (0.00), correlation (0.)*/, 7, 1, 8, 6/*mean (0.0), correlation (0.)*/, 7, -8, 7, 6/*mean (0.0), correlation (0.)*/, -7, -4, -7, 1/*mean (0.0), correlation (0.)*/, -8, 11, -7, -8/*mean (0.0), correlation (0.)*/, -13, 6, -12, -8/*mean (0.0), correlation (0.)*/, 2, 4, 3, 9/*mean (0.0), correlation (0.)*/, 10, -5, 12, 3/*mean (0.0), correlation (0.)*/, -6, -5, -6, 7/*mean (0.0), correlation (0.)*/, 8, -3, 9, -8/*mean (0.0), correlation (0.)*/, 2, -12, 2, 8/*mean (0.0), correlation (0.)*/, -11, -2, -10, 3/*mean (0.0), correlation (0.)*/, -12, -13, -7, -9/*mean (0.0), correlation (0.)*/, -11, 0, -10, -5/*mean (0.0), correlation (0.)*/, 5, -3, 11, 8/*mean (0.0), correlation (0.)*/, -2, -13, -1, 12/*mean (0.), correlation (0.48941)*/, -1, -8, 0, 9/*mean (0.), correlation (0.)*/, -13, -11, -12, -5/*mean (0.), correlation (0.)*/, -10, -2, -10, 11/*mean (0.), correlation (0.)*/, -3, 9, -2, -13/*mean (0.), correlation (0.)*/, 2, -3, 3, 2/*mean (0.14892), correlation (0.)*/, -9, -13, -4, 0/*mean (0.), correlation (0.)*/, -4, 6, -3, -10/*mean (0.), correlation (0.)*/, -4, 12, -2, -7/*mean (0.), correlation (0.)*/, -6, -11, -4, 9/*mean (0.15749), correlation (0.)*/, 6, -3, 6, 11/*mean (0.), correlation (0.)*/, -13, 11, -5, 5/*mean (0.), correlation (0.)*/, 11, 11, 12, 6/*mean (0.16652), correlation (0.)*/, 7, -5, 12, -2/*mean (0.), correlation (0.)*/, -1, 12, 0, 7/*mean (0.), correlation (0.)*/, -4, -8, -3, -2/*mean (0.), correlation (0.)*/, -7, 1, -6, 7/*mean (0.175), correlation (0.)*/, -13, -12, -8, -13/*mean (0.), correlation (0.)*/, -7, -2, -6, -8/*mean (0.), correlation (0.)*/, -8, 5, -6, -9/*mean (0.), correlation (0.)*/, -5, -1, -4, 5/*mean (0.), correlation (0.)*/, -13, 7, -8, 10/*mean (0.), correlation (0.)*/, 1, 5, 5, -13/*mean (0.19973), correlation (0.)*/, 1, 0, 10, -13/*mean (0.), correlation (0.49873)*/, 9, 12, 10, -1/*mean (0.), correlation (0.49063)*/, 5, -8, 10, -9/*mean (0.), correlation (0.)*/, -1, 11, 1, -13/*mean (0.212), correlation (0.)*/, -9, -3, -6, 2/*mean (0.), correlation (0.)*/, -1, -10, 1, 12/*mean (0.), correlation (0.)*/, -13, 1, -8, -10/*mean (0.21327), correlation (0.)*/, 8, -11, 10, -6/*mean (0.), correlation (0.)*/, 2, -13, 3, -6/*mean (0.), correlation (0.50287)*/, 7, -13, 12, -9/*mean (0.), correlation (0.)*/, -10, -10, -5, -7/*mean (0.), correlation (0.)*/, -10, -8, -8, -13/*mean (0.), correlation (0.)*/, 4, -6, 8, 5/*mean (0.22906), correlation (0.)*/, 3, 12, 8, -13/*mean (0.), correlation (0.)*/, -4, 2, -3, -3/*mean (0.), correlation (0.)*/, 5, -13, 10, -12/*mean (0.), correlation (0.)*/, 4, -13, 5, -1/*mean (0.), correlation (0.)*/, -9, 9, -4, 3/*mean (0.), correlation (0.)*/, 0, 3, 3, -9/*mean (0.24314), correlation (0.)*/, -12, 1, -6, 1/*mean (0.), correlation (0.)*/, 3, 2, 4, -8/*mean (0.00), correlation (0.)*/, -10, -10, -10, 9/*mean (0.00), correlation (0.54297)*/, 8, -13, 12, 12/*mean (0.0034413), correlation (0.)*/, -8, -12, -6, -5/*mean (0.003565), correlation (0.)*/, 2, 2, 3, 7/*mean (0.00), correlation (0.55285)*/, 10, 6, 11, -8/*mean (0.00), correlation (0.)*/, 6, 8, 8, -12/*mean (0.0), correlation (0.)*/, -7, 10, -6, 5/*mean (0.0), correlation (0.)*/, -3, -9, -3, 9/*mean (0.0), correlation (0.)*/, -1, -13, -1, 5/*mean (0.0), correlation (0.)*/, -3, -7, -3, 4/*mean (0.0), correlation (0.)*/, -8, -2, -8, 3/*mean (0.017049), correlation (0.55461)*/, 4, 2, 12, 12/*mean (0.01778), correlation (0.)*/, 2, -5, 3, 11/*mean (0.0), correlation (0.)*/, 6, -9, 11, -13/*mean (0.029161), correlation (0.)*/, 3, -1, 7, 12/*mean (0.0), correlation (0.)*/, 11, -1, 12, 4/*mean (0.0), correlation (0.)*/, -3, 0, -3, 6/*mean (0.0), correlation (0.)*/, 4, -11, 4, 12/*mean (0.0), correlation (0.)*/, 2, -4, 2, 1/*mean (0.0), correlation (0.)*/, -10, -6, -8, 1/*mean (0.0), correlation (0.)*/, -13, 7, -11, 1/*mean (0.0), correlation (0.)*/, -13, 12, -11, -13/*mean (0.0), correlation (0.55383)*/, 6, 0, 11, -13/*mean (0.065126), correlation (0.)*/, 0, -1, 1, 4/*mean (0.074224), correlation (0.)*/, -13, 3, -9, -2/*mean (0.0), correlation (0.)*/, -9, 8, -6, -3/*mean (0.0), correlation (0.)*/, -13, -6, -8, -2/*mean (0.0), correlation (0.)*/, 5, -9, 8, 10/*mean (0.0), correlation (0.)*/, 2, 7, 3, -9/*mean (0.0), correlation (0.)*/, -1, -6, -1, -1/*mean (0.10045), correlation (0.)*/, 9, 5, 11, -2/*mean (0.), correlation (0.)*/, 11, -3, 12, -8/*mean (0.), correlation (0.)*/, 3, 0, 3, 5/*mean (0.), correlation (0.)*/, -1, 4, 0, 10/*mean (0.), correlation (0.)*/, 3, -6, 4, 5/*mean (0.), correlation (0.)*/, -13, 0, -10, 5/*mean (0.), correlation (0.)*/, 5, 8, 12, 11/*mean (0.), correlation (0.)*/, 8, 9, 9, -6/*mean (0.), correlation (0.)*/, 7, -4, 8, -12/*mean (0.), correlation (0.)*/, -10, 4, -10, 9/*mean (0.12094), correlation (0.)*/, 7, 3, 12, 4/*mean (0.), correlation (0.)*/, 9, -7, 10, -2/*mean (0.), correlation (0.)*/, 7, 0, 12, -2/*mean (0.), correlation (0.)*/, -1, -6, 0, -11/*mean (0.), correlation (0.)*/ }; 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; } } // angle should be arc tan(m01/m10); 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++){
//corresponding to 8 different directions 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]); //rotate with theta 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 = cv::Point2f(cos_theta * q.x - sin_theta * q.y, sin_theta * q.x + cos_theta * q.y) + kp.pt; if(img.at<uchar>(pp.y, pp.x) < img.at<uchar>(.y, .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 = 40; 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++) {
//calculate the number of 1s in the 32-bit integer passed in(hamming weight) 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); } } }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/156061.html