14基于opencv的重映射_SURF特征点检测

来源:互联网 发布:软件著作权 源程序 编辑:程序博客网 时间:2024/06/09 13:59

重映射和SURF特征点检测

一、remap ()函数

1.1 remap ()函数各参数详解

void remap(InputArray src, OutputArraydst,InputArray map1,InputArray map2,int interpolation, intborderMode =BORDER_CONSTANT,constScalar& 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。

1.2调用示例 

Mat ScrImage, OutImage_x, OutImage_y;

ScrImage = imread("E:\\1TJQ\\Opencv\\Images\\image1.jpg");//读入图像

   imshow("【原图】", ScrImage);

 

   OutImage_x.create(ScrImage.size(),CV_32FC1); //创建CV_32FC1类型图片

   OutImage_y.create(ScrImage.size(),CV_32FC1);

 

   //3】双层循环,遍历每一个像素点,改变map_x & map_y的值 

   for (int j = 0;j < ScrImage.rows; j++)

   {

      for (int i = 0;i < ScrImage.cols; i++)

      {

         //改变map_x & map_y的值.  

         OutImage_x.at<float>(j,i) = static_cast<float>(i);

         OutImage_y.at<float>(j,i) = static_cast<float>(ScrImage.rows - j);//像素倒过来

      }

   }

 

   remap(ScrImage,OutImage1, OutImage_x, OutImage_y, CV_INTER_LINEAR);

 

   imshow("【重映射remmap操作】",OutImage1);

 

二、SURF特征点监测

2.1函数简介

voiddrawKeypoints(constMat&image,constvector<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。可以在如下这个结构体中选取值。

 

2.2调用示例

Mat ScrImage, OutImage1, keypoints_1;

ScrImage = imread("E:\\1TJQ\\Opencv\\Images\\image1.jpg");//读入图像

   imshow("【原图】", ScrImage);

  

   drawKeypoints(ScrImage,keypoints_1, OutImage1, Scalar::all(-1), DrawMatchesFlags::DEFAULT);

  

imshow("【重映射remmap操作】", OutImage1);

 

三、完整程序

//-----------------------------------【头文件包含部分】---------------------------------------

//    描述:包含程序所依赖的头文件

//----------------------------------------------------------------------------------------------

#include "opencv2/highgui/highgui.hpp"

#include "opencv2/imgproc/imgproc.hpp"

#include <iostream>

 

//-----------------------------------【命名空间声明部分】--------------------------------------

//          描述:包含程序所使用的命名空间

//-----------------------------------------------------------------------------------------------

using namespacecv;

using namespacestd;

 

//-----------------------------------【宏定义部分】--------------------------------------------

//  描述:定义一些辅助宏

//------------------------------------------------------------------------------------------------

#define WINDOW_NAME"【程序窗口】"       //为窗口标题定义的宏

 

 

//-----------------------------------【全局变量声明部分】--------------------------------------

//          描述:全局变量的声明

//-----------------------------------------------------------------------------------------------

Matg_srcImage, g_dstImage;

Matg_map_x, g_map_y;

 

 

//-----------------------------------【全局函数声明部分】--------------------------------------

//          描述:全局函数的声明

//-----------------------------------------------------------------------------------------------

intupdate_map(int key);

static voidShowHelpText();//输出帮助文字

 

//-----------------------------------main( )函数】--------------------------------------------

//          描述:控制台应用程序的入口函数,我们的程序从这里开始执行

//-----------------------------------------------------------------------------------------------

int main(int argc, char** argv)

{

   //改变console字体颜色

   system("color 2F");

 

   //显示帮助文字

   ShowHelpText();

 

   //1】载入原始图

   g_srcImage =imread("E:\\1TJQ\\Opencv\\Images\\image1.jpg", 1);

   if(!g_srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~ \n"); return false; }

   imshow("原始图", g_srcImage);

 

   //2】创建和原始图一样的效果图,x重映射图,y重映射图

   g_dstImage.create(g_srcImage.size(),g_srcImage.type());

   g_map_x.create(g_srcImage.size(),CV_32FC1);

   g_map_y.create(g_srcImage.size(),CV_32FC1);

 

   //3】创建窗口并显示

   namedWindow(WINDOW_NAME, CV_WINDOW_AUTOSIZE);

   imshow(WINDOW_NAME, g_srcImage);

 

   //4】轮询按键,更新map_xmap_y的值,进行重映射操作并显示效果图

   while (1)

   {

      //获取键盘按键 

      int key =waitKey(0);

 

      //判断ESC是否按下,若按下便退出 

      if ((key& 255) == 27)

      {

         cout<< "程序退出...........\n";

         break;

      }

 

      //根据按下的键盘按键来更新 map_x & map_y的值.然后调用remap( )进行重映射

      update_map(key);

      remap(g_srcImage,g_dstImage, g_map_x, g_map_y, CV_INTER_LINEAR, BORDER_CONSTANT,Scalar(0, 0, 0));

 

      //显示效果图

      imshow(WINDOW_NAME, g_dstImage);

   }

   return 0;

}

 

//-----------------------------------update_map( )函数】--------------------------------

//          描述:根据按键来更新map_xmap_x的值

//----------------------------------------------------------------------------------------------

intupdate_map(intkey)

{

   //双层循环,遍历每一个像素点

   for (int j = 0;j < g_srcImage.rows; j++)

   {

      for (int i = 0; i < g_srcImage.cols; i++)

      {

         switch (key)

         {

         case '1': // 键盘【1】键按下,进行第一种重映射操作

            if (i >g_srcImage.cols*0.25 && i < g_srcImage.cols*0.75 && j >g_srcImage.rows*0.25 && j < g_srcImage.rows*0.75)

            {

                g_map_x.at<float>(j,i) = static_cast<float>(2 * (i - g_srcImage.cols*0.25) + 0.5);

                g_map_y.at<float>(j,i) = static_cast<float>(2 * (j - g_srcImage.rows*0.25) + 0.5);

            }

            else

            {

                g_map_x.at<float>(j,i) = 0;

                g_map_y.at<float>(j,i) = 0;

            }

            break;

         case '2':// 键盘【2】键按下,进行第二种重映射操作

            g_map_x.at<float>(j,i) = static_cast<float>(i);

            g_map_y.at<float>(j,i) = static_cast<float>(g_srcImage.rows - j);

            break;

         case '3':// 键盘【3】键按下,进行第三种重映射操作

            g_map_x.at<float>(j,i) = static_cast<float>(g_srcImage.cols - i);

            g_map_y.at<float>(j,i) = static_cast<float>(j);

            break;

         case '4':// 键盘【4】键按下,进行第四种重映射操作

            g_map_x.at<float>(j,i) = static_cast<float>(g_srcImage.cols - i);

            g_map_y.at<float>(j,i) = static_cast<float>(g_srcImage.rows - j);

            break;

         }

      }

   }

   return 1;

}

 

//-----------------------------------ShowHelpText( )函数】---

//      描述:输出一些帮助信息 

//------------------------------------------------------------

static voidShowHelpText()

{

   //输出一些帮助信息 

   printf("\n\n\n\t欢迎来到重映射示例程序~\n\n");

   printf("\t当前使用的OpenCV版本为 OpenCV "CV_VERSION);

   printf("\n\n\t按键操作说明: \n\n"

      "\t\t键盘按键【ESC-退出程序\n"

      "\t\t键盘按键【1第一种映射方式\n"

      "\t\t键盘按键【2-第二种映射方式\n"

      "\t\t键盘按键【3-第三种映射方式\n"

      "\t\t键盘按键【4-第四种映射方式\n"

      "\n\n\t\t\t\t\t\t\t\t by浅墨\n\n\n"

      );

}

 

参考内容:

http://www.cnblogs.com/mq0036/p/5902104.html

阅读全文
0 0
原创粉丝点击