赵春江的专栏



在嵌入式系统内,对图像进行实时匹配,,这项任务给特征点的检测与描述提出了更高的要求。这不仅要求运算速度快,而且还要求占用更少的内存。

方法性能优异,但它们在实时应用中就力不从心,一个主要的原因就是特征点的描述符结构较复杂,表现形式是第一描述符的维数较多,第二描述符采用浮点型的数据格式。维数多固然可以提高特征点的可区分性,但使描述符的生成和特征点的匹配的效率降低,另一方面采用浮点型的数据格式也必然增加了更大的内存开销。因此改进描述符的形式就成为提高特征点匹配的一个重要手段。

“1”的数量越多,两个描述符的相似性越差。

BinaryRobust Independent Elementary Features)方法。该方法也是二值位字符串的描述符形式,但描述符的创建更简单,更有效。

nd个像素点对。然后比较像素点对的灰度值:

(1)

i个像素点对的两个像素pi和qi的灰度值。最后把补丁区域内所有点对的比较结果串成一个二值位字符串的形式,从而形成了该特征点的描述符。

B =b0b1…bi…bnd

k =nd / 8)

k就表示为描述符的字节数。

//bytes表示描述符的字节数,即公式3中的k,k只可能为16,32和64,默认为32BriefDescriptorExtractor::BriefDescriptorExtractor(int bytes) :bytes_(bytes), test_fn_(NULL){//根据字节数选择不同的函数,字节数不同,则所需要的像素点对的数量就不同,所以要调用不同的函数switch (bytes){case 16: //128个点对test_fn_ = pixelTests16;break;case 32: //256个点对test_fn_ = pixelTests32;break;case 64: //512个点对test_fn_ = pixelTests64;break;default: //只可能为以上三种情况CV_Error(CV_StsBadArg, "bytes must be 16, 32, or 64");}}

void BriefDescriptorExtractor::computeImpl(const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors) const{// Construct integral image for fast smoothing (box filter)Mat sum; //积分图像矩阵Mat grayImage = image; //输入图像//把输入图像转换为灰度图像if( image.type() != CV_8U ) cvtColor( image, grayImage, CV_BGR2GRAY );///TODO allow the user to pass in a precomputed integral image//if(image.type() == CV_32S)// sum = image;//elseintegral( grayImage, sum, CV_32S); //得到输入图像的积分图像//Remove keypoints very close to the border// PATCH_SIZE = 48;表示补丁区域的边长,KERNEL_SIZE = 9;表示盒状滤波器的边长//根据补丁区域和盒状滤波器的尺寸大小,去掉那些过于靠近图像边界的特征点KeyPointsFilter::runByImageBorder(keypoints, image.size(), PATCH_SIZE/2 + KERNEL_SIZE/2);//描述符矩阵变量清零descriptors = Mat::zeros((int)keypoints.size(), bytes_, CV_8U);//调用test_fn_指向的函数,创建BRIEF描述符test_fn_(sum, keypoints, descriptors);}

函数为进行讲解。

static void pixelTests16(const Mat& sum, const std::vector<KeyPoint>& keypoints, Mat& descriptors){//遍历所有的特征点for (int i = 0; i < (int)keypoints.size(); ++i){uchar* desc = descriptors.ptr(i); //描述符的首地址指针const KeyPoint& pt = keypoints[i]; //特征点的首地址指针#include "generated_16.i" //执行generated_16.i预处理文件}}

函数,它的作用是对点对进行盒状滤波器的平滑处理,我们先给出这个函数:

//sum为积分图像,pt为特征点变量,x和y表示点对中某一个像素相对于特征点的坐标,函数返回滤波的结果inline int smoothedSum(const Mat& sum, const KeyPoint& pt, int y, int x){//盒状滤波器边长的一半static const int HALF_KERNEL = BriefDescriptorExtractor::KERNEL_SIZE / 2;//计算点对中某一个像素的绝对坐标int img_y = (int)(pt.pt.y + 0.5) + y;int img_x = (int)(pt.pt.x + 0.5) + x;//计算以该像素为中心,以KERNEL_SIZE为边长的正方形内所有像素灰度值之和,本质上是均值滤波return sum.at<int>(img_y + HALF_KERNEL + 1, img_x + HALF_KERNEL + 1)- sum.at<int>(img_y + HALF_KERNEL + 1, img_x – HALF_KERNEL)- sum.at<int>(img_y – HALF_KERNEL, img_x + HALF_KERNEL + 1)+ sum.at<int>(img_y – HALF_KERNEL, img_x – HALF_KERNEL);}

始终调整好自己观风景的心态,

赵春江的专栏

相关文章:

你感兴趣的文章:

标签云: