目录
cv::DMatch(opencv2/core/types.hpp)
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 – 附加到尺度变换后的值上的偏移量(可选)。
- 公式
- 参考
-
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)
特征匹配
-
cv::DMatch(opencv2/core/types.hpp)
含义:
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); } }