学习使用opencv库
cv::waitKey()函数的一些用法
基本知识:
waitKey(delay )在一个给定的时间内(单位ms)等待用户按键触发;如果用户没有按下键,则继续等待(循环)。有按键按下,返回按键的ASCII值。无按键按下,返回-1。
- 延时delay = 0 函数则延时无限长,必须有键按下才继续执行。
- 延时delay > 0 函数返回值为按下的键的ASCII码值,超时则返回-1。
示例
- waitKey(0),表示程序会无限制的等待用户的按键事件;
- waitKey(1),表示程序每1ms检测一次按键,检测到返回按键值,检测不到返回-1;
- waitKey(100),表示程序每100ms检测一次按键,检测到返回按键值,检测不到返回-1;
使用场景示例
cv::imshow("variable_obstacle_map",out_mat);
cv::waitKey(0);
注:cv::imshow函数后面需要加上cv::waitKey函数,让程序等待你的操作而不至于闪退。
cv::Mat 详解
元素类型–数据格式
由于cv::Mat要用于存储图像,它里面的元素可以是“像素”,对于像素,OpenCV定义了专门的数据格式来描述它们。
“像素”的数据格式----命名规则:基本数据类型 + 通道数
CV_{8U, 16S, 16U, 32S, 32F, 64F}C{1, 2, 3}
其中: {8U, 16S, 16U, 32S, 32F, 64F}:表示数据类型
8U:unsigned char ; 16S: short int ; 16U: unsigned short int ; 32F: float ; 64F: double
{1,2,3}:代表通道数,特别注意的是1,2,3分别指B,G,R
示例: CV_8UC3: 三通道、每个通道是unsigned char类型的数据
cv::Mat类
//使用示例:
//默认构造函数与值构造函数
cv::Mat img; //默认构造函数
//值构造函数1
cv::Mat img1(480, 640, CV_8UC3); //图像高(行)480-row,宽(列)640-col, 数据类型:CV_8UC3
//值构造函数2
//cv::Scalar(B, G, R)可以表示三通道颜色,这里所示为纯蓝色
cv::Mat img2(480, 640, CV_8UC3, cv::Scalar(255, 0, 0));
//值构造函数3
//效果与上面一样
cv::Size sz3(480, 640);
cv::Mat img3(sz3, CV_8UC3, cv::Scalar(255, 0, 0));
//拷贝构造函数1---都是以静态引用传递参数(const &)
cv::Mat img4(img3);
//拷贝构造函数2---只拷贝感兴趣的区域----由Rect对象定义
//rect左上角(100,100),宽高均为200,(x,y,width,height)
cv::Rect rect(100, 100, 200, 200);
cv::Mat img5(img3, rect);
//拷贝构造函数3--从指定行列构造
//从img3中拷贝0-239行以及0-319行到img6
cv::Range rows(0, 240);
cv::Range cols(0, 320);
cv::Mat img6(img3, rows, cols);
//静态构造函数
cv::Mat img7 = cv::Mat::zeros(480, 640, CV_8UC3); //480行640列,值全为零的数组。
cv::Mat img8 = cv::Mat::ones(480, 640, CV_64FC1); //全1矩阵
cv::Mat img9 = cv::Mat::eye(480, 640, CV_16SC2); //单位矩阵
如何访问
//使用示例
//直接访问---模板函数at<>()
//单通道, 尖括号里面的类型照着文章开头介绍的类型对应关系输入
cv::Mat img = cv::Mat::ones(240, 320, CV_32FC1);
float elem = img.at<float>(10, 10);
//多通道---Vec3b代表固定向量类
//注意类型之间的对应,固定向量与Mat的代表字母有一点差异
//UC3 -> 3b
cv::Mat img1(480, 640, CV_8UC3, cv::Scalar(255,255,0));
cv::Vec3b elem = img1.at<cv::Vec3b>(10, 10);
elem_B = elem[0]; //蓝色通道数值---255
elem_G = elem[1]; //绿色通道数值---255
elem_R = elem[2]; //红色通道---0
//区域访问
//320×320, 3通道白色图像
cv::Mat img(320, 320, CV_8UC3, cv::Scalar(255,255,255));
//访问第1行元素
cv::Mat img_r_0 = img.row(0);
//访问第2列元素
cv::Mat img_c_2 = img.col(1);
//0-160行元素组成的数组
cv::Mat img_r_range = img.rowRange(0, 160);
//0-160列元素组成的数组
cv::Mat img_c_range = img.colRange(0, 160);
//注意:上述操作没有复制行和列,其实相当于只是引用了指定的行和列,我们可以对其进行读写。返回值仍然可以当作图像对待,它是原图像的一部分。
其他使用
//使用示例:
//克隆矩阵
cv::Mat img(480, 640, CV_64FC3);
cv::Mat img1 = img.clone();
//设置元素值
img1.setTo(cv::Scalar(1.0, 2.0, 3.0));
//返回通道数目
size_t num_c = img1.channels();
//返回数组大小
cv::Size sz = img1.size();
//检验数组是否为空,为空返回true
bool e = img1.empty();
固定向量类cv::Vec<>
固定向量别名命名规则: cv::Vec{2,3,4,6}{b, s ,w , i, f, d}
其中:{2,3,4,6}代表向量的长度
{b, s ,w , i, f, d}表示向量内数据类型。
b:unsigned char ; s:short int ;w:unsigned short; i:int;f:float; d:double
示例: cv::Vec3i:三维向量,内部数据为整型
//使用示例:
//默认构造函数
cv::Vec2s v2s;
cv::Vec3i v3i;
//拷贝构造函数
cv::Vec3i v3i_a(v3i);
//值构造函数
cv::Vec3f v3f(1.0, 3.0, 6.0);
cv::Vec2d v2d(1.0, 2.0);
//成员访问,可用[]
float elem_v3f = v3f[0];
//向量叉乘
cv::Vec3d v3d_b(1, 0, 0);
cv::Vec3d v3d_c(0, 1, 0);
cv::Vec3d v3d_bcc = v3d_b.cross(v3d_c);
std::cout<<v3d_bcc<<std::endl;//对<<进行了运算符重载