OpenCV图像像素遍历与访问

遍历方式有很多种,下面给出两种方式:

  • 基于数组遍历
  • 基于指针遍历

1、基于数组遍历
Mat类中的cols、rows为图像的宽、高。成员函数at(row,col)可以存取图像元素。对于包含彩色图像的Mat,OpenCV中将三个8位数组组成的向量定义为Vec3b。
访问彩色图像像素的一般形式:

 image.at<Vec3b>(j, i)[channel] = value;

程序演示:

#include<opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {
	Mat src = imread("D:/VC2017_WORKSPACE/Images/dog.jpg", IMREAD_COLOR);
	if (src.empty()) {
		printf("could not find image file");
		return -1;
	}
	namedWindow("demo-002", WINDOW_FREERATIO);
	imshow("demo-002", src);
	//获取图像的宽度、高度、通道数
	int width = src.cols;
	int height = src.rows;
	int dim = src.channels();

	//像素遍历
	for (int row = 0; row < height; row++) {
		for (int col = 0; col < width; col++) {
			if (dim == 3) {//彩色图像遍历
				Vec3b pixel = src.at<Vec3b>(row, col);
				int blue = pixel[0];
				int green = pixel[1];
				int red = pixel[2];
				//取反
				src.at<Vec3b>(row, col)[0] = 255 - blue;
				src.at<Vec3b>(row, col)[1] = 255 - green;
				src.at<Vec3b>(row, col)[2] = 255 - red;
			}

			if (dim == 1) {//灰度图像遍历
				uchar pv = src.at<uchar>(row, col);
				//取反
				src.at<uchar>(row, col) = (255 - pv);
			}
		}
	}
	namedWindow("pixel-demo", WINDOW_FREERATIO);
	imshow("pixel-demo", src);
	waitKey(0);
	destroyAllWindows();
	return 0;
}

显示结果:
在这里插入图片描述
2、基于指针遍历
Mat类提供了ptr函数可以得到图像任意行的首地址。ptr是一个模板函数,返回值为第i行的首地址,一般形式如下:

uchar* data = image.ptr<uchar>(i);

程序演示:

#include<opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {
	Mat src = imread("D:/VC2017_WORKSPACE/Images/dog.jpg", IMREAD_COLOR);
	if (src.empty()) {
		printf("could not find image file");
		return -1;
	}
	namedWindow("原图", WINDOW_FREERATIO);
	imshow("原图", src);
	//获取图像的宽度、高度、通道数
	int width = src.cols;
	int height = src.rows;
	int dim = src.channels();

	//像素遍历
	Mat result = Mat::zeros(src.size(), src.type());//后面用来观察遍历结果,作对比
	for (int row = 0; row < height; row++) {

		uchar* curr_row = src.ptr<uchar>(row);//获取当前行的指针
		uchar* result_row = result.ptr<uchar>(row);//获取result图像的行指针

		for (int col = 0; col < width; col++) {
			if (dim == 3) {//彩色图像遍历

				int blue = *curr_row++;
				int green = *curr_row++;
				int red = *curr_row++;

				//访问的每个通道的像素赋值给result
				*result_row++ = blue;
				*result_row++ = green;
				*result_row++ = red;

			}

			if (dim == 1) {//灰度图像遍历

				int pv = *curr_row++;
				*result_row++ = pv;

			}
		}
	}
	namedWindow("原图像素遍历后赋值给result的结果", WINDOW_FREERATIO);
	imshow("原图像素遍历后赋值给result的结果", result);
	waitKey(0);
	destroyAllWindows();
	return 0;
}

效果显示:
在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值