OpenCV学习笔记与代码示例(二):访问图像像素与添加椒盐噪声

1.图像矩阵在内存中的储存方式

我们可以在OpenCV文档中找到图像在内存中的储存方式。矩阵的大小取决于所使用的颜色系统。更准确地说,它取决于使用的通道数量。在灰度图像的情况下,我们有类似的东西:

对于多通道图像,列包含与通道数一样多的子列。例如在 BGR 颜色系统的情况下:

 因为在许多情况下,内存足够大,可以以连续的方式存储行,这些行可能会一个接一个地跟随,从而创建一个长行。因为所有东西都在一个地方一个接一个地放在一个地方,这可能有助于加快扫描过程。

我们同时可以得到如下结论:在我们访问像素时,包含灰度图像的cv::Mat返回的是一个值,而彩色图像每个像素对应三个通道,因此包含彩色图像的cv::Mat类会返回一个向量

2.访问像素

利用cv::Mat类中的at(int y,int x)可以访问元素,其中y是行号,x是列号。使用该类需要指定返回值的预期类型(指定类型必须与矩阵内类型一致)。对于彩色图像返回的短向量类型,OpenCV定义了cv::Vec3b,我们可以利用它访问某个像素的某个通道值,也可以同时访问三个通道值。

int i, j;
image.at<uchar>(j,i) = 255;//访问灰度图像像素
image.at<cv::Vec3b>(j, i)[0] = 255;//访问彩色图像像素的通道B
image.at<cv::Vec3b>(j, i) = cv::Vec3b(255, 255, 255);//访问彩色图像像素的三个通道

如果我们已经知道矩阵的类型,可以使用cv::Mat类的模板子类cv::Mat_类,以避免代码冗长。

//使用Mat模板操作图像
cv::Mat_<uchar>img(image);
img(50, 100) = 0;//访问第50行第100列的值

3.应用:为图像加入椒盐噪声

#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include <random>
using namespace std;
using namespace cv;
void salt(cv::Mat image, int n) {
	//C++随机数生成器
	std::default_random_engine generator;
	std::uniform_int_distribution<int>
		randomRow(0, image.rows - 1);
	std::uniform_int_distribution<int>
		randomCol(0, image.cols - 1);
	int i, j;
	for (int k = 0; k < n; k++) {
		//随机生成图形位置
		i = randomCol(generator);
		j = randomRow(generator);
		if (image.type() == CV_8UC1) {//灰度图像
			//单通道8位图像
			image.at<uchar>(j, i) = 255;
		}
		else if (image.type()==CV_8UC3)//彩色图像
		{
			//3通道图像
			image.at<cv::Vec3b>(j, i) = cv::Vec3b(255, 255, 255);
		}
	}
}
int main() {
	cv::Mat image = cv::imread("1.bmp");
	salt(image, 3000);
    cv::namedWindow("Image");
	cv::imshow("Image", image);
	cv::waitKey(0);
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑化咸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值