OpenCV 对图片的基本操作(nice)

简介: OpenCV 对图片的基本操作 输入/输出 图像 从文件加载图像 Mat img = imread(filename) 如果你加载的是 JPG 文件,将会默认创建一个 3 通道的图像,如果你需要灰度图,可以用: Mat img = imread(filename, 0); 注意 文件的根据市根据文件内容自动识



输入/输出

图像

从文件加载图像

Mat img = imread(filename)

如果你加载的是 JPG 文件,将会默认创建一个 3 通道的图像,如果你需要灰度图,可以用:

Mat img = imread(filename, 0);

注意

文件的根据市根据文件内容自动识别的(一般是前几个字节的内容)

将突破保存到文件:

imwrite(filename, img);

注意

文件的格式是通过其扩展名进行识别.

注意

请使用 imdecode 和 imencode 来读写内存中的图片,而不是文件中的图片。

XML/YAML

待处理

基本的图像操作

访问像素强度值

为了获得像素强度值,你需要知道图片的类型已经包含多少个通道。这里是一个单通道灰度图的例子(8UC1 类型), 其像素坐标为 x 和 y:

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

intensity.val[0] 包含了值范围从 0 到 255。请注意 x 和 y 参数的顺序。因为 OpenCV 的图像是使用和阵列相同结构的方式存储,我们使用相同的约定来处理两种方式:基于 0 的行索引(或者称为纵坐标)作为首个参数以及基于 0 的列索引(横坐标)跟进其后。你也可以使用下面的方式来代替:

Scalar intensity = img.at<uchar>(Point(x, y));

现在让我们考虑一个使用 BGR 色彩顺序 3 通道的图像(通过 imread 返回默认的格式):

Vec3b intensity = img.at<Vec3b>(y, x);
uchar blue = intensity.val[0];
uchar green = intensity.val[1];
uchar red = intensity.val[2];

你可以对浮点图像使用相同的方法(例如通过运行 Sobel 在一个三通道图像来获取图像):

Vec3f intensity = img.at<Vec3f>(y, x);
float blue = intensity.val[0];
float green = intensity.val[1];
float red = intensity.val[2];

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

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

OpenCV 的 calib3d 模块有很多函数,例如 projectPoints 使用 Mat 形式来获取 2D 和 3D 点的数组。矩阵包含了一列数据,每一行对应一个点,矩阵类型可以是 32FC2 或者 32FC3。可以使用 std::vector 来构建一个矩阵:

vector<Point2f> points;
//... fill the array
Mat pointsMat = Mat(points);

你可以使用 Mat::at 方法来访问阵列中的点:

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

内存管理与引用计数

Mat 是一个用来保存阵列/图像特征的数据结构(包含行列编号、数据类型等),同时包含了指向数据的指针。因此同一个数据我们可以有多个 Mat 实例。一个 Mat 实例保存了一个数据的引用计数,当 Mat 实例被销毁时引用计数会减一。下面是一个无需拷贝数据的情况下创建两个矩阵的示例代码:

std::vector<Point3f> points;
// .. fill the array
Mat pointsMat = Mat(points).reshape(1);

上述结果返回一个 32FC1 的矩阵,包含 3 列数据,而不是 32FC3 的 1 列数据。pointsMat 使用这些点数据,在销毁的时候不会释放内存。在这个特定的情况下,开发者必须确保点阵的生命周期比 pointsMat 要长才行。如果我们需要复制数据,可以使用 Mat::copyTo 或者 Mat::clone:

Mat img = imread("image.jpg");
Mat img1 = img.clone();

与开发人员所创建的输出图像的相反,一个空的输出 Mat 可以提供给每个函数。该方法为一个空的矩阵分配数据。如果矩阵的数据和类型都无误,则该方法什么都不做。如果输入参数的大小和类型不一致,该数据就会被释放(并丢失)然后分配新的数据,例如:

Mat img = imread("image.jpg");
Mat sobelx;
Sobel(img, sobelx, CV_32F, 1, 0);

基本操作

一个阵列有很多的基本操作。例如我们可以从一个已有的灰度图总生成一个黑色图像::

img = Scalar(0);

Selecting a region of interest:

Rect r(10, 10, 100, 100);
Mat smallImg = img(r);

将 Mat 转成 C API 数据结构:

Mat img = imread("image.jpg");
IplImage img1 = img;
CvMat m = img;

注意这里没有做任何的数据拷贝。

将彩色图转成灰度图:

Mat img = imread("image.jpg"); // loading a 8UC3 image
Mat grey;
cvtColor(img, grey, CV_BGR2GRAY);

将图片类型从 8UC1 改为 32FC1:

src.convertTo(dst, CV_32F);

图像显示

在开发过程中看到通过你算法出来的图片是很爽的。OpenCV 提供了一个便捷的方式来显示图像。一个8U图像可以使用如下代码显示:

Mat img = imread("image.jpg");

namedWindow("image", CV_WINDOW_AUTOSIZE);
imshow("image", img);
waitKey();

waitKey() 方法调用开始一个消息的传递循环,等待用户在图像窗口中按键。32F 的图像需要转成 8U 才可以显示,例如:

Mat img = imread("image.jpg");
Mat grey;
cvtColor(img, grey, CV_BGR2GRAY);

Mat sobelx;
Sobel(grey, sobelx, CV_32F, 1, 0);

double minVal, maxVal;
minMaxLoc(sobelx, &minVal, &maxVal); //find minimum and maximum intensities
Mat draw;
sobelx.convertTo(draw, CV_8U, 255.0/(maxVal - minVal), -minVal * 255.0/(maxVal - minVal));

namedWindow("image", CV_WINDOW_AUTOSIZE);
imshow("image", draw);
waitKey();

目录
相关文章
|
2月前
|
计算机视觉
Opencv学习笔记(十二):图片腐蚀和膨胀操作
这篇文章介绍了图像腐蚀和膨胀的原理、作用以及使用OpenCV实现这些操作的代码示例,并深入解析了开运算和闭运算的概念及其在图像形态学处理中的应用。
126 1
Opencv学习笔记(十二):图片腐蚀和膨胀操作
|
2月前
|
计算机视觉 Python
Opencv学习笔记(二):如何将整个文件下的彩色图片全部转换为灰度图
使用OpenCV库将一个文件夹内的所有彩色图片批量转换为灰度图,并提供了相应的Python代码示例。
37 0
Opencv学习笔记(二):如何将整个文件下的彩色图片全部转换为灰度图
|
2月前
|
计算机视觉 Python
Opencv学习笔记(一):如何将得到的图片保存在指定目录以及如何将文件夹里所有图片以数组形式输出
这篇博客介绍了如何使用OpenCV库在Python中将图片保存到指定目录,以及如何将文件夹中的所有图片读取并以数组形式输出。
154 0
Opencv学习笔记(一):如何将得到的图片保存在指定目录以及如何将文件夹里所有图片以数组形式输出
|
7月前
|
监控 API 计算机视觉
OpenCV这么简单为啥不学——1.13图片冷白皮(美白)处理
OpenCV这么简单为啥不学——1.13图片冷白皮(美白)处理
71 0
|
7月前
|
存储 编解码 监控
OpenCV这么简单为啥不学——2.1、imwrite逐帧保存图片
OpenCV这么简单为啥不学——2.1、imwrite逐帧保存图片
121 0
|
7月前
|
人工智能 Linux API
OpenCV这么简单为啥不学——1.1、图像处理(灰度图、模糊图片、GaussianBlur函数、提取边缘、边缘膨胀、边缘细化)
OpenCV这么简单为啥不学——1.1、图像处理(灰度图、模糊图片、GaussianBlur函数、提取边缘、边缘膨胀、边缘细化)
106 0
|
2月前
|
计算机视觉
Opencv错误笔记(一):通过cv2保存图片采用中文命名出现乱码
在使用OpenCV的cv2模块保存带有中文命名的图片时,直接使用cv2.imwrite()会导致乱码问题,可以通过改用cv2.imencode()方法来解决。
148 0
Opencv错误笔记(一):通过cv2保存图片采用中文命名出现乱码
|
4月前
|
计算机视觉 Windows Python
windows下使用python + opencv读取含有中文路径的图片 和 把图片数据保存到含有中文的路径下
在Windows系统中,直接使用`cv2.imread()`和`cv2.imwrite()`处理含中文路径的图像文件时会遇到问题。读取时会返回空数据,保存时则无法正确保存至目标目录。为解决这些问题,可以使用`cv2.imdecode()`结合`np.fromfile()`来读取图像,并使用`cv2.imencode()`结合`tofile()`方法来保存图像至含中文的路径。这种方法有效避免了路径编码问题,确保图像处理流程顺畅进行。
369 1
|
2月前
|
Serverless 计算机视觉
语义分割笔记(三):通过opencv对mask图片来画分割对象的外接椭圆
这篇文章介绍了如何使用OpenCV库通过mask图像绘制分割对象的外接椭圆。首先,需要加载mask图像,然后使用`cv2.findContours()`寻找轮廓,接着用`cv2.fitEllipse()`拟合外接椭圆,最后用`cv2.ellipse()`绘制椭圆。文章提供了详细的代码示例,展示了从读取图像到显示结果的完整过程。
58 0
语义分割笔记(三):通过opencv对mask图片来画分割对象的外接椭圆
|
4月前
|
存储 编解码 API
python多种方法压缩图片,opencv、PIL、tinypng、pngquant压缩图片
python多种方法压缩图片,opencv、PIL、tinypng、pngquant压缩图片
296 1