目录
1 图像的像素读写介绍
在利用opencv库进行图像处理时,有时对图像的像素进行读写是必不可少的一个处理过程中,在对图像读取时,针对不同的通道的图像有着不同的数据类型。例如在读取灰度图像和二值图像时一般采用的是uchar类型数据类型。而针对多通道的图像,例如3通道的RGB图像,一般根据图像存储的数据类型,包括int、float、double、uchar等常用类型,分为Vec3i、Vec3f、Vec3d、Vec3b等,针对不同的通道数,只需要更改数字即可,如Vec2i、Vec4i。
2 图像的像素读写方法详解
2.1 利用at对图像像素进行读写操作
例如单通道和3通道的RGB图像:
//单通道的读写像素值
for(int row =0;row < src.rows;row++)
{
for (int col =0;col < src.cols;col++)
{
int pixel = src.at<uchar>(row,col);
}
}
//多通道的读写像素值
for(int row =0;row < src.rows;row++)
{
for (int col =0;col < src.cols;col++)
{
int b = src.at<Vec3b>(row,col)[0];
int g = src.at<Vec3b>(row,col)[1];
int r = src.at<Vec3b>(row,col)[2];
}
}
2.2 利用指针ptr对图像像素进行读写操作
//单通道的读写像素值
for(int row =0;row < src.rows;row++)
{
uchar * data = src.ptr<uchar>(row);
for (int col =0;col < src.cols;col++)
{
int pixel = data[row];
}
}
//多通道的读写像素值
for(int row =0;row < src.rows;row++)
{
Vec3b * data1 = src.ptr<Vec3b>(row);
for (int col =0;col < src.cols;col++)
{
int b = data1[row][0];
int g = data1[row][1];
int r = data1[row][2];
}
}
2.3 利用迭代器对图像像素的读写操作
Mat类可以看作是一个容器变量,因此,其具有迭代器MatIterator_<>,我们可以根据迭代器对图像进行读写。
//单通道的读写像素值
Mat_<uchar> it = src.begin<uchar>();
Mat_<uchar> itend = src.end<uchar>();
for(;it < itend;it++)
{
int pixel = *it;
}
//多通道的读写像素值
Mat_<Vec3b> it = src.begin<Vec3b>();
Mat_<Vec3b> itend = src.end<Vec3b>();
for(;it < itend;it++)
{
int b = (*it)[0];
int g = (*it)[1];
int r = (*it)[2];
}
3 图像的像素读写代码实现
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
//读取图像
Mat src = imread("G:\\image\\lena.png");
Mat src1 = imread("G:\\image\\lena.png", IMREAD_GRAYSCALE);
if (src.empty())
{
cout << "could not load image" << endl;
}
//以at读取像素
//
//单通道的读写像素值
for (int row = 0; row < src1.rows; row++)
{
for (int col = 0; col < src1.cols; col++)
{
src1.at<uchar>(row, col) = 255;
}
}
//多通道的读写像素值
for (int row = 0; row < src.rows; row++)
{
for (int col = 0; col < src.cols; col++)
{
src.at<Vec3b>(row, col)[0] =255- src.at<Vec3b>(row, col)[0];
src.at<Vec3b>(row, col)[1]=255 - src.at<Vec3b>(row, col)[1];
src.at<Vec3b>(row, col)[2]= 255 - src.at<Vec3b>(row, col)[2];
}
}
//以指针方式读取
//单通道的读写像素值
for (int row = 0; row < src1.rows; row++)
{
uchar* data = src1.ptr<uchar>(row);
for (int col = 0; col < src1.cols; col++)
{
int pixel = data[row];
}
}
//多通道的读写像素值
for (int row = 0; row < src.rows; row++)
{
Vec3b* data1 = src.ptr<Vec3b>(row);
for (int col = 0; col < src.cols; col++)
{
int b = data1[row][0];
int g = data1[row][1];
int r = data1[row][2];
}
}
//利用迭代器读写像素值
//单通道的读写像素值
//单通道的读写像素值
MatIterator_<uchar> it = src1.begin<uchar>();
MatIterator_<uchar> itend = src1.end<uchar>();
for (; it < itend; it++)
{
int pixel = *it;
}
//多通道的读写像素值
MatIterator_<Vec3b> it1 = src.begin<Vec3b>();
MatIterator_<Vec3b> itend1 = src.end<Vec3b>();
for (; it1 < itend1; it1++)
{
int b = (*it1)[0];
int g = (*it1)[1];
int r = (*it1)[2];
}
//创建窗口
namedWindow("input", WINDOW_AUTOSIZE);
//显示图像
imshow("input", src);
//显示时间
waitKey(0);
return 0;
}