OpenCV学习2:访问像素值

前言

开局一张图,内容全靠编。

访问像素值

函数 at()实现读去矩阵中的某个像素,或者对某个像素进行赋值操作。
例如:

uchar value = image.at<uchar>(i,j);//读出第 i 行第 j 列像素值
image.at<uchar>(i,j)=128; //将第 i 行第 j 列像素值设置为 128

在图像中加入椒盐噪声

椒盐噪声是一个专门的噪声类型,它随机选择一些像素,把它们的颜色替换成白色或黑色。如果通信时出错,部分像素的值在传输时丢失,就会产生这种噪声。这里只是随机选择一些像素,把它们设置为白色。

函数声明:
void salt(cv::Mat image, int n);
函数定义:
void salt(cv::Mat image, int n) {
	// C++11 的随机数生成器
	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)[0] = 255;
			image.at<cv::Vec3b>(j, i)[1] = 255;
			image.at<cv::Vec3b>(j, i)[2] = 255;
		}
	}
}

这个函数使用一个简单的循环,执行 n 次,每次都把随机选择的像素设置为 255。这里用随机数生成器生成像素的列 i 和行 j。请注意,这里使用了 type 方法来区分灰度图像和彩色图像。对于灰度图像,把单个的 8 位数值设置为 255;对于彩色图像,需要把三个主颜色通道都设置为255 才能得到一个白色像素。

测试代码:
#include <iostream> 
#include <random>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>

void salt(cv::Mat image, int n);
void salt(cv::Mat image, int n) {
	// C++11 的随机数生成器
	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)[0] = 255;
			image.at<cv::Vec3b>(j, i)[1] = 255;
			image.at<cv::Vec3b>(j, i)[2] = 255;
		}
	}
}

int main()
{
	// 打开图像
	cv::Mat image = cv::imread("test.bmp", 1);
	if (image.empty()) { // 错误处理
						 // 未创建图像……
						 // 可能显示一个错误消息
						 // 并退出程序
		std::cout << "no image!\n";
	}
	else
	{
		// 调用函数以添加噪声
		salt(image, 3000);
		// 显示结果
		cv::namedWindow("Image");
		cv::imshow("Image", image);
		cv::waitKey(0); // 等待按键
	}
	system("pause");
	return 0;
}
测试结果:

原图:
在这里插入图片描述
处理后图片:
在这里插入图片描述
OpenCV 存储通道数据的次序是蓝色(B)、绿色(G)和红色(R)

img.at<Vec3b>(row, col)[0] = 255;  // 这是指修改B通道数据
img.at<Vec3b>(row, col)[1] = 255;  // 这是指修改G通道数据
img.at<Vec3b>(row, col)[2] = 255;  // 这是指修改R通道数据
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值