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
指针遍历
//指针
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 指针遍历