Opencv学习记录

目录

Mat类型 

初始化方式:

DataType类

waitkey:延时

像素级别的访问(2种)

特征检测

cv::KeyPoint

cv::Feature2D

 cv::xfeatures2d(命名空间)

特征匹配

cv::DMatch(opencv2/core/types.hpp)

含义:

类的定义:

成员变量:

构造函数:

操作符重载:

cv::DescriptorMatcher

 成员函数


 1.imread():读入图像

  • 函数原型:
Mat cv::imread 	( const String &  filename,
                  int  flags = IMREAD_COLOR ) 	
  •  参数:
flags=说明
IMREAD_UNCHANGED如果设置,则按原样返回加载的图像(比如:保存为了16位的图片,读取出来仍然为16位)
IMREAD_GRAYSCALE如果设置,则始终将图像转换为单通道灰度图像(编解码器内部转换)。
IMREAD_COLOR如果设置,请始终将图像转换为3通道BGR彩色图像。
IMREAD_ANYDEPTH如果设置,则在输入具有相应深度时返回16位/ 32位图像,否则将其转换为8位。
IMREAD_ANYCOLOR如果设置,则以任何可能的颜色格式读取图像。
IMREAD_LOAD_GDAL如果设置,使用gdal驱动程序加载图像
IMREAD_REDUCED_GRAYSCALE_2如果设置,则始终将图像转换为单通道灰度图像,图像尺寸减小1/2。
IMREAD_REDUCED_COLOR_2如果设置,则始终将图像转换为3通道BGR彩色图像,图像尺寸减小1/2。
IMREAD_REDUCED_GRAYSCALE_4如果设置,则始终将图像转换为单通道灰度图像,图像尺寸减小1/4
IMREAD_REDUCED_COLOR_4如果设置,则始终将图像转换为3通道BGR彩色图像,图像尺寸减小1/4
IMREAD_REDUCED_GRAYSCALE_8如果设置,则始终将图像转换为单通道灰度图像,图像尺寸减小1/8。
IMREAD_REDUCED_COLOR_8如果设置,则始终将图像转换为3通道BGR彩色图像,图像尺寸减小1/8。
IMREAD_IGNORE_ORIENTATION如果设置,请不要根据EXIF的方向标志旋转图像。

2.imwrite():保存图像

  • 函数原型
bool cv::imwrite(
    const String & filename,
    InputArray img,
    const std::vector<int> & params = std::vector<int>()
)
  • 保存不同位数的深度图
// 加载图像
Mat src = imread("../1.png", IMREAD_UNCHANGED);

// 转为为16位图像
Mat dst;
src.convertTo(dst, CV_16U);
imshow("dst", dst);
imwrite("../2.png", dst);
// 加载图像
Mat src = imread("../1.png", IMREAD_UNCHANGED);

// 转为为16位图像
Mat dst;
src.convertTo(dst, CV_16U);

// 归一化再保存
normalize(dst, dst, 0, 256 * 256, NORM_MINMAX);
imwrite("../2.png", dst);
imshow("dst", dst);

 3.convertTo():矩阵数据类型转换

  • 函数原型
void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;
  • 参数
  • m       – 目标矩阵。如果m在运算前没有合适的尺寸或类型,将被重新分配。
  • rtype – 目标矩阵的类型。因为目标矩阵的通道数与源矩阵一样,所以rtype也可以看做是目标矩阵的位深度。如果rtype为负值,目标矩阵和源矩阵将使用同样的类型。
  • alpha – 尺度变换因子(可选)。
  • beta   – 附加到尺度变换后的值上的偏移量(可选)。
  • 公式

  • 参考

OpenCV—矩阵数据类型转换cv::convertTo


  • Mat类型 

  • 一幅图像被保存为一个头(地址)和一个包含像素数据的内存区

  • OpenCV提供了代理类InputArray和OutputArray,允许前面的任意类型作为函数的参数使用。 

 

初始化方式:

注:数组元素的初始值可以由Scalar类设置为一个典型的四元素向量

例如:

DataType类

OpenCV的基本数据类型。 基本数据类型可以是bool、 unsigned char、 signed char、 unsigned short、 signed short、 int、float、 double或者是以这些基本类型之一的值构成的一个元组(或称数组)

  • U、 S和F分别代表unsigned、 signed和float数据类型

waitkey:延时

这个函数在数毫秒(delay>0)内等待一个按键操作,并返回键的编码如果延迟结束时没有按键则返回-1。如果delay是0或负数,那么函数一直等待直到一个键被按下。

  • 注意:只有至少创建和激活一个窗口时, 函数waitKey才会工作。
     

像素级别的访问(2种)

  • at<>

  • ptr(返回指向图像特定行的一个指针)

特征检测

 

  • cv::Feature2D

 

  •  detect
virtual void cv::Feature2D::detect ( 
                InputArray  image,
		std::vector< KeyPoint > &  keypoints,
		InputArray  mask = noArray() 
) 	
virtual void cv::Feature2D::detect (
                InputArrayOfArrays  images,
		std::vector< std::vector< KeyPoint > > &  keypoints,
		InputArrayOfArrays  masks = noArray() 
) 	
  •  compute
virtual void cv::Feature2D::compute ( 
                InputArray  image,
		std::vector< KeyPoint > &  keypoints,
		OutputArray  descriptors 
) 	
virtual void cv::Feature2D::compute ( 
                InputArrayOfArrays  images,
		std::vector< std::vector< KeyPoint > > &  keypoints,
		OutputArrayOfArrays  descriptors 
) 	
  •  detectAndCompute
virtual void cv::Feature2D::detectAndCompute (
                InputArray  image,
		InputArray  mask,
		std::vector< KeyPoint > &  keypoints,
		OutputArray  descriptors,
		bool  useProvidedKeypoints = false 
) 	

 

  •  cv::xfeatures2d(命名空间)

 这些类继承cv::Feature2D 类,然后再次进行定义。

typedef SIFT 	SiftDescriptorExtractor
 
typedef SIFT 	SiftFeatureDetector
 
typedef SURF 	SurfDescriptorExtractor
 
typedef SURF 	SurfFeatureDetector

 说明:

  • SUFT=SurfDescriptorExtractor=SurfFeatureDetector
  • SIFT=SiftDescriptorExtractor=SiftFeatureDetector

例如:

cv::Ptr<cv::Feature2D> f2d=cv::xfeatures2d::SURF::create(2000);
  • SUFT
static Ptr< SURF > create (
                double hessianThreshold=100, 
                int nOctaves=4, 
                int nOctaveLayers=3, 
                bool extended=false, 
                bool upright=false)
 virtual bool 	getExtended () const =0
 
virtual double 	getHessianThreshold () const =0
 
virtual int 	getNOctaveLayers () const =0
 
virtual int 	getNOctaves () const =0
 
virtual bool 	getUpright () const =0
 
virtual void 	setExtended (bool extended)=0
 
virtual void 	setHessianThreshold (double hessianThreshold)=0
 
virtual void 	setNOctaveLayers (int nOctaveLayers)=0
 
virtual void 	setNOctaves (int nOctaves)=0
 
virtual void 	setUpright (bool upright)=0
  • SIFT
static Ptr< SIFT > create (
                   int nfeatures=0, 
                   int nOctaveLayers=3, 
                   double contrastThreshold=0.04, 
                   double edgeThreshold=10, 
                   double sigma=1.6)

 

特征匹配

含义:

DMatch主要用来储存匹配信息的结构体,当Opencv找到匹配时,生成cv::DMatch对象的列表(vector)来描述。

类的定义:

struct CV_EXPORTS_W_SIMPLE DMatch 
{ 
    //默认构造函数,FLT_MAX是无穷大 
    //#define FLT_MAX         3.402823466e+38F        /* max value */ 
    CV_WRAP DMatch() : queryIdx(-1), trainIdx(-1), imgIdx(-1), distance(FLT_MAX) {} 
    //DMatch构造函数 
    CV_WRAP DMatch( int _queryIdx, int _trainIdx, float _distance ) : 
            queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(-1), distance(_distance) {} 
    //DMatch构造函数 
    CV_WRAP DMatch( int _queryIdx, int _trainIdx, int _imgIdx, float _distance ) : 
            queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(_imgIdx), distance(_distance) {} 
   
    //queryIdx为query描述子的索引,match函数中前面的那个描述子 
    CV_PROP_RW int queryIdx; // query descriptor index 
    //trainIdx为train描述子的索引,match函数中后面的那个描述子 
    CV_PROP_RW int trainIdx; // train descriptor index 
    //imgIdx为进行匹配图像的索引 
    //例如已知一幅图像的sift描述子,与其他十幅图像的描述子进行匹配,找最相似的图像,则imgIdx此时就有用了。 
    CV_PROP_RW int imgIdx;   // train image index 
    //distance为两个描述子之间的距离 
    CV_PROP_RW float distance; 
    //DMatch比较运算符重载,比较的是DMatch中的distance,小于为true,否则为false 
    // less is better 
    bool operator<( const DMatch &m ) const 
    { 
        return distance < m.distance; 
    } 
};  

成员变量:

  • imgIdx:用于辨别在图像和字典之间寻求匹配的情况下训练图像来自的特定图像;
  • query:是要匹配的描述子;
  • train:是被匹配的描述子;

构造函数:

cv::DMatch::DMatch()
cv::DMatch::DMatch (
 	int  	_queryIdx,
	int  	_trainIdx,
	float  	_distance 
) 	
cv::DMatch::DMatch ( int  _queryIdx,
		int  	_trainIdx,
		int  	_imgIdx,
		float  	_distance 
	) 	

操作符重载:

bool cv::DMatch::operator< ( const DMatch &  m) const
  • cv::DescriptorMatcher

 成员函数:

  • match
void cv::DescriptorMatcher::match ( 
                InputArray  queryDescriptors,
		InputArray  trainDescriptors,
		std::vector< DMatch > &  matches,
		InputArray  mask = noArray() 
) 		
void cv::DescriptorMatcher::match ( 
                InputArray  queryDescriptors,
		std::vector< DMatch > &  matches,
		InputArrayOfArrays  masks = noArray() 
)
  •  radiusMatch
void cv::DescriptorMatcher::radiusMatch ( 
                InputArray  queryDescriptors,
		InputArray  trainDescriptors,
		std::vector< std::vector< DMatch > > &  matches,
		float  maxDistance,
       		InputArray  mask = noArray(),
		bool  compactResult = false 
) 	const
void cv::DescriptorMatcher::radiusMatch ( 
                InputArray  	queryDescriptors,
		std::vector< std::vector< DMatch > > &  matches,
		float  maxDistance,
		InputArrayOfArrays  masks = noArray(),
		bool  compactResult = false 
) 	
  •  knnMatch
void cv::DescriptorMatcher::knnMatch ( InputArray  queryDescriptors,
		InputArray  trainDescriptors,
		std::vector< std::vector< DMatch > > &  matches,
		int  k,
    		InputArray  mask = noArray(),
		bool  compactResult = false 
) const
void cv::DescriptorMatcher::knnMatch (
                InputArray  queryDescriptors,
		std::vector< std::vector< DMatch > > &  matches,
		int  k,
		InputArrayOfArrays  masks = noArray(),
		bool  compactResult = false 
) 	
  •  create
static Ptr<DescriptorMatcher> cv::DescriptorMatcher::create 	( 	const String &  	descriptorMatcherType	) 	
static Ptr<DescriptorMatcher> cv::DescriptorMatcher::create 	( 	const DescriptorMatcher::MatcherType &  	matcherType	) 	

 传递的参数:

参数选项
  FLANNBASED = 1,
 
FLANN方法
BRUTEFORCE = 2,
 
使用L2范数进行元素直接比较
BRUTEFORCE_L1 = 3,
 
使用L1范数进行元素直接比较
BRUTEFORCE_HAMMING = 4,
 
使用hamming距离进行元素比较
BRUTEFORCE_HAMMINGLUT = 5,
 
使用多级hamming距离的元素直接比较
BRUTEFORCE_SL2 = 6使用平方二分法进行元素直接比较

 例如:

cv::Ptr<cv::DescriptorMatcher> matcher=cv::DescriptorMatcher::create(cv::DescriptorMatcher::FLANNBASED);

 

 鼠标事件

函数原型:

c++: CV_EXPORTS void setMouseCallback(const string& winname, MouseCallback onMouse, void* userdata = 0);
  • winname:窗口的名字
  • onMouse:鼠标响应函数,回调函数
  • userdate:传给回调函数的参数 ,例如当鼠标在 winname的窗口进行操作时,将指针的地址传给on mouse

回调函数的定义:

typedef void (MouseCallback)(int event, int x, int y, int flags, void userdata);
  • event为 CV_EVENT_*所定义,代表鼠标点击事件,每当鼠标有点击事件发生,就把相应数字传给on_Mouse函数,以进行下一步处理。
  • x为鼠标当前所在位置的x坐标。
  • y为鼠标当前所在位置的y坐标
  • flags为CV_EVENT_FLAG所定义,代表鼠标拖拽事件

event对应的事件:

enum
{
CV_EVENT_MOUSEMOVE =0,//滑动
CV_EVENT_LBUTTONDOWN =1,//左键点击
CV_EVENT_RBUTTONDOWN =2,//右键点击
CV_EVENT_MBUTTONDOWN =3,//中键点击
CV_EVENT_LBUTTONUP =4,//左键放开
CV_EVENT_RBUTTONUP =5,//右键放开
CV_EVENT_MBUTTONUP =6,//中键放开
CV_EVENT_LBUTTONDBLCLK =7,//左键双击
CV_EVENT_RBUTTONDBLCLK =8,//右键双击
CV_EVENT_MBUTTONDBLCLK =9//中键双击
};

flag对应的事件:

enum
{
CV_EVENT_FLAG_LBUTTON =1,//左键拖拽
CV_EVENT_FLAG_RBUTTON =2,//右键拖拽
CV_EVENT_FLAG_MBUTTON =4,//中键拖拽
CV_EVENT_FLAG_CTRLKEY =8,//按CTRL不放
CV_EVENT_FLAG_SHIFTKEY =16,//按SHIFT不放
CV_EVENT_FLAG_ALTKEY =32//按ALT不放
};

实现:

#include<opencv2/opencv.hpp>
#include <cstring>
#include<iostream>
using namespace cv;
using namespace std;
void on_mouse(int EVENT, int x, int y, int flags, void* ustc);
Mat srcImg,tmpImg, MidImg;

int main(void)
{
    srcImg = imread("000012.png");
    namedWindow("DealImg");

    setMouseCallback("DealImg", on_mouse, (void*)(&srcImg)); //调用回调函数
    imshow("DealImg", srcImg);
    waitKey(0);
    destroyWindow("DealImg");
}

void on_mouse(int EVENT, int x, int y, int flags, void* ustc)
{
    static Point Pre_pt(-1, -1);
    static Point Cur_pt(-1, -1);
    char Txt_Point[50] = { 0 };

    if (ustc == NULL)
    {
        return;
    }

    if (EVENT == CV_EVENT_LBUTTONDOWN)                                      //左键按下,读取初始坐标,并在图像上该点处划圆
    {
        Pre_pt = Point(x, y);
        sprintf(Txt_Point, "(%d,%d)", x, y);
        putText(tmpImg, Txt_Point, Pre_pt,CV_FONT_HERSHEY_COMPLEX, 0.5, Scalar(0, 0, 0, 255), 1, 8);
        //circle(tmpImg, Pre_pt, 2, Scalar(255, 0, 0, 0), CV_FILLED, CV_AA, 0);    //左键按下的点划圆
        //imshow("DealImg", tmpImg);
    }

    else if ((EVENT == CV_EVENT_MOUSEMOVE) && !(flags & CV_EVENT_FLAG_LBUTTON))//左键没有按下的情况下鼠标移动的处理函数
    {
        if (MidImg.data == NULL)
        {
            srcImg.copyTo(tmpImg);                                            //将src复制到临时图像tmp上,用于显示实时坐标
        }
        else
        {
            MidImg.copyTo(tmpImg);                                             //当已划定矩形的情况时,在图像上显示前面所画图像
        }
        Cur_pt = Point(x, y);
        sprintf(Txt_Point, "(%d,%d)", x, y);
        putText(tmpImg, Txt_Point, Cur_pt,CV_FONT_HERSHEY_COMPLEX, 0.5, Scalar(0, 0, 0, 255), 1, 8);
        imshow("DealImg", tmpImg);
    }

    else if (EVENT == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))//左键按下时,鼠标移动,则在图像上划矩形
    {
        srcImg.copyTo(MidImg);
        Cur_pt = Point(x, y);
        sprintf(Txt_Point, "(%d,%d)", x, y);
        putText(MidImg, Txt_Point, Pre_pt,CV_FONT_HERSHEY_COMPLEX, 0.5, Scalar(0, 0, 0, 255), 1, 8);
        rectangle(MidImg, Cur_pt, Pre_pt, Scalar(0, 0, 255), 1, 8, 0);
        imshow("DealImg", MidImg);
    }
    else if (EVENT == CV_EVENT_LBUTTONUP)                                          //左键松开,将在图像上划矩形
    {
        srcImg.copyTo(MidImg);
        std::sprintf(Txt_Point, "(%d,%d)", x, y);
        Cur_pt = Point(x, y);
        putText(MidImg, Txt_Point, Pre_pt,CV_FONT_HERSHEY_COMPLEX, 0.5, Scalar(0, 0, 0, 255), 1, 8);
        putText(MidImg, Txt_Point, Cur_pt,CV_FONT_HERSHEY_COMPLEX, 0.5, Scalar(0, 0, 0, 255), 1, 8);
        rectangle(MidImg, Cur_pt, Pre_pt, Scalar(0, 0, 255), 1, 8, 0);
        imshow("DealImg", MidImg);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

火柴的初心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值