C++数字图像处理—OpenCV的常用操作

    使用C++开发图像处理算法时,不需要去调用OpenCV的内置算法函数,主要是利用OpenCV完成图像文件的输入、输出以及自动内存管理(重点)。所以,只要需要掌握一些简单的OpenCV的操作即可。

1、图像读取

    OpenCV支持bmp、jpg、png、tiff等常用图像格式的解析,所用API为imread。imread函数原型如下:

CV_EXPORTS_W Mat imread( const String& filename, int flags = IMREAD_COLOR );

filename参数为图像文件的路径,可以是相对路径,也可以是绝对路径;flags参数为图像文件解析的方式,支持的方式有如下:

       IMREAD_UNCHANGED:不对图像文件进行任何转换,直接读取。
       IMREAD_GRAYSCALE :将任何图像均转换为灰度图像(单通道)进行读取。
       IMREAD_COLOR:将任何图像均转为RGB彩色图像(三通道)进行读取。
       IMREAD_ANYDEPTH:如果不设置这个参数,16/32位图像将会自动转为8位图像。
       IMREAD_ANYCOLOR:将按照图像文件设定的颜色格式进行图像读取。

       IMREAD_LOAD_GDAL:调用gdal库进行图像文件读取。(可以简单地理解为读取TIFF图像文件)

示例代码:

	//不做任何转化进行读取
	cv::Mat matUnchanged = cv::imread("./lena.jpg", cv::IMREAD_UNCHANGED);	cv::imshow("UNCHANGED", matUnchanged);

	//彩色模式进行读取	
	cv::Mat matColor = cv::imread("./lena.jpg", cv::IMREAD_COLOR);	cv::imshow("COLOR", matColor);

	//灰度模式进行读取
	cv::Mat matGrayScale = cv::imread("./lena.jpg", cv::IMREAD_GRAYSCALE);
	cv::imshow("GRAYSCALE", matGrayScale);

运行结果:

C++数字图像处理—OpenCV的常用操作_第1张图片

2、图像显示

    OpenCV的图像显示函数为imshow,函数原型如下:

CV_EXPORTS_W void imshow(const String& winname, InputArray mat);

winname参数表示显示图像窗口的名称(任意字符),mat参数表示需要显示的图像。对于这个函数,需要注意的是(特别是新手),imshow函数只支持8位灰度图像、8位彩色图像和32位灰度图像(像素值范围0-1),具体原因大家可以自行百度关键词【显示器灰度等级】。

3、获取图像的属性

    图像的常用属性有图像的宽度、高度、数据缓存区指针(图像像素存储地址)、图像的通道数、深度。示例代码:

       cv::Mat matUnchanged = cv::imread("./lena.jpg", cv::IMREAD_UNCHANGED);
	//宽度
	std::cout << "宽度:"<

 

C++数字图像处理—OpenCV的常用操作_第2张图片

 

4、图像遍历的几种方式

    作为示例,读取一副RGB彩色图像,将每个像素的R值置0作为测试。(在Windows下,RGB存储的顺序为BGR)

(1)、使用OpenCV的at成员函数

    OpenCV提供了便利的访问图像数据的接口,at函数原型:

template inline _Tp& Mat::at(int i0, int i1)

参数i0为行号,i1为列号;模板参数_Tp常用类型如下:

 

图像类型 _Tp参数
单通道灰度 unsigned char
三通道彩色(8位) cv::Vec3b
16位灰度

unsigned short

32位浮点型 float
双通道32位 cv::Vec2f

 

示例代码:

 
for (size_t r = 0; r < matUnchanged.rows; r++)//行
	for (size_t c = 0; c < matUnchanged.cols; c++)//列
	{
		cv::Vec3b& bgr = matUnchanged.at(r, c);
		bgr[2] = 0;
	}

 

(2)、使用指针

 

 
for (size_t r = 0; r < matUnchanged.rows; r++)//行
	{
		//step返回图像一行的字节数
		unsigned char* pRow = matUnchanged.data + r * matUnchanged.step[0];//计算图像行首指针
		for (size_t c = 0; c < matUnchanged.cols; c++)//列
		{
			pRow[3 * c + 2] = 0;
		}
	}

 

(3)、行首指针存储法

 

//存储图像行首指针
	std::vector rowPtr(matUnchanged.rows);
	for (size_t r = 0; r < matUnchanged.rows; r++)
		rowPtr[r] = matUnchanged.data + r * matUnchanged.step[0];

	//遍历图像
	for (size_t r = 0; r < matUnchanged.rows; r++)//行
	for (size_t c = 0; c < matUnchanged.cols; c++)//列
	{
		rowPtr[r][c * 3 + 2] = 0;
	}

 

    访问图像数据的方式有很多,这里只列出几种常用的方式,考虑到算法的效率问题,通常使用指针对数据进行访问。

 

C++数字图像处理—OpenCV的常用操作_第3张图片

技术交流合作QQ:3355138068 

你可能感兴趣的:(C++数字图像处理)