关于cv::imread读取图片类型的初探[通俗易懂]

关于cv::imread读取图片类型的初探[通俗易懂]关于cv::imread读取图片类型的初探问题来源环境首先生成单通道和三通道的png图片cv::imread函数及其参数不同参数读取rgb图像不同参数读取单通道图片问题来源在处理深度图的时候,在用cv::imread读取深度图像时,本以为得到的是单通道图,但实际是三通道图。所以仔细看了一下cv::imread函数。环境Ubuntu16Opencv4.0.0首先生成单通道和三通…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

问题来源

在处理深度图的时候,在用 cv::imread 读取深度图像时,本以为得到的是单通道图,但实际是三通道图。所以仔细看了一下 cv::imread 函数。

环境

Ubuntu16
Opencv 4.0.0

首先生成单通道和三通道的png图片

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
using namespace std;
int main(){
	cv::Mat mat1(480,480,CV_8UC3,cv::Scalar(255,128,0));
	cv::imshow("mat1",mat1);
	cv::Mat mat2(480,480,CV_8UC1,cv::Scalar(128));
	cv::imshow("mat2",mat2);
	cv::imwrite("mat1.png",mat1);
	cv::imwrite("mat2.png",mat2);
	cv::waitKey(0);
	return 1;
}

两张图片,一张三通道图片有颜色,一张单通道图片,无颜色。保存成PNG格式。文件大小分别为2.3KB和1.3KB。
在这里插入图片描述

cv::imread函数及其参数

Mat cv::imread (
	const String & filename, 
	int flags = IMREAD_COLOR 
)

enum cv::ImreadModes{
	IMREAD_UNCHANGED,			//-1   使图像保持原样输出  
	IMREAD_GRAYSCALE,			//0   把图像转成单通道的灰度图输出
	IMREAD_COLOR ,				//1	//把图像转成三通道的rgb图输出
	IMREAD_ANYDEPTH, 			//2   //If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit.
	IMREAD_ANYCOLOR	,			//4   //以任何可能的颜色格式读取图像
	IMREAD_LOAD_GDAL, 			//8 	//use the gdal driver for loading the image
	IMREAD_REDUCED_GRAYSCALE_2,	//16	//输出单通道灰度图,并且将图像缩小为原来的1/2
	IMREAD_REDUCED_COLOR_2 ,	//17  //输出三通道的rgb图,并且缩小图像到原来的1/2
	IMREAD_REDUCED_GRAYSCALE_4, //32  //单通道  1/4
	IMREAD_REDUCED_COLOR_4 ,	//33	//三通道  1/4
	IMREAD_REDUCED_GRAYSCALE_8, //64	//单通道  1/8
	IMREAD_REDUCED_COLOR_8 ,	//65	//三通道  1/8
	IMREAD_IGNORE_ORIENTATION 	//128	//do not rotate the image according to EXIF's orientation flag. 
}

对我们有意义的有参数-1,0,1。
而参数IMREAD_COLOR 默认值为1。
下面是一些具体例子而已。

不同参数读取rgb图像

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace std;
int main(){
	cv::Mat mat1 = cv::imread("mat1.png");
	cout<<mat1.type()<<endl;
	cout<<mat1(cv::Range(0,3),cv::Range(0,3))<<endl;

	cv::Mat mat1_0 = cv::imread("mat1.png",0);
	cout<<mat1_0.type()<<endl;
	cout<<mat1_0(cv::Range(0,3),cv::Range(0,3))<<endl;

	cv::Mat mat1_1;
	cv::cvtColor(mat1,mat1_1,cv::COLOR_RGB2GRAY);
	cout<<mat1_1.type()<<endl;
	cout<<mat1_1(cv::Range(0,3),cv::Range(0,3))<<endl;

	return 1;
}

输出

16
[255, 128,   0, 255, 128,   0, 255, 128,   0;
 255, 128,   0, 255, 128,   0, 255, 128,   0;
 255, 128,   0, 255, 128,   0, 255, 128,   0]
0
[104, 104, 104;
 104, 104, 104;
 104, 104, 104]
0
[151, 151, 151;
 151, 151, 151;
 151, 151, 151]

单通道读取不等于直接把图像转为灰度图。

附 cv::Mat.type()

		C1 	C2 	C3 	C4 
CV_8U   0   8   16	24
CV_8S   1   9	17	25
CV_16U  2   10	18	26
CV_16S  3   11	19	27
CV_32S  4   12	20	28
CV_32F  5   13	21	29
CV_64F  6   14	22	30 

不同参数读取单通道图片

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace std;
int main(){

	cv::Mat mat2 = cv::imread("mat2.png");
	cout<<mat2.type()<<endl;
	cout<<mat2(cv::Range(0,3),cv::Range(0,3))<<endl;

	cv::Mat mat2_00 = cv::imread("mat2.png",-1);
	cout<<mat2_00.type()<<endl;
	cout<<mat2_00(cv::Range(0,3),cv::Range(0,3))<<endl;

	cv::Mat mat2_0 = cv::imread("mat2.png",0);
	cout<<mat2_0.type()<<endl;
	cout<<mat2_0(cv::Range(0,3),cv::Range(0,3))<<endl;

	cv::Mat mat2_1 = cv::imread("mat2.png",1);
	cout<<mat2_1.type()<<endl;
	cout<<mat2_1(cv::Range(0,3),cv::Range(0,3))<<endl;


	return 1;
}

输出:

16
[128, 128, 128, 128, 128, 128, 128, 128, 128;
 128, 128, 128, 128, 128, 128, 128, 128, 128;
 128, 128, 128, 128, 128, 128, 128, 128, 128]
0
[128, 128, 128;
 128, 128, 128;
 128, 128, 128]
0
[128, 128, 128;
 128, 128, 128;
 128, 128, 128]
16
[128, 128, 128, 128, 128, 128, 128, 128, 128;
 128, 128, 128, 128, 128, 128, 128, 128, 128;
 128, 128, 128, 128, 128, 128, 128, 128, 128]

参数-1和0是期望的输出。
参数1也按照预期进行了复制。
无参数时,参数并非默认-1 。

当我打出默认参数的时候,才注意到我只需要找到默认参数cv::IMREAD_COLOR(见“cv::imread函数及其参数”),而打印出来是1。

遇到的一些情况

以上笔者读取的是自己制作的图片,但在项目中碰到的一张深度图,如图
在这里插入图片描述
(在此显示不太清楚)
在-1参数下读取的type为2,也即是16UC1。
总结起来,在读取图像后,需要确认读取格式和自己预期是否相同。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/182233.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 无刷直流电动机驱动控制系统_直流无刷电机驱动电路

    无刷直流电动机驱动控制系统_直流无刷电机驱动电路无刷直流电动机利用电子开关线路和位置传感器来代替有刷直流电机电刷和换向器,使其同时具有直流电动机和交流电动机的优良特性。无刷直流电机(驱动系统)主要由电动机本体、位置传感器、电子开关线路三部分组成。

    2022年10月21日
  • bigdecimal保留2位小数_java如何保留一位小数

    bigdecimal保留2位小数_java如何保留一位小数http://blog.csdn.net/yuhua3272004/article/details/3075436使用java.math.BigDecimal工具类实现java保留两位小数问题:方式一(四舍五入形式保留两位小数,注意模式ROUND_HALF_UP):四舍五入doublef=111231.5585;BigDecimal…

  • 浅析Promise用法[通俗易懂]

    浅析Promise用法[通俗易懂]浅析Promise用法要理解Promise要知道没有Promise的回调地狱如何插入一段漂亮的代码片Promise语法与then的用法所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise是一个对象,从它可以获取异步操作的消息。Promise提供统一的API,各种异步操作都可以用同样的方法进行处理。Promis…

  • ureport 显示html,UReport2 与业务结合

    ureport 显示html,UReport2 与业务结合本小节中我们将介绍如何在业务页面中展示报表、导出报表文件、引用报表内容等操作。报表相关URL在配置好一个包含UReport2的项目后,就可以运行我们的项目,打开UReport2的基于网页的报表设计器,它的地址如下:UReport2报表设计器URLhttp://host[:port][/context-path]/ureport/designer如果我们是在本地启动项目,并且服务器端口号为8080,…

    2022年10月29日
  • 2022 idea最新激活码【2022免费激活】2022.02.16「建议收藏」

    (2022 idea最新激活码)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.htmlFZP9ED60OK-eyJsaWNlbnNlSW…

  • ajax请求的五个步骤java_js ajax请求的五个步骤实现详解

    ajax请求的五个步骤java_js ajax请求的五个步骤实现详解Ajax是Java前端最重要的技术之一,是支撑着前端交互数据的基石,今天我们就来了解下ajax发送请求所需的五个步骤。首先我们需要来了解一下ajax,ajax的全称是AsynchronousJavascript+XML。异步传输+js+xml。所谓异步,在这里简单地解释就是:向服务器发送请求的时候,我们不必等待结果,而是可以同时做其他的事情,等到有了结果我们可以再来处理这个事。这个很重要,如果不是…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号