简介

  • OpenCV 常见的数据结构笔记

OpenCV cv::Mat 详解

cv::Mat 是 OpenCV 中用于表示图像的核心数据结构之一。它是一个多维数组,可以存储图像中的像素值,并提供了许多用于图像处理和分析的功能。

以下是 cv::Mat 的一些关键特性和常用操作:

  1. 图像的表示cv::Mat 对象可以表示单通道或多通道的图像,可以是灰度图像、彩色图像或者其他图像类型。每个通道中的像素值可以是不同的数据类型,如 ucharfloatdouble 等。

  2. 构造函数cv::Mat 提供了多种构造函数,可以用来创建不同类型的图像。例如,你可以通过指定图像尺寸、通道数、数据类型来创建一个空的图像;也可以通过直接传入图像数据来创建一个图像;还可以通过复制另一个 cv::Mat 对象来创建一个副本。

  3. 像素访问cv::Mat 提供了多种方式来访问和修改图像中的像素值。你可以使用 .at<>() 方法来访问指定像素的值,也可以通过直接访问像素数组来进行操作。例如,对于一个单通道的灰度图像,你可以使用 .at<uchar>(row, col) 来获取指定位置的像素值;对于一个三通道的彩色图像,你可以使用 .at<cv::Vec3b>(row, col) 来获取指定位置的像素值,其中 cv::Vec3b 是一个包含三个 uchar 值的类型。

  4. 图像的加载和保存cv::Mat 对象可以通过 OpenCV 提供的函数加载和保存图像数据。例如,你可以使用 cv::imread() 函数加载图像文件,并将其存储为一个 cv::Mat 对象;也可以使用 cv::imwrite() 函数将图像数据保存为一个文件。

  5. 图像的操作cv::Mat 提供了许多图像处理和操作的函数,如图像的缩放、旋转、裁剪、滤波、边缘检测等。这些函数可以直接对 cv::Mat 对象进行操作,而无需额外的内存分配。

  6. 内存管理cv::Mat 对象会自动管理内存,当对象被销毁时,它所占用的内存也会被释放。你也可以通过 .release() 方法手动释放对象的内存,或者通过 .clone() 方法创建对象的副本。

  7. 其他特性:除了上述功能外,cv::Mat 还提供了其他一些特性,如图像的拷贝、赋值、转换、填充等功能,以及与其他 OpenCV 类型的兼容性。

总的来说,cv::Mat 是 OpenCV 中最常用的数据结构之一,它为图像处理和分析提供了一个灵活而高效的工具。通过熟练使用 cv::Mat,你可以轻松处理各种图像处理任务,并实现各种图像处理算法。

cv::InputArray 详解

cv::InputArray 是 OpenCV 中的一个类,用于表示输入数据,例如图像、矩阵、数组等。它设计用于简化函数参数的传递,使其能够接受不同数据类型和数据源,从而提高函数的通用性。以下是关于 cv::InputArray 的详解:

  1. 概述: cv::InputArray 是一个模板类,它接受各种数据类型作为输入参数。它允许您传递以下类型的数据:

    • cv::Mat:OpenCV 的矩阵类,用于表示图像和多维数据。
    • cv::UMat:OpenCV 的UMat类,用于处理多线程和异构计算。
    • 数组指针:可以是 C/C++ 数组指针,如 float* data
    • STL 容器:例如,std::vectorstd::liststd::array
    • cv::Scalar:OpenCV 的标量类,用于表示颜色、强度等。
    • cv::Pointcv::Size:OpenCV 的点和大小类。
    • cv::InputArrayOfArrays:用于传递多个 cv::InputArray
  2. 构造函数: cv::InputArray 不需要显式创建对象,它可以通过传递参数构造。例如:

    1
    2
    
    cv::Mat image = cv::imread("image.jpg");
    cv::InputArray inputArray = image;
    

    或者直接在函数中传递:

    1
    2
    3
    
    void myFunction(cv::InputArray input) {
        // 使用 input 处理数据
    }
    
  3. 内部处理: cv::InputArray 内部会根据传递的数据类型和来源执行适当的数据转换,以便函数可以在不同数据源上工作。这包括数据的复制或引用,以确保数据在函数内部可用。

  4. 性能优化: OpenCV 会尽力优化 cv::InputArray,以避免不必要的数据复制,从而提高性能。这意味着通常情况下,不需要担心性能开销。

  5. 使用范例:

    1
    2
    3
    4
    5
    6
    7
    
    void processImage(cv::InputArray input) {
        cv::Mat inputMat = input.getMat(); // 获取输入数据的 Mat 表示
        // 在 inputMat 上执行图像处理操作
    }
    
    cv::Mat myImage = cv::imread("image.jpg");
    processImage(myImage); // 将图像传递给函数
    

cv::InputArray 是 OpenCV 函数设计中的重要工具,它使函数更加通用,可以接受不同类型的输入数据。这有助于提高代码的灵活性和可重用性。