OpenCV学习笔记-day4 图像像素的读写操作(数组遍历和指针遍历实现,uchar Vec3b 数据类型以及mat类函数 Mat::at()、Mat::ptr())

day4-图像像素的读写操作(数组和指针)

数据类型

uchar

uchar是无符号的字符类型,数值范围为0~255,在图像处理中表示像素值范围时用的多

Vec3b

表示每一个Vec3b对象中,存储3个char(字符型)数据,可以去存储RGB图像中的一个像素点
例1
描述一种RGB颜色:

Vec3b color;
color[0]=0;//B分量
color[1]=0;//G分量
color[2]=255;//R分量

函数

at()函数 Mat类

返回指定数组元素
对于单通道图像"picture1",picture1.at(i,j)就表示在第i行第j列的像素值。

对于多通道图像如RGB图像"picture2",可以用picture2.at(i,j)[c]来表示某个通道中在(i,j)位置的像素值。

//定义
_Tp& Mat::at(int i0, int i1)
{
    CV_DbgAssert(dims <= 2);
    CV_DbgAssert(data);
    CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
    CV_DbgAssert((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()));
    CV_DbgAssert(CV_ELEM_SIZE1(traits::Depth<_Tp>::value) == elemSize1());
    return ((_Tp*)(data + step.p[0] * i0))[i1];
}

例2

if (dims == 1)//单通道
{
	int pv = image.at<uchar>(row, col);
	//读取为uchar类型(0-255 八位) 
	//转成int类型赋值给 pv  image.at
	image.at<uchar>(row, col) = 255 - pv;
}//遍历灰度图像并取反色图

例3

if (dims==3)
{
	Vec3b bgr=image.at<Vec3b>(row, col);//读取每个像素点的三个值bgr[0],bgr[1],bgr[2],赋值给bgr  可以用picture2.at<Vec3b>(i,j)[c]
	//给当前RGB色彩空间的像素三个颜色通道取反值
	image.at<Vec3b>(row, col)[0]=255-bgr[0];
	//像素 b通道 255-bgr[]:取图像反色
	image.at<Vec3b>(row, col)[1] = 255 - bgr[1];
	//像素 g通道
	image.at<Vec3b>(row, col)[2] = 255 - bgr[2];
	//像素 r通道
}//遍历彩色图像并取反色图
ptr()函数 Mat类

返回指定位置的指针

//定义
_Tp* Mat::ptr(int y)
{
    CV_DbgAssert( y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) );
    return (_Tp*)(data + step.p[0] * y);
}

例4

//指针类型为 uchar
uchar* current_row = image.ptr<uchar>(row);
//指向第row行的第一个元素

代码

数组遍历
quickopencv.h

#pragma once

#include <opencv2\highgui.hpp>

#include <opencv2\imgproc.hpp>

using namespace cv;
//定义类
class QuickDemo{
public:
	void colorSpace_Demo(Mat &image);
	//色彩空间转换函数2021-12-24
	void mat_creation_demo(Mat &image);
	//Mat对象与创建2021-12-27
	void pixel_vist_Demo(Mat &image);
	//图像像素的读写操作2022-1-3
};

QuickDemo.cpp

void QuickDemo::pixel_vist_Demo(Mat &image){
	int w = image.cols;
	int h = image.rows;
	int dims = image.channels();
	//数组
	for (int row = 0; row < h; row++)
	{
		for (int col = 0; col < w; col++)
		{
			if (dims == 1)
			{
			//读取一个灰度图像的像素值
				int pv = image.at<uchar>(row, col);//读取为uchar类型(0-255 八位) 转成int类型赋值给 pv  (image.at)
				image.at<uchar>(row, col) = 255 - pv;
			}//遍历灰度图像并取反色图
			if (dims==3)
			{
				Vec3b bgr=image.at<Vec3b>(row, col);//读取每个像素点的三个值bgr[0],bgr[1],bgr[2],赋值给bgr
				//给当前RGB色彩空间的像素三个通道取反值
				image.at<Vec3b>(row, col)[0]=255-bgr[0];//像素 b通道 255-bgr[]:取图像反色
				image.at<Vec3b>(row, col)[1] = 255 - bgr[1];//像素 g通道
				image.at<Vec3b>(row, col)[2] = 255 - bgr[2];//像素 r通道
			}//遍历彩色图像并取反色图--显示效果1

		}//for
	}//for
	namedWindow("像素读写显示", WINDOW_NORMAL);
	imshow("像素读写显示", image);
}//pixel_vist_Demo
#include <iostream>
#include <opencv2\highgui.hpp>
#include <opencv2\imgproc.hpp>
#include<quickopencv.h>

using namespace cv;
using namespace std;

int main()
{
	Mat scr = imread("...\\image\\1.jpg");//打开一张图
	if (!scr.data == 1)//判空
		return -1;
	QuickDemo qd;
	qd.pixel_vist_Demo(scr);//图像像素的读写操作(数组遍历和指针遍历 功能取反色)
	waitKey(0);
	return 0;
}

显示效果1
显示效果1-3通道每个像素都反色后
指针遍历

//指针
void QuickDemo::pixel_vist_Demo(Mat &image){
	int w = image.cols;
	int h = image.rows;
	int dims = image.channels();
	int temp = 0;
	for (int row = 0; row < h; row++)
	{
		uchar* current_row = image.ptr<uchar>(row);//xxx.ptr<uchar>(row):获取当前行的指针current_row 
		for (int col = 0; col < w*dims; col++)//三通道共 row*col*dims 个元素 不明白请查看 day3建立空白图像笔记
		{
			if (dims == 1)
			{
				int pv = *current_row;//读取指针指向的当前行第一个元素
				*current_row++ = 255 - pv;//直到加到当前行结束 第二个for循环退出 开始下一行
			}//遍历灰度图像并取反色图
			if (dims == 3)
			{
				*current_row++ = 255;
				temp++;

			}//遍历彩色图像并取反色图--显示结果2

		}//for
	}//for
	namedWindow("像素读写显示", WINDOW_NORMAL);
	imshow("像素读写显示", image);
}//pixel_vist_Demo 指针遍历

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值