OpenCV使用图像进行操作

发布时间:2024年01月21日

输入/输出

图像

C++爪哇岛蟒

从文件加载图像:

垫子 img = imread(文件名);

如果您读取 jpg 文件,则默认创建一个 3 通道图像。如果您需要灰度图像,请使用:

垫子 img = imread(文件名,IMREAD_GRAYSCALE);

注意

文件的格式由其内容(前几个字节)决定。要将图像保存到文件:

imwrite(文件名,img);

注意

文件的格式由其扩展名决定。

使用 cv::imdecode 和 cv::imencode?从内存而不是文件读取和写入图像。

图像的基本操作

访问像素强度值

C++爪哇岛蟒

为了获得像素强度值,您必须知道图像的类型和通道数。以下是单通道灰度图像(类型 8UC1)和像素坐标 x 和 y 的示例:

标量强度 = img.at<uchar>(y, x);

仅限 C++ 版本:intensity.val[0] 包含从 0 到 255 的值。注意 x 和 y 的顺序。由于在 OpenCV 中,图像由与矩阵相同的结构表示,因此我们对这两种情况使用相同的约定 - 从 0 开始的行索引(或 y 坐标)排在最前面,从 0 开始的列索引(或 x 坐标)紧随其后。或者,您可以使用以下表示法(仅限 C++):

标量强度 = img.at<uchar>(Point(x, y));

现在让我们考虑一个带有 BGR 颜色排序的 3 通道图像(imread 返回的默认格式):

C++ 代码

Vec3b 强度 = img.at<Vec3b>(y, x);
乌查尔蓝 = intensity.val[0];
乌查尔绿 = Intensity.Val[1];
乌查尔红 = 强度.val[2];

蟒蛇

_blue = img[y,x,0]
_green = img[y,x,1]
_red = img[y,x,2]

您可以对浮点图像使用相同的方法(例如,您可以通过在 3 通道图像上运行 Sobel 来获取此类图像)(仅限 C++):

Vec3f 强度 = img.at<Vec3f>(y, x);
浮动蓝色 = 强度。val[0];
浮点绿 = intensity.val[1];
浮点红 = intensity.val[2];

可以使用相同的方法更改像素强度:

img.at<uchar>(y, x) = 128;

OpenCV中有一些函数,特别是来自calib3d模块的函数,例如cv::p rojectPoints,它们以Mat的形式接受2D或3D点的数组。 矩阵应该正好包含一列,每行对应一个点,矩阵类型应该对应32FC2或32FC3。这样的矩阵可以很容易地从(仅限 C++)中构造:std::vector

vector<Point2f> 点;
...填充数组
垫子点Mat = 垫子(点);

可以使用相同的方法(仅限 C++)访问此矩阵中的点:Mat::at

Point2f 点 = pointsMat.at<Point2f>(i, 0);

内存管理和引用计数

C++爪哇岛蟒

Mat 是一种结构,用于保留矩阵/图像特征(行和列数、数据类型等)和指向数据的指针。因此,没有什么能阻止我们拥有对应于相同数据的多个 Mat 实例。Mat 保留一个引用计数,该计数指示在销毁特定 Mat 实例时是否必须释放数据。下面是在不复制数据的情况下创建两个矩阵的示例(仅限 C++):

std::vector<Point3f> 点;
..填充数组
垫点Mat = Mat(points).reshape(1);

结果,我们得到一个有 3 列的 32FC1 矩阵,而不是有 1 列的 32FC3 矩阵。 使用来自点的数据,并且在销毁时不会释放内存。然而,在这种特殊情况下,开发人员必须确保 的生存期长于 如果我们需要复制数据,可以使用例如 cv::Mat::copyTo 或 cv::Mat::clone:pointsMatpointspointsMat

垫子 img = imread“image.jpg”);
垫子 img1 = img.clone();

可以为每个功能提供一个空的输出垫。每个实现都为目标矩阵调用 Mat::create。如果矩阵为空,则此方法为矩阵分配数据。如果它不为空且具有正确的大小和类型,则该方法不执行任何操作。但是,如果大小或类型与输入参数不同,则会取消分配数据(并丢失)并分配新数据。例如:

垫子 img = imread“image.jpg”);
垫子索贝尔克斯;
索贝尔(img, sobelx, CV_32F, 1, 0);

基元操作

C++爪哇岛蟒

矩阵上定义了许多方便的运算符。例如,以下是我们如何从现有的灰度图像中制作黑色图像img

img = 标量(0);

选择感兴趣的区域:

矩形 r(10, 10, 100, 100);
垫子 smallImg = img(r);

从彩色到灰度的转换:

Mat img = imread“图像.jpg”);加载 8UC3 镜像
哑光灰色;
cvtColor(img, 灰色, COLOR_BGR2GRAY);

将映像类型从 8UC1 更改为 32FC1:

src.convertTo(dst, CV_32F);

可视化图像

C++爪哇岛蟒

在开发过程中查看算法的中间结果非常有用。OpenCV 提供了一种可视化图像的便捷方式。可以使用以下方式显示 8U 图像:

垫子 img = imread“image.jpg”);
namedWindow“图像”WINDOW_AUTOSIZE);
imshow“图像”, img);

对?waitKey()?的调用会启动一个消息传递周期,该周期在“image”窗口中等待击键。32F镜像需要转换为8U型。例如:

垫子 img = imread“image.jpg”);
哑光灰色;
cvtColor(img, 灰色, COLOR_BGR2GRAY);
垫子索贝尔克斯;
Sobel(灰色,sobelx,CV_32F,1,0);
double minVal, maxVal;
minMaxLoc(sobelx, &minVal, &maxVal);最小和最大强度
垫子拉;
sobelx.convertTo(draw, CV_8U, 255.0/(maxVal - minVal), -minVal * 255.0/(maxVal - minVal));
namedWindow“图像”WINDOW_AUTOSIZE);
imshow“图像”, 绘制);

注意

这里?cv::namedWindow?不是必需的,因为它紧随其后的是?cv::imshow。不过,它可用于更改窗口属性或使用?cv::createTrackbar?时

文章来源:https://blog.csdn.net/2301_81888214/article/details/135711946
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。