OpenCV学习笔记之十四——opencv重映射&surf特征点检测


首先感谢@浅墨_毛星云本篇博文是小武通过学习@浅墨_毛星云的博客以及书籍《opencv3.0编程入门》整理的笔记及疑问心得,小武水平有限,欢迎交流。

@浅墨_毛星云博文:https://blog.csdn.net/poem_qianmo/article/category/1923021


重映射  

一、概念简析

映射,就是把一幅图像中某位置的像素放置到另一个图片指定位置的过程。为了完成映射过程, 我们需要获得一些插值为非整数像素的坐标,因为源图像与目标图像的像素坐标不是一一对应的。一般情况下,我们通过重映射来表达每个像素的位置 (x,y),像这样 :


g(x,y) = f ( h(x,y) )

 

在这里, g( ) 是目标图像, f() 是源图像, 而h(x,y) 是作用于 (x,y) 的映射方法函数。

 

来看个例子。 若有一幅图像 I ,想满足下面的条件作重映射:

 

h(x,y) = (I.cols - x, y )


在OpenCV中,我们用函数remap( )来实现简单重映射,下面我们就一起来看看这个函数。

 

二、函数解析

remap( )函数会根据我们指定的映射形式,将源图像进行重映射几何变换,基于的式子如下:

 

需要注意,此函数不支持就地(in-place)操作。看看其原型和参数。


原型:

C++: void remap(InputArray src, 
                OutputArray dst, 
                InputArray map1,
                InputArray map2, 
                int interpolation, 
                int borderMode=BORDER_CONSTANT, 
                const Scalar& borderValue=Scalar())

参数:

    • 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可,且需为单通道8位或者浮点型图像。
    • 第二个参数,OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放函数调用后的输出结果,需和源图片有一样的尺寸和类型。
    • 第三个参数,InputArray类型的map1,它有两种可能的表示对象。
  • 表示点(x,y)的第一个映射。
  • 表示CV_16SC2 , CV_32FC1 或CV_32FC2类型的X值。
    • 第四个参数,InputArray类型的map2,同样,它也有两种可能的表示对象,而且他是根据map1来确定表示那种对象。
  • 若map1表示点(x,y)时。这个参数不代表任何值。
  • 表示CV_16UC1 , CV_32FC1类型的Y值(第二个值)。

  • 第五个参数,int类型的interpolation,插值方式,之前的resize( )函数中有讲到,需要注意,resize( )函数中提到的INTER_AREA插值方式在这里是不支持的,所以可选的插值方式如下:
  • INTER_NEAREST - 最近邻插值
  • INTER_LINEAR – 双线性插值(默认值)
  • INTER_CUBIC – 双三次样条插值(逾4×4像素邻域内的双三次插值)
  • INTER_LANCZOS4 -Lanczos插值(逾8×8像素邻域的Lanczos插值)

  • 第六个参数,int类型的borderMode,边界模式,有默认值BORDER_CONSTANT,表示目标图像中“离群点(outliers)”的像素值不会被此函数修改。
  • 第七个参数,const Scalar&类型的borderValue,当有常数边界时使用的值,其有默认值Scalar( ),即默认值为0。


对于第3、第4个参数,也可以这样理解:

第三个参数,InputArray类型的map1,里面存储着源图像中各像素点的x坐标在目标图像中的x坐标,x坐标就是代表列号 ,第四个参数,InputArray类型的map2,里面存储着源图像中各像素点的y坐标在目标图像中的y坐标,y坐标就是代表行号。


代码实现:

#include<iostream>  
  
using namespace std;  
using namespace cv;


int main()
{

 Mat scr_img,dst_img,x_img,y_img;
 scr_img=imread("boy.jpg");
 imshow("source",scr_img);

 //创建和原始图一样的效果图,x重映射图,y重映射图 
 x_img.create(scr_img.size(),CV_32FC1);
 y_img.create(scr_img.size(),CV_32FC1);
 
 //遍历所有像素,改变 x_img 和 y_img 值
 for(int i=0;i<scr_img.rows;i++)
 {
    for(int j=0;j<scr_img.cols;j++)
	{
	   x_img.at<float>(i,j)=static_cast<float>(scr_img.cols-j);    
	   y_img.at<float>(i,j)=static_cast<float>(i);
	
	}
 }

 //进行重映射操作
 remap( scr_img,dst_img,x_img,y_img,CV_INTER_LINEAR, BORDER_CONSTANT);
 imshow("work",dst_img);
 waitKey(0);
 return 0;
}

效果:


  




surf特征点检测

一、算法简介

SURF,我们简单介绍一下,英语全称为SpeededUp Robust Features,直译的话就是“加速版的具有鲁棒性的特征“算法,由Bay在2006年首次提出。SURF是尺度不变特征变换算法(SIFT算法)的加速版。一般来说,标准的SURF算子比SIFT算子快好几倍,并且在多幅图片下具有更好的稳定性。SURF最大的特征在于采用了harr特征以及积分图像的概念,这大大加快了程序的运行时间。SURF可以应用于计算机视觉的物体识别以及3D重构中。


原理:参考这里

二、函数解释

原型:

C++: voidFeatureDetector::detect(constMat& image, vector<KeyPoint>& keypoints,
                                 const Mat& mask=Mat() ) const

参数:

  • 第一个参数—输入图像;
  • 第二个参数—检测的关键点的参数,vector模板类是能够存放任意类型的动态数组,能够增加和压缩;
  • 第三个参数——掩码指定在哪里寻找关键点(可选)。它必须是在感兴趣区域中具有非零值的8位整数矩阵。


drawKeypoints()函数详解:

此函数用于画关键点

C++: void drawKeypoints(const Mat&image, 
                        const vector<KeyPoint>& keypoints,
                        Mat& outImage, 
                        constScalar& color=Scalar::all(-1),
                        int flags=DrawMatchesFlags::DEFAULT)
  • 第一个参数,const Mat&类型的src,输入图像。
  • 第二个参数,const vector<KeyPoint>&类型的keypoints,根据源图像得到的特征点,它是一个输出参数。
  • 第三个参数,Mat&类型的outImage,输出图像,其内容取决于第五个参数标识符falgs。
  • 第四个参数,const Scalar&类型的color,关键点的颜色,有默认值Scalar::all(-1)。
  • 第五个参数,int类型的flags,绘制关键点的特征标识符,有默认值DrawMatchesFlags::DEFAULT。可以在如下这个结构体中选取值。

猜你喜欢

转载自blog.csdn.net/weixin_40647819/article/details/80094177
今日推荐