OPenCV高级编程——OpenCV常见的API及绘图知识详解

目录

引言

一、Mat类详解

1. Mat类的基本结构

2. Mat类的数据类型

3. Mat类的创建与初始化

4. Mat类的使用技巧

二、OpenCV核心功能模块

1. 基本的图像读取与显示

2. 图像的保存

3. 矩阵操作

4. 等待键盘输入与销毁窗口

5. 命名窗口

三、图像处理模块

1. 色彩空间转换

2. 图像写入

3. 图像变换

4. 图像滤波

四、绘图与交互

1. 绘制基本图形

  2. 文本绘制

  3. 鼠标与键盘事件

4. 示例:在图像上绘制并响应鼠标事件

五、结论


引言

OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库,它提供了大量的图像处理、视频分析、对象检测等功能。本文将详细介绍OpenCV中常见的API以及绘图相关的知识,帮助开发者更好地理解和使用OpenCV。

一、Mat类详解

Mat类是OpenCV中C++版本的矩阵类,它替代了原来C版本的矩阵结构体CvMat和图像结构体IplImage。Mat类具有许多优势,特别是与STL(Standard Template Library)的兼容性很好,提供了许多类似于STL的操作,并且是一种高效的数据类型,对内存进行动态管理,无需用户手动管理内存。

1. Mat类的基本结构

Mat类定义于OpenCV的core.hpp中,主要包含两部分数据:

  1. 矩阵头(matrix header):这部分的大小是固定的,包含了矩阵的大小(行数和列数)、存储方式、矩阵存储的地址等信息。
  2. 数据指针(data pointer):一个指向矩阵包含像素值的指针,用于访问矩阵的实际数据。

Mat类的定义大致如下(简化版):

class CV_EXPORTS Mat {  
public:  
    int flags; // 包含矩阵的多个标志位,如深度、通道数等  
    int dims;   // 数组的维度,>= 2  
    int rows, cols; // 矩阵的行数和列数  
    uchar* data; // 指向数据的指针  
    int* refcount; // 指向引用计数器的指针  
    // 其他成员...  
};

2. Mat类的数据类型

Mat类支持多种数据类型,这些数据类型决定了矩阵中元素的存储方式。常见的数据类型包括:

  • CV_8U:8位无符号整数(0~255)
  • CV_8S:8位有符号整数(-128~127)
  • CV_16U:16位无符号整数(0~65535)
  • CV_16S:16位有符号整数(-32768~32767)
  • CV_32S:32位有符号整数
  • CV_32F:32位浮点数
  • CV_64F:64位浮点数

在OpenCV中,可以通过特定的模板类(如Mat_<uchar>Mat_<int>等)或类型标识符(如CV_8UC1CV_32FC3等)来指定Mat的数据类型。

3. Mat类的创建与初始化

Mat类可以通过多种方式创建和初始化:

  1. 使用构造函数

    • Mat::Mat():默认构造函数,创建一个空的Mat对象。
    • Mat::Mat(int rows, int cols, int type):指定行数、列数和类型创建Mat对象。
    • Mat::Mat(Size size, int type):使用Size结构体指定尺寸和类型创建Mat对象。
    • Mat::Mat(const Mat& m):拷贝构造函数,创建一个与已有Mat对象相同的Mat对象(但注意,这种方式只是复制了矩阵头,数据是共享的)(浅拷贝)
  2. 使用create函数:可以在不重新创建Mat对象的情况下改变其大小和类型。

  3. 使用其他函数:如zerosoneseye等,用于创建全零、全一或单位矩阵。

4. Mat类的使用技巧

  1. 元素访问
    • 使用at函数:M.at<type>(i, j),其中type是元素的数据类型,ij是行和列的索引。
    • 使用迭代器:通过MatIterator_迭代器遍历矩阵元素。
    • 使用指针:直接操作data指针访问矩阵数据(注意边界和步长)。
  2. 矩阵操作
    • 支持多种数学运算,如加法、减法、乘法等。
    • 支持矩阵变换,如转置、缩放、旋转等。
  3. 内存管理
    • Mat类自动管理内存,无需用户手动释放。
    • 使用clone函数可以复制整个Mat对象(包括数据),避免数据共享问题。(深拷贝)

二、OpenCV核心功能模块

1. 基本的图像读取与显示

  • cv::imread:用于读取图像文件。其原型为cv::Mat cv::imread(const String& filename, int flags = IMREAD_COLOR)。其中,filename是图像文件的路径,flags是读取图像的方式,例如IMREAD_COLOR表示以彩色模式读取图像,IMREAD_GRAYSCALE表示以灰度模式读取图像。

  • cv::imshow:用于在窗口中显示图像。其原型为void cv::imshow(const String& winname, InputArray mat)。其中,winname是窗口的名称,mat是要显示的图像数据。

2. 图像的保存

  • cv::imwrite:用于将图像写入文件。其原型为bool cv::imwrite(const String& filename, InputArray img, const std::vector<int>& params = std::vector<int>())。其中,filename是保存图像的路径,img是要保存的图像数据,params是保存图像时的一些可选参数。

3. 矩阵操作

  • cv::Mat:是OpenCV中用于存储图像数据和其他多维数组的数据结构。提供了丰富的矩阵操作函数,如加法、减法、乘法、除法、归一化等。

4. 等待键盘输入与销毁窗口

  • cv::waitKey:等待键盘输入。函数原型为int cv::waitKey(int delay = 0)delay参数表示等待时间(毫秒),如果设置为0,则表示无限等待。常用于在显示图像时等待用户按键。
  • cv::destroyAllWindows:销毁所有由OpenCV创建的窗口。

5. 命名窗口

  • cv::namedWindow:用于创建窗口并指定窗口类型。函数原型为void cv::namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE)winname是窗口名称,flags用于指定窗口类型,如WINDOW_AUTOSIZE表示窗口大小自动调整。

三、图像处理模块

1. 色彩空间转换

  • cv::cvtColor:用于图像的色彩空间转换。其原型为void cv::cvtColor(InputArray src, OutputArray dst, int code, int dstCn = 0)。其中,src是输入图像,dst是输出图像,code是转换代码,如COLOR_BGR2GRAY表示将BGR图像转换为灰度图像。

2. 图像写入

  • cv::imwrite:用于将图像写入文件。函数原型为bool cv::imwrite(const String& filename, InputArray img, const std::vector<int>& params = std::vector<int>())filename是输出文件的路径,img是要写入的图像数据。

3. 图像变换

  • cv::resize:用于改变图像的大小。支持多种插值方法,如线性插值、立方插值等。

  • cv::warpAffinecv::warpPerspective:分别用于图像的仿射变换和透视变换。

4. 图像滤波

  • cv::blurcv::GaussianBlur:分别用于图像的均值模糊和高斯模糊。

四、绘图与交互

1. 绘制基本图形

  • cv::line:用于绘制直线。其原型为void cv::line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0)。其中,img是绘制图形的载体,pt1pt2是线段的起点和终点,color是线条的颜色,thickness是线条的粗细。

  • cv::rectangle:用于绘制矩形。其原型为void cv::rectangle(InputOutputArray img, Point pt1, Point pt2, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0)。其中,pt1pt2分别是矩形的左上顶点和右下顶点。

  • cv::circle:用于绘制圆形。其原型为void cv::circle(InputOutputArray img, Point center, int radius, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0)。其中,center是圆心的坐标,radius是圆的半径。

  • cv::ellipse:用于绘制椭圆。其原型为void cv::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)。其中,center是椭圆的圆心坐标,axes是椭圆的长轴和短轴的长度,angle是椭圆的旋转角度。

  • cv::polylines:用于绘制多边形。其原型为void cv::polylines(InputOutputArray img, InputArrayOfArrays pts, bool isClosed, const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0)。其中,pts是多边形的顶点坐标,isClosed表示多边形是否闭合。

  2. 文本绘制

  • cv::putText:用于在图像上绘制文本。其原型为void cv::putText(InputOutputArray img, const String& text, Point org, int fontFace, double fontScale, const Scalar& color, int thickness = 1, int lineType = LINE_8, bool bottomLeftOrigin = false)。其中,img是绘制文本的图像,text是要绘制的文本字符串,org是文本左下角的坐标(如果bottomLeftOriginfalse,则为左下角的坐标,否则为基线的起点),fontFace是字体的类型,fontScale是字体大小的缩放比例,color是文本的颜色,thickness是文本的线条粗细。

  3. 鼠标与键盘事件

OpenCV提供了创建窗口并响应鼠标和键盘事件的功能,这在交互式应用中非常有用。你可以使用cv::namedWindow来创建一个窗口,然后使用cv::setMouseCallbackcv::setKeyboardCallback来分别设置鼠标和键盘的回调函数。

  • cv::namedWindow:创建一个窗口。
  • cv::setMouseCallback:为指定的窗口设置鼠标回调函数。
  • cv::setKeyboardCallback:为指定的窗口设置键盘回调函数。

4. 示例:在图像上绘制并响应鼠标事件

#include <opencv2/opencv.hpp>  
  
void onMouse(int event, int x, int y, int flags, void* param) {  
    cv::Mat* image = (cv::Mat*)param;  
    if (event == cv::EVENT_LBUTTONDOWN) {  
        cv::circle(*image, cv::Point(x, y), 5, cv::Scalar(0, 255, 0), -1);  
    }  
}  
  
int main() {  
    cv::Mat image = cv::imread("path_to_image.jpg");  
    if (image.empty()) {  
        std::cerr << "Could not read the image" << std::endl;  
        return 1;  
    }  
  
    cv::namedWindow("Image Window", cv::WINDOW_AUTOSIZE);  
    cv::setMouseCallback("Image Window", onMouse, &image);  
  
    while (true) {  
        cv::imshow("Image Window", image);  
        if (cv::waitKey(20) >= 0) break;  
    }  
  
    return 0;  
}

在这个示例中,我们创建了一个窗口并在其中显示一张图像。通过cv::setMouseCallback设置了一个鼠标回调函数onMouse,该函数会在鼠标左键点击时在图像上绘制一个绿色的圆点。

五、结论

OpenCV提供了丰富的API用于图像处理、图像分析以及绘图等任务。通过本文的介绍,你应该对OpenCV中常见的API以及绘图相关的知识有了更深入的了解。希望这些信息能够帮助你在实际的项目中更加高效地利用OpenCV。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值