神存在于细节之中!
什么是图像深度
很多人开始学习OpenCV之后,接触前面几个API就包括imwrite函数,而且很快知道了如何去保存Mat对象为图像,常规代码如下:
imwrite("D:/result.png ", dst);
其中dst是Mat对象。
这样保存的图像默认是每个通道8位的字节图像,常见的RGB图像是图像深度为24,这个可以通过windows下查看图像属性获得,截图如下:
如果每个通道占16位的话,RGB图像深度就会变成48,如果每个通道占32位的话,深度就会变成96,显然图像深度越大,图像文件也会越多,加载时候消耗的内存也会越多,所以OpenCV中默认读写图像都是每个通道8位(单字节)图像。
重温imwrite函数
假设我们想保存图像为16位或者32位浮点数图像时候,我们该怎么去做,在开始之前我们首先再次复习一下OpenCV中保存图像的API函数-imwrite
bool cv::imwrite(
const String & filename,
InputArray img,
const std::vector< int > & params = std::vector< int >()
)
Filename 参数为声明的文件保存路径
Img参数表示的是将要保存的Mat图像对象
Params 表示的是保存图像时的选项,
这些选项包括PNG/JPG/WEBP/TIFF压缩质量、格式选择等,可以分为如下四个大类
之前写过一篇文章是关于在保持时候如何使用这些选项对图像进行适当的压缩处理,这里关于Params参数使用方式就不再赘述,主要是基于key-value方式添加到vector中去即可。可以看这里
imwrite函数在关于保存为不同深度格式时候的图像类型支持说明如下:
在要保存为指定格式之前,可以通过convertTo或者cvtCOLOR进行图像类型或者通道转换之后,再调用imwrite进行保存。
各种不同深度保存
16位图像保存
转换之后,如果直接保存,代码如下:
// 加载图像
Mat src = imread("D:/flower.png", IMREAD_UNCHANGED);
printf("depth %d \n", src.depth());
// 转为为16位图像
Mat dst;
src.convertTo(dst, CV_16U);
imshow("flower16", dst);
imwrite("D:/flower-16.png", dst);
转换之后,归一化之后再保存,代码如下:
// 加载图像
Mat src = imread("D:/flower.png", IMREAD_UNCHANGED);
printf("depth %d \n", src.depth());
// 转为为16位图像
Mat dst;
src.convertTo(dst, CV_16U);
// 归一化再保存
normalize(dst, dst, 0, 256 * 256, NORM_MINMAX);
imwrite("D:/flower-16.png", dst);
imshow("flower-16", dst);
两者效果对比如下:
32位图像保存
// 加载图像
Mat src = imread("D:/flower.png", IMREAD_UNCHANGED);
printf("depth %d \n", src.depth());
// 转为为16位图像
Mat dst;
src.convertTo(dst, CV_32F);
// 归一化再保存
normalize(dst, dst, 0, 1.0, NORM_MINMAX);
imwrite("D:/flower-32.png", dst);
imshow("flower-32", dst);
对上述各种不同深度的图像,必须通过下面的方式才可以正确读取
Mat src = imread("D:/flower.png", IMREAD_UNCHANGED);
其中IMREAD_UNCHANGED表示不对原图像做任何改变。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有