读写图像
相关函数
读取图像
函数原型:
1 | Mat imread(const String& filename, int flags = IMREAD_COLOR) |
第一参数为图像路径,第二参数为加载图像的形式(默认加载彩色图像)。
第二参数可选参数有三种:
-
0
或IMREAD_GRAYSCALE
,表示加载灰度图像。 -
1
或IMREAD_COLOR
,表示加载彩色图像(默认)。 -
-1
或IMREAD_UNCHANGED
,表示加载包括alpha通道。
创建窗口
函数原型:
1 | void namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE) |
第一参数为窗口名字,第二参数为窗口形式。
窗口形式常用有两种:
-
WINDOW_AUTOSIZE
表示固定大小(默认)。 -
WINDOW_NORMAL
表示可调节大小。
显示图像
函数原型:
1 | void imshow(const String& winname, InputArray mat) |
第一参数为窗口名字,第二参数为图像对象名称。
写入图像
函数原型:
1 | bool imwrite( const String& filename, InputArray img, const std::vector<int>& params = std::vector<int>()) |
第一参数为存储图像路径,第二参数为图像对象名称,其余参数不重要。
等待延时
函数原型:
1 | int waitKey(int delay = 0) |
参数为延时的毫秒数,默认为0,即无限时等待键盘输入。
窗口销毁
函数原型:
1 | void destroyWindow(const String& winname) |
参数为销毁的窗口名称,一般情况下系统会自动回收。
示例代码
1 |
|
读写视频
相关概念
VideoCapture类
VideoCapture类提供了有关视频的操作:
1 | cv::VideoCapture cap(0); |
创建VideoCapture实例,使用构造函数,传入参数0表示设备0。
1 | bool isOpened() |
确认摄像头是否开启成功。
1 | bool grab() |
确认摄像头在运行中是否捕获到帧。
1 | bool read(OutputArray image) |
将视频捕获对象中捕获到的图像输出到image中。
转化图像颜色通道
函数原型:
1 | void cvtColor(InputArray src, OutputArray dst, int code, int dstCn = 0) |
第一参数是输入图像,第二参数是输出图像,第三参数是转化图像颜色通道代码,第四参数暂不管。
转化图像颜色通道代码有许多,通常用到:
-
COLOR_BGR2GRAY
:由OpenCV的BGR通道转为灰度通道。 -
COLOR_BGR2BGRA
:由OpenCV的BGR通道添加了Alpha通道。
读取、显示视频
与使用摄像头的思路类似,将捕获设备改为捕获本地文件。
1 | cv::VideoCapture cap("src/test.mp4"); |
显示与使用摄像头的思路类似,捕获视频每一帧并展示图像对象。
写入视频
定义编解码器并创建VideoWriter对象进行保存。
1 | int fourcc = cv::VideoWriter::fourcc('X', 'V', 'I', 'D'); // 编解码器 |
VideoWriter的其中一个构造函数原型如下:
1 | VideoWriter(const String& filename, int fourcc, double fps, Size frameSize, bool isColor = true) |
2.2.2 示例代码
1 |
|
图像的基本操作
创建空白图像
使用 Mat
创建图像矩阵的常用形式:
- 创建空图像,大小为0:
1 | cv::Mat image1; |
- 指定矩阵大小,指定数据类型
1 | cv::Mat image2(100, 100, CV_8U); |
-
创建100行×100列的矩阵,数据类型为无符号8位int,即灰度图像。
-
还有一种常用的类型CV_8UC3,表示三通道无符号8位int。
- 指定矩阵大小,指定数据类型,设置初始值
1 | cv::Mat image3(100, 100, CV_8U, 100) |
-
创建100行×100列的矩阵,数据类型为无符号8位int灰度图像,灰度值为100。
-
对于三通道图像,应使用Scalar():
1 | cv::Mat image(640, 640, CV_8UC3, cv::Scalar(100, 100, 0)); |
获取图像信息
获取行列数、通道数
直接访问Mat类成员rows、cols和函数channels()返回图像的行、列和通道数。可以通过通道数判断是灰度图像(通道为1)还是彩色图像(通道为3)。
1 | std::cout << "图像的行:" << image.rows << std::endl; |
访问像素点的BGR值
通过Vec3b数据类型访问返回像素点的BGR值,注意,前者是行数,后者是列数。
1 | int blue = image.at<cv::Vec3b>(100, 100)[0]; |
同理进行修改:
1 | image.at<cv::Vec3b>(100, 100)[0] = 201; |
当然大面积的修改才会明显,通过循环进行:
1 | for(int i = 0; i < 100; ++ i) |
如果修改BGR值,则组成Vec3b类型:
1 | for(int i = 0; i < 100; ++ i) |
标记区域
创建tmp变量,获取图像行从200到1000,列从200到1000的区域。将图像行从1200到2000,列从1200到2000的区域变成tmp
1 | cv::Mat image = cv::imread("src/test.jpg"); |
遍历图像
循环行和列遍历图像
对于OpenCV的Mat,其顺序是行和列。与C++的二维数组类似,遍历:
1 | for(int i = 0; i < 100; ++ i) |
指针扫描
1 |
|
绘图入门
静态绘制
绘制线
函数原型:
1 | void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,int thickness = 1, int lineType = LINE_8, int shift = 0) |
参数分别为:图像对象、始点坐标、终点坐标、颜色、线粗细、线类型……
使用示例:
1 | cv::line(image, cv::Point(0, 0), cv::Point(512, 512), cv::Scalar(255, 0, 0), 5); |
绘制矩形
函数原型:
1 | void rectangle(InputOutputArray img, Rect rec, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0) |
参数分别为:图像对象、矩形框、颜色、边框线粗细、边框线类型……
矩形框的四个参数分别为:x坐标、y坐标、宽、高。
使用示例:
1 | cv::rectangle(image, cv::Rect(0, 0, 100, 100), cv::Scalar(0, 255, 255), 5); |
绘制圆
函数原型:
1 | void circle(InputOutputArray img, Point center, int radius, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0) |
参数分别为:图像对象、圆心、半径、颜色、边框线粗细、边框线类型……
使用示例:
1 | cv::circle(image, cv::Point(319, 319), 50, cv::Scalar(0, 0, 255), 5); |
绘制椭圆
函数原型:
1 | void ellipse(InputOutputArray img, Point center, Size axes, double angle, double startAngle, double endAngle, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0) |
参数分别为:图像对象、中心点、长短轴、初始旋转角度、椭圆开始角度、椭圆结束角度、颜色、边框线粗细、边框线类型……边框线粗细为-1表示内填充。
使用示例:
1 | cv::ellipse(image, cv::Point(319, 119), cv::Size(100, 50), 0, 180, 360, 255, -1); |
绘制多边形
函数原型:
1 | void polylines(InputOutputArray img, const Point* const* pts, const int* npts, int ncontours, bool isClosed, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0 ) |
参数分别为:图像对象、const修饰的指向多边形数组的指针、多边形顶点个数的数组名、绘制多边形的个数、是否闭合、颜色、边框粗细、边框线类型
使用示例:
1 | // 构造多边形的端点形成的点类型数组。 |
添加文本
函数原型:
1 | void putText( InputOutputArray img, const String& text, Point org, int fontFace, double fontScale, Scalar color, int thickness = 1, int lineType = LINE_8, bool bottomLeftOrigin = false ) |
参数分别为:图像对象、文本内容、文字在图像中的左下角坐标、字体、字体大小、字体颜色、字体粗细、描绘字体的线类型……
使用示例:
1 | cv::putText(image, "OpenCV", cv::Point(10, 500), cv::FONT_HERSHEY_SIMPLEX, 4, cv::Scalar(255, 255, 255), 2, cv::LINE_AA); |
整体绘制展示
1 |
|
鼠标绘制
1 |
|