概述
在本专栏的第一篇文章中就介绍了一个用OpenCV处理图片的实例(《图片处理基础》),这篇文章进一步详细介绍OpenCV中处理图片的一些操作。
我这里使用的都是C++20的初始化语法,之前版本的C++可以参考下面这节中不同版本C++语法的对比。
图片的导入和保存
从图片文件中导入图片数据:
Mat img = imread(filename);
Mat imgCpp20 {
imread(filename) }; //C++20的初始化语法
如果导入的是jpg格式的图片,那么默认是3通道的图像数据。如果想要以灰度(只有黑白两色)格式导入,可以这样导入:
Mat img = imread(filename, IMREAD_GRAYSCALE);
Mat imgCpp20 {
imread(filename, IMREAD_GRAYSCALE) }; //C++20的初始化语法
要将数据保存到图片:
imwrite(filename, img);
对导入的图片的操作
获取像素值
要获取像素的值,必须要知道图片的类型以及颜色通道数量。
关于图片数据的类型,可以参考该合集中的《基本图像容器——Mat》
如果要获取一个单通道灰度图片(即,8UC1类型)中(x, y)坐标上的像素的值,可以使用下面这条语句:
Scalar intensity {
img.at<uchar>(y, x) };
**注意这里坐标的表示是(y, x)
。**因为在OpenCV中图片都是用矩阵来表示的,而矩阵一般是通过(row, col)
的先行后列的模式来定位的,为了统一,OpenCV中坐标的表示也是纵坐标在前、横坐标在后。
在C++中,还可以使用Point
来换回传统的坐标表示:
Scalar intensity {
img.at<uchar>(Point(x, y) };
如果是3通道的BGR格式的图片,要获取某个像素上每个通道的颜色值,可以使用以下方法:
Vec3b intensity {
img.at<Vec3b>(y, x) };
uchar blue {
intensity.val[0] };
uchar green {
intensity.val[1] };
uchar red {
intensity.val[2] };
可以看到,储存单通道的像素值,使用的是Scalar
类型;而储存3通道的像素值,使用的是Vec3b
类型;3通道中单个通道的颜色值则是uchar
类型。
获取像素值的方法也可以用来修改像素值:
img.