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

使用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);

运行结果:
在这里插入图片描述
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 << "宽度:"<<matUnchanged.cols << std::endl;
	//高度
	std::cout << "高度:" << matUnchanged.rows << std::endl;
	//数据缓存区指针
	unsigned char* pData = matUnchanged.data;
	std::cout << "数据地址:" << &pData << std::endl;
	//通道数
	std::cout << "通道数:" << matUnchanged.channels() << std::endl;
	//深度
	//elemSize函数返回的是一个像素占用的字节数
	std::cout << "深度:" << matUnchanged.elemSize() / matUnchanged.channels() * 8 << std::endl;
	cv::imshow("UNCHANGED", matUnchanged);
	cv::waitKey(0);

在这里插入图片描述
4、图像遍历的几种方式

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

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

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

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

参数i0为行号,i1为列号;模板参数_Tp常用类型如下:
在这里插入图片描述
示例代码:

for (size_t r = 0; r < matUnchanged.rows; r++)        //行
	for (size_t c = 0; c < matUnchanged.cols; c++)    //列
	{
		cv::Vec3b& bgr = matUnchanged.at<cv::Vec3b>(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<unsigned char*> 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;
	}

访问图像数据的方式有很多,这里只列出几种常用的方式,考虑到算法的效率问题,通常使用指针对数据进行访问。
在这里插入图片描述
转载至 https://blog.csdn.net/huqiang_823/article/details/80698670

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值