opencv01-像素的访问

本文介绍使用OpenCV的不同方法来访问图像像素,并通过三种方法对比实现图像中添加椒盐噪声的过程,展示了不同访问效率的特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

opencv01-像素的访问

对于opencv像素的访问,可以有很多种方法,不同的访问方式有着不同的效率。
下面我们将用不同的访问像素的方法来对图像随机加一些椒盐噪声


  • 方法一:
void salt(Mat &img, int n){
	for (int k = 0; k < n; k++){ //添加k个随机噪声
		int i = rand() % img.cols;//其随机域为0~img.cols-1
		int j = rand() % img.rows;

		if (img.channels() == 1){ //灰度图像
			img.at<uchar>(j, i) = 255;
		}
		else if (img.channels() == 3){
			img.at<Vec3b>(j, i)[0] = 255; //B
			img.at<Vec3b>(j, i)[1] = 255; //G
			img.at<Vec3b>(j, i)[2] = 255; //R
		}
	}
}

方法一是通过img.at实现访问,灰度图像每个像素是uchar类型,所以是img.at< uchar>(j, i)。而RGB图像有三个通道,每个通道的像素也是uchar类型,因此是Vec3b。

  • 方法二
void salt2(Mat &img, int n){
	for (int k = 0; k < n; k++){
		int i = rand() % img.rows;//其随机域为0~img.cols-1
		int j = rand() % img.cols;
		int nl = i * img.channels();

		if (img.channels() == 1){
			uchar* data = img.ptr<uchar>(i);
			*(data + j) = 255;
		}
		else if (img.channels() == 3){
			Vec3b* data = img.ptr<Vec3b>(i);
		
			(*(data + j))[0] = 255;
			(*(data + j))[1] = 255;
			(*(data + j))[2] = 255;
		}
	}
}

方法二用指针访问像素。如果是灰度图像,img.ptr < uchar>(i)得到的是i行第一个像素的地址。所以,(data + j)就可以获取到i行j列的像素了。
对于RGB图像,img.ptr< Vec3b>(i)得到的也是i行第一个像素的地址,但要注意的是这个地址对应有三个值了。(
(data + j))[0]就可以获取行j列的像素B通道的值了。

  • 方法三:
void salt3(Mat &img, int div){
	int nl = img.rows; //行数
	int nc = img.cols * img.channels();

	if (img.isContinuous()){ //非边界像素
		nc = nc * nl;
		nl = 1;
	}

	for (int j = 0; j < nl; j++){
		uchar* data = img.ptr<uchar>(j);
		for (int i = 0; i < nc; i++){
			*(data + i) = *(data + i) / div*div + div / 2;
		}
	}
}

方法三做的事情就是把像素RGB通道的值放在一起。当是连续的像素时,即非边界的像素,一个循环for (int j = 0; j < nc; j++)来访问所有像素的BGR值。

显然,方法三具有最高的访问效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值