大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE稳定放心使用
关于cv::imread读取图片类型的初探
问题来源
在处理深度图的时候,在用 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账号...