ORB算法中计算FAST角点的主方向 IC_Angle(C++ 转C)

ORB算法中计算FAST角点的主方向 IC_Angle(C++ 转C)

1.openCv库中 IC_Angle源码

static float IC_Angle(const Mat& image, const int half_k, Point2f pt,  
                      const vector<int> & u_max)  
{  
    int m_01 = 0, m_10 = 0;  
  
    const uchar* center = &image.at<uchar> (cvRound(pt.y), cvRound(pt.x));  
  
    // Treat the center line differently, v=0  
    for (int u = -half_k; u <= half_k; ++u)  
        m_10 += u * center[u];  
  
    // Go line by line in the circular patch  
    int step = (int)image.step1();  
    
	// Treat the center line differently, v=0
    for (int v = 1; v <= half_k; ++v)  
    {  
        // Proceed over the two lines  上下和左右两条线同时计算
        int v_sum = 0;  
        int d = u_max[v];  
        for (int u = -d; u <= d; ++u)  
        {  
            int val_plus = center[u + v*step], val_minus = center[u - v*step];  
            //计算上下的时候是有符号的,所以这边是减
            v_sum += (val_plus - val_minus);  
            //这边加是由于u已经确定好了符号
            m_10 += u * (val_plus + val_minus);  
        }  
        m_01 += v * v_sum;  
    }  
  
    return fastAtan2((float)m_01, (float)m_10);  
}  

2.C实现+测试(读取图片)

这一部分有所改动,ORB在计算BRIEF描述子时建立的坐标系是以关键点为圆心,以关键点和取点区域的形心的连线为X轴建立2维坐标系。
这里C实现,不再是圆,而是以关键点为中心,左8右7,16*16的正方形。
//#include"stdafx.h" 
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2\imgproc\types_c.h>
#include <math.h>
#include<cstring>
//#include "Ic_Angle_head.h"
//#include <stdlib.h>

using namespace cv;
using namespace std;

typedef struct 
{
	float data[65536];		// 像素值
	int rows, cols;		// 行数和列数

}Img;
typedef  struct 
{
	int x;
	int y;
}my_Point;
float IC_Angle(Img *src, Img* dst, my_Point pt)
{
	float M_00 =0, M_10 = 0, M_01 = 0, Qx, Qy, Angle;
	for (int i = pt.x- 8; i <= pt.x + 7; i++)
	{
		for (int j = pt.y - 8; j <= pt.y + 7; j++)
		{
			M_00 = M_00 + dst->data[i * dst->cols + j];
			M_10 = M_10 + i * dst->data[i * dst->cols + j];
			M_01 = M_01 + j *dst->data[i * dst->cols + j];
		}
	}
	Qx = M_10 / M_00;
	Qy = M_01 / M_00;
	Angle = atan((Qy - pt.y) / (Qx - pt.x))* (180/ 3.1415926);
	cout << Angle << endl;
	return Angle;
}
int main(int argc, char* argv[])
{
	Mat src;
	Mat dst;
	string imgpath = "E:\\C_100_practice\\IC_Angle\\1.jpg";
	//string imgpath = argv[1];
	src = imread(imgpath, 1);
	cvtColor(src, dst, CV_BGR2GRAY);
	//imshow("src", src);
	//imshow("dst",dst);
	Img _src;
	_src.rows = src.rows;
	_src.cols = src.cols;
	for (int i = 0; i < src.rows; i++)
		for (int j = 0; j < src.cols; j++) {
			_src.data[i * src.cols + j] = static_cast<float>(dst.at<uchar>(i, j));
		}
	Img _dst;
	_dst.rows = _src.rows;
	_dst.cols = _src.cols;
	my_Point pt;//设置P点坐标
	pt.x = 10;
	pt.y = 10;
	float res = IC_Angle(&_src, &_dst, pt);

	waitKey(0);
	return 0;
}

3.C实现+测试(随机生成数组)

#include <iostream>
#include <math.h>
#include<cstring>
#include <cstdlib>   ///生成随机数组
#include <ctime>     ///
using namespace std;
void Random(int* a, int n, int l, int r)//生成范围在l~r的随机数 
{
	srand(time(0));  //设置时间种子
	for (int i = 0; i < n; i++) {
		a[i] = rand() % (r - l + 1) + l;//生成区间r~l的随机数 
	}
}
void Print(int* a, int n)
{
	for (int i = 0; i < n; i++)
		cout << a[i] << " ";
	cout << endl;
}
int arrSum(int* arr, int len)//M00
{ 
	int i = 0, sum = 0;
	for (i = 0; i < len; i++)
		sum += arr[i];
	return sum;
}
int arrSum_x(int* arr, int len)// M10
{
	int i = 0, j = 0,sum = 0;
	for (i = 0; i < len; i++)
	{
		for (j = 0;j < len; j++) {
			sum += i * arr[i*16+j];
		}		
	}		
	return sum;
}
int arrSum_y(int* arr, int len)// M10
{
	int i = 0, j = 0, sum = 0;
	for (i = 0; i < len; i++)
	{
		for (j = 0; j< len; j++) {
			sum += j * arr[i * 16 + j];
		}
	}
	return sum;
}

int main()
{
	int a[256];//数组元素的个数,即生成随机数的个数、 模拟一个16*16 的图片 所以生成256 个数
	Random(a, 256, 1, 10);//生成随机数的通常范围为0~32767,这里通过取模控制取值为0~10 
	Print(a, 256);
	my_Point pt;//设置P点坐标
	pt.x = 7;
	pt.y = 7;
	float M_00 = 0, M_10 = 0, M_01 = 0, Qx, Qy, Angle;
	for (int i = 0; i < 16; i++)
	{
		for (int j = 0; j <16; j++)
		{
			M_00 = M_00 + a[i * 16 + j];
			M_10 = M_10 + i * a[i * 16 + j];
			M_01 = M_01 + j * a[i * 16 + j];
		}
	}
	Qx = M_10 / M_00;
	Qy = M_01 / M_00;
	Angle = atan((Qy - pt.y) / (Qx - pt.x)) * (180 / 3.1415926);
	double  I = arrSum(a, 256);
	double  qx = arrSum_x(a, 16)/I;
	double  qy = arrSum_y(a, 16) / I;
	cout << "Qx: " << Qx << endl;
	cout << "Qy: " << Qy << endl;
	cout << "qx: " << qx << endl;
	cout << "qy: " << qy << endl;
	cout << "I: " << I << endl;
	cout << Angle << endl;
	return 0;
}

4.参考阅读

(i) ORB算法解读.
(ii)VS配置OpenCv.注意动态链接库的配置

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页