OpenCV2学习(10)之Mat类对象元素的获取与赋值

矩阵元素的表达:

对于单通道图像,其元素类型一般为 8U (即 8位无符号整数),当然也可以 是 16S 、32S、32F 等;这些类型可以直接用 uchar、short 、float等 C/C++语言中的基本数据类型表达。

如果多通道图像,如RGB彩色图像,需要用三个通道来表示。在这种情况 下,如果依然将图像视作一个二维矩阵那么矩阵的元素不再是基本数据类型。

opencv中使用vec可表示向量,用于矩阵元素的表达。
OpenCV2学习(10)之Mat类对象元素的获取与赋值

1、像素值的读写可使用at()函数:

          cv::Mat也是向量,可以使at方法取值,使用调用方法image.at<cv::Vec3b>(j,i),at方法方便,直接给i,j赋值就可以随意访问图像中任何一个像素,其中j表示第j行,i表示该行第i个像素。但是at方法效率是这3中访问方法中最慢的一个,所以如果遍历图像或者访问像素比较多时,建议不要使用这个方法,毕竟程序的效率还是比程序的可读性要重要的。

OpenCV2学习(10)之Mat类对象元素的获取与赋值

   如:

for (int j = 0; j< image.rows; j++)
{
	for (int i = 0; i< image.cols; i++)
	{
		image.at<cv::Vec3b>(j, i)[0] = image.at<cv::Vec3b>(j, i)[0] / div*div + div / 2;
		image.at<cv::Vec3b>(j, i)[1] = image.at<cv::Vec3b>(j, i)[1] / div*div + div / 2;
		image.at<cv::Vec3b>(j, i)[2] = image.at<cv::Vec3b>(j, i)[2] / div*div + div / 2;
	} // end of line                     
}

  

 

2、使用Mat的成员函数ptr< >( )

         cv::Mat中提供ptr函数访问任意一行像素的首地址,特别方便图像的一行一行的横向访问,如果需要一列一列的纵向访问图像,就稍微麻烦一点。但是ptr访问效率比较高,程序也比较安全,有越界判断。

如:

int nl = image.rows; //行数  
int nc = image.cols * image.channels();
for (int j = 0; j<nl; j++)
{
	uchar* data = image.ptr<uchar>(j);
	for (int i = 0; i<nc; i++)
	{
		data[i] = data[i] / div*div + div / 2;
	}
}

 

3、使用迭代器遍历图像

cv::Mat同样有标准模板库(STL),可以使用迭代器访问数据。

用迭代器来遍历图像像素,可简化过程降低出错的机会,比较安全,不过效率较低;如果想避免修改输入图像实例cv::Mat,可采用const_iterator。iterator有两种调用方法,cv::MatIterator_<cv::Vec3b>it;cv::Mat_<cv::Vec3b>::iterator it;中间cv::Vec3b是因为图像是彩色图像,3通道,cv::Vec3b可以代表一个像素。

如:

cv::Mat_<cv::Vec3b>::iterator it = image.begin<cv::Vec3b>();
cv::Mat_<cv::Vec3b>::iterator itend = image.end<cv::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;
}

 

参考:https://blog.csdn.net/u011574296/article/details/70139563

           https://blog.csdn.net/xuhang0910/article/details/47058419