持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情
前言
为了访问矩阵的每个独立元素,只需要指定其行号和列号,将返回相应的元素,在多通道图像的情况下,它可以是单个数值或值的向量。
访问像素值
为了介绍如何对像素值进行访问,我们首先创建一个简单的函数,为图像添加椒盐噪声,椒盐噪声是一种特殊类型的噪声,其中使用白色或黑色像素替换一些随机选择的像素,当某些像素的值在传输过程中丢失时,可能会出现这种类型的噪声。在示例代码中,我们简单地随机选择几个像素并将它们修改为白色值。
接下来我们将创建一个盐噪声函数,并在程序中使用此函数。
1. 创建一个接收输入图像和数字的函数。第一个参数是函数修改的图像,第二个参数是要被覆盖为白色值的像素数量:
void salt(cv::Mat image, int n);
2. 定义两个变量,使用它们来存储图像上的随机位置:
int i, j;
3. 创建一个迭代 n 次的循环。其中 n 就是 salt 函数中的第二个参数,它定义了要被覆盖为白色值的像素数量:
for (int k=0; k<n; k++) {
4. 使用 std::rand() 函数生成两个值用于表示随机图像坐标位置,将 x 坐标值存储在 i 变量中,将 y 坐标值存储在 j 变量中。std::rand() 函数可以返回一个介于 0 和 RAND_MAX 之间的值,然后我们应用求模运算 % (使用图像的列数或行数),以返回介于 0 和图像宽度或高度之间的值:
i= std::rand()%image.cols;
j= std::rand()%image.rows;
5. 使用 type 方法,我们可以区分灰度图像和彩色图像。对于灰度图像,使用 Mat 函数 at<type>(y,x) 可以修改位于坐标 (y,x) 处的图像像素值,使用以下方法将单个像素( 8 位值)修改为值 255:
if (image.type() == CV_8UC1) { // 灰度图像
// 单通道 8 bit 图像
image.at<uchar>(j,i)= 255;
}
6. 对于彩色图像,需要为三基色通道同时分配值 255 以获得白色像素。我们可以使用数组访问 (nChannel) 访问图像通道,其中 nChannel 是通道索引,0 表示蓝色,1 表示绿色,2 表示红色:
else if (image.type() == CV_8UC3) { // 彩色图像
// 3通道图像
image.at<cv::Vec3b>(j,i)[0]= 255;
image.at<cv::Vec3b>(j,i)[1]= 255;
image.at<cv::Vec3b>(j,i)[2]= 255;
}
完成函数的编写后,使用闭括号结束循环和函数体。
7. 要使用 salt 函数,我们首先从磁盘读取图像:
cv::Mat image= cv::imread("1.png",1);
8. 然后,使用加载的图像和要更改的像素数量(例如,3000) 调用 salt 函数:
salt(image,3000);
9. 最后,使用 cv::imshow 函数显示图像:
cv::namedWindow("Image");
cv::imshow("Image",image);
生成的图像结果如下所示: