opencv像素操作

1、遍历图像像素

int height = gray_src.rows;//获取图像行数
int width = gray_src.cols;//获取图像列数
for (int row = 0; row < height; row++) {//遍历图像各个像素点的像素值
for (int col = 0; col < width; col++) { }
}

2、获取图像像素值

  • 读一个GRAY像素点的像素值     

int gray = image.at<uchar>(row, col);

  • 读一个RGB像素点的像素值

int b = image.at<Vec3b>(row, col)[0];//获取row行col列0通道的像素值,Vec3b可以用来读取三通道的RGB图像像素值
int g = image.at<Vec3b>(row, col)[1];//获取row行col列1通道的像素值
int r = image.at<Vec3b>(row, col)[2];//获取row行col列2通道的像素值

注:

Vec3b:blue,green,red的uchar类型;Vec3f则表示blue,green,red的float类型

把CV_8UC1转换到CV32F1:   src.convertTo(dst,CV_32F);

3、修改像素值

  • 灰度图像

image.at<uchar> (row,col) = 目标像素值;

  • RGB三通道图像:

image.at<Vec3b>(row, col)[0] = 目标像素值;//修改row行col列0通道的像素值
image.at<Vec3b>(row, col)[1] = 目标像素值;//修改row行col列1通道的像素值
image.at<Vec3b>(row, col)[2] = 目标像素值;//修改row行col列2通道的像素值

  • 空间图像赋值

image = Scalar(0);

  • ROI选择

Rect r(10,10,100,100);

Mat smallImg = img(r);

  • 生成灰度图:

gray_src.at<uchar>(row, col) = min(r, min(b,g));//取RGB中的最小值作为灰度值
gray_src.at<uchar>(row, col) = max(r, max(b,g));//取RGB中的最大值作为灰度值

4、反转图像色彩

  • 反转灰度图像

gray_image.at<uchar>(row, col) = 255 - gray;

  • 反转RGB图像

image.at<Vec3b>(row, col)[0] = 255 - b;//反转row行col列0通道的像素值
image.at<Vec3b>(row, col)[1] = 255 - g;//反转row行col列1通道的像素值
image.at<Vec3b>(row, col)[2] = 255 - r;//反转row行col列2通道的像素值

  • 利用函数实现图像色彩反转bitwise_not(原图像, 反转后图像);

5、去掉图像某一通道色彩

image.at<Vec3b>(row, col)[0] = b;//保持row行col列0通道的像素值
image.at<Vec3b>(row, col)[1] = g;//保持row行col列1通道的像素值
image.at<Vec3b>(row, col)[2] = 0;//清零row行col列2通道的像素值


反转图像色彩示例代码:

Mat src;
src = imread("C:/Users/26839/Pictures/测试.png");
if (src.empty()) {
cout << "could not load image...\n" << endl;
return -1;
}
imshow("src", src);
Mat dst;
dst.create(src.size(), src.type());//构造一张与src大小类型一致的图片dst
int height = src.rows;
int width = src.cols;
int nc = src.channels();

for (int row = 0; row < height; row++) {//遍历图像各个像素点的像素值
for (int col = 0; col < width; col++) {
if (nc == 1) {//使单通道图片色彩反转
int gray = src.at<uchar>(row, col);//获取像素值
dst.at<uchar>(row, col) = 255 - gray;//反转图像
} else if (nc == 3) {//使3通道图片色彩反转
int r = src.at<Vec3b>(row, col)[0];//获取row行col列0通道的像素值,Vec3b可以用来读取三通道的RGB图像像素值
int g = src.at<Vec3b>(row, col)[1];//获取row行col列1通道的像素值
int b = src.at<Vec3b>(row, col)[2];//获取row行col列2通道的像素值
dst.at<Vec3b>(row, col)[0] = 255 - r;//反转row行col列0通道的像素值
dst.at<Vec3b>(row, col)[1] = 255 - g;//反转row行col列1通道的像素值
dst.at<Vec3b>(row, col)[2] = 255 - b;//反转row行col列2通道的像素值
}}}

//bitwise_not(src, dst);//反转图像色彩的函数
imshow("invert", dst);
waitKey(0);
destroyAllWindows();
return 0;


输出运行结果如下所示:

原始图像

在这里插入图片描述

反转处理后的图像

在这里插入图片描述

使用迭代器

迭代器(iterator)可以方便地遍历所有元素。Mat 也增加了迭代器的支持,以便于矩阵元素的遍历。使用迭代器,则无需用行数和列数遍历,所以没 i 、 j 变量,图像的像素值设置为一个随机数。

Mat grayim(600, 800, CV_8UC1);
Mat colorim(600, 800, CV_8UC3);

//遍历所有像素,并设置像素值

MatIterator_<uchar> grayit, grayend;     

for (grayit = grayim.begin<uchar>( ), grayend =grayim.end<uchar>( ); grayit != grayend; ++grayit)
              *grayit = rand() % 255;

//遍历所有像素,并设置像素值
MatIterator_<Vec3b> colorit, colorend;
for (colorit = colorim.begin<Vec3b>( ), colorend =colorim.end<Vec3b>( ); colorit != colorend; ++colorit)
{
(*colorit)[0] = rand() % 255; //Blue
(*colorit)[1] = rand() % 255; //Green
(*colorit)[2] = rand() % 255; //Red}
//显示结果
imshow("grayim", grayim);
imshow("colorim", colorim);
waitKey(0);
return 0;
输出结果:

通过数据指针

用 IplImage 结构时,会经常使用数据指针来直接操作像素。通过指针操作来访问像素非常高效。C/C++中的指针操作是不进行类型以及越界检查的,如果指针访问出错,程序运行时可能看上去一切正常,有时却突然弹出“段错误”(segment fault)。当程序规模较大且逻辑复杂时,查找指针错误十分困难。【注重程序运行速度,那么遍历像素时建议使用指针。】

用指针遍历图像中所有像素。

Mat grayim(600, 800, CV_8UC1);
Mat colorim(600, 800, CV_8UC3);
//遍历所有像素,并设置像素值
for (int i = 0; i < grayim.rows; ++i)
{
//获取第 i 行首像素指针
uchar * p = grayim.ptr<uchar>(i);
//对第 i 行的每个像素(byte)操作
for (int j = 0; j < grayim.cols; ++j)
p[j] = (i + j) % 255;
}

//遍历所有像素,并设置像素值
for (int i = 0; i < colorim.rows; ++i)
{
//获取第 i 行首像素指针
Vec3b * p = colorim.ptr<Vec3b>(i);
for (int j = 0; j < colorim.cols; ++j)
{
p[j][0] = i % 255; //Blue
p[j][1] = j % 255; //Green
p[j][2] = 0; //Red}}
//显示结果
imshow("grayim", grayim);
imshow("colorim", colorim);
waitKey(0);
return 0;

参考:

OpenCV4---像素操作(读写像素、修改像素值)_image.at<ushort>(row, col)-CSDN博客

opencv--像素值的读写_ptr<vec3b>(i, j)[0] = vec3b(0, 0, a)-CSDN博客

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值