您的位置:首页 > 运维架构

【OpenCV】之图像像素访问方法

2018-03-05 15:03 253 查看
任何图像处理算法,都是从操作图像中的每个像素开始的。


图像的存储:

1.单通道图像



2.多通道图像



【方法1】指针访问像素:
访问速度最快

用指针访问像素是C语言中操作符[ ]。

图像中每行像素的个数:
每行像素数=列数 X 通道数


Mat类提供了ptr函数可得到图像任意行的首地址。

// 获取i行的首地址
uchar *data = image.ptr<uchar>(i);


//--------------【colorReduce()函数】---------------//
//  Description:通过指针实现颜色空间缩减函数
//-------------------------------------------------
void colorReduce(Mat &srcImg, Mat &dstImg, int div)
{
// 设置参数
dstImg = srcImg.clone(); // 设置目标图像与源图像一样
int rowNum = dstImg.rows; // 行数
int colNum = dstImg.cols * dstImg.channels(); // 每行像素数 = 列数 x 通道数

// 双重循环,遍历所有的像素值
for (int i = 0; i < rowNum; i++) // 行循环
{
uchar *data = dstImg.ptr<uchar>(i); // 获取第i行的首地址
for (int j = 0; j < colNum; j++) // 列循环
{
// 开始处理每个像素
data[j] = data[j] / div * div + div / 2;
} // 处理完一行,进行下一行像素处理
}
}


【方法2】迭代器操作像素
在迭代法中,我们只需获取图像矩阵的begin和end,然后增加迭代直至从begin到end。将*操作符添加在迭代指针前,即可访问当前指向的内容。

相比用指针直接访问像素可能出现越界问题,迭代器绝对是非常安全的方法。

该方法与STL库的用法类似

//--------------【colorReduce()函数】---------------//
//  Description:通过迭代器实现颜色空间缩减函数
//-------------------------------------------------
void colorReduce(Mat &srcImg, Mat &dstImg, int div)
{
// 设置参数
dstImg = srcImg.clone(); // 设置目标图像与源图像一样
// 获取迭代器
Mat_<Vec3b>::iterator it = dstImg.begin<Vec3b>(); // 初始位置的迭代器
Mat_<Vec3b>::iterator itEnd = dstImg.end<Vec3b>(); // 终止位置的迭代器

// 存取彩色图像像素
for (; it != itEnd; it++) // 行循环
{
// 开始处理每个像素
(*it)[0] = (*it)[0] / div * div + div / 2;
(*it)[1] = (*it)[1] / div * div + div / 2;
(*it)[2] = (*it)[2] / div * div + div / 2;
}
}


注意:(*it)[0]代表蓝色通道像素值,(*it)[1]代表绿色通道像素值,(*it)[2]代表红色通道像素值。
在OpenCV中,RGB存储是顺序是BGR


【方法3】动态地址访问
该方法较直观,但耗时最长。

//--------------【colorReduce()函数】---------------//
//  Description:通过动态地址实现颜色空间缩减函数
//-------------------------------------------------
void colorReduce(Mat &srcImg, Mat &dstImg, int div)
{
// 设置参数
dstImg = srcImg.clone(); // 设置目标图像与源图像一样
int rowNum = dstImg.rows; // 行数
int colNum = dstImg.cols ; // 列数

// 存取彩色图像像素
for (int i = 0; i < rowNum; i++) // 行循环
{
for (int j = 0; j < colNum; j++) // 列循环
{
// 开始处理每个像素
dstImg.at<Vec3b>(i,j)[0] = dstImg.at<Vec3b>(i,j)[0] / div * div + div / 2; // 蓝色通道
dstImg.at<Vec3b>(i,j)[1] = dstImg.at<Vec3b>(i,j)[1] / div * div + div / 2; // 绿色通道
dstImg.at<Vec3b>(i,j)[2] = dstImg.at<Vec3b>(i,j)[2] / div * div + div / 2; // 红色通道
} // 处理完
}
}


Mat 类中的cols和rows给出了图像的宽和高。而成员函数at(int y, int x)可用来存取图像元素,但必须在编译期知道图像的数据类型。

在OpenCV将彩色图像的类型的向量定义为Vec3b,即由三个unsigned char 组成的向量。

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


【摘引:】

《OpenCV3编程入门》

https://www.cnblogs.com/skyfsm/p/7082914.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  像素访问 OpenCV