使用OpenCV保存指定格式、指定类型的图像

最近使用OpenCV的函数保存图像,发现这里面存在诸多的坑,经过多次尝试,这才发现原来保存图像也是一门学问哦!之前已经写过一篇图像读写的博客:opencv读写图像问题!,这里再写一篇作为补充。

一、类型转换
1.Mat数据的类型

opencv中的mat数据类型共包含28种:

类型C1C2C3C4
CV_8U081624
CV_8S191725
CV_16U2101826
CV_16S3111927
CV_32S4122028
CV_32F5132129
CV_64F6142230

opencv提供了获取类型的函数:type()
这里提供一个简单的获取类型名的代码:

#include <string>
#include <opencv2/opencv.hpp>
using namespace std;
using namesapce cv;
string getImageType(Mat img)
{
 int type = img.type();
 string channel = "";
 string depth = "";

 // 判断通道数
 if (type >= 0 && type <= 6)
 {
 	channel += "C1";
 }
 else if (type >= 8 && type <= 14)
 {
 	channel += "C2";
 }
 else if (type >= 16 && type <= 22)
 {
 	channel += "C3";
 }
 else if (type >= 24 && type <= 30)
 {
 	channel += "C4";
 }
 // 判断位深
 if (0 == type || 8 == type || 16 == type || 24 == type)
 {
 	depth += "CV_8U";
 }
 else if (1 == type || 9 == type || 17 == type || 25 == type)
 {
 	depth += "CV_8S";
 }
 else if (2 == type || 10 == type || 18 == type || 26 == type)
 {
 	depth += "CV_16U";
 }
 else if (3 == type || 11 == type || 19 == type || 27 == type)
 {
 	depth += "CV_16S";
 }
 else if (4 == type || 12 == type || 20 == type || 28 == type)
 {
 	depth += "CV_32S";
 }
 else if (5 == type || 13 == type || 21 == type || 29 == type)
 {
 	depth += "CV_32F";
 }
 else if (6 == type || 14 == type || 22 == type || 30 == type)
 {
 	depth += "CV_64F";
 }

 return depth + channel;
}
2.类型转换

opencv中提供了类型转换的函数convertTo()用于进行图像类型转换,函数简介如下:

 /** @brief Converts an array to another data type with optional scaling.

    The method converts source pixel values to the target data type. saturate_cast\<\> is applied at
    the end to avoid possible overflows:

    \f[m(x,y) = saturate \_ cast<rType>( \alpha (*this)(x,y) +  \beta )\f]
    @param m output matrix; if it does not have a proper size or type before the operation, it is
    reallocated.
    @param rtype desired output matrix type or, rather, the depth since the number of channels are the
    same as the input has; if rtype is negative, the output matrix will have the same type as the input.
    @param alpha optional scale factor.
    @param beta optional delta added to the scaled values.
     */
    void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;

示例如下:

    string path = "C:\\Users\\admin\\Desktop\\0.png";
	Mat img = imread(path, -1);
	cout << getImageType(img) << endl;

	Mat cv8u;
	cvtColor(img, cv8u, CV_BGRA2GRAY);
	cout << getImageType(cv8u) << endl;

	Mat cv8uc3;
	cvtColor(img, cv8uc3, CV_BGRA2BGR);
	cout << getImageType(cv8uc3) << endl;

	Mat cv16u;
	cv8u.convertTo(cv16u, CV_16UC1);
	cout << getImageType(cv16u) << endl;

	Mat cv16uc3;
	cv8uc3.convertTo(cv16uc3, CV_16UC3);
	cout << getImageType(cv16uc3) << endl;
    // 其他类型依此类推

注意:在转换过程中如果想要转换为3通道的图像,必须保证被转换的图像也为3通道的图像,否则最终转换过来仍然是单通道。

二、图像保存
1.保存类型

我在这里经过大量测试,总结成一个表格,每种格式的图像可保存的类型如下:

类型/格式TIFF/TIF(*.tiff)JPG(*.jpg)PNG(*.png)BMP(*.bmp)
CV_8U
CV_8UC3
CV_8S××××
CV_8SC3××××
CV_16U××
CV_16UC3××
CV_16S××××
CV_16SC3××××
CV_32S××××
CV_32SC3××××
CV_32F×××
CV_32FC3×××
CV_64F×××
CV_64FC3××××

可以看到,以上四种格式都无法保存所有类型的Mat,想要保存任何一种Mat,可以使用XML或YAML格式,opencv提供了FileStorage类用于将数据存储为xml或yaml格式的文件

2.图像保存的接口
CV_EXPORTS_W bool imwrite( const String& filename, InputArray img, const std::vector<int>& params = std::vector<int>());
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值