标签:relevant phi 特定 图层 void xmlns not bool 更新
转自 @yhl_leo
首先看一下,imread函数的声明:
// C++: Mat based Mat imread(const string& filename, int flags=1 ); // C: IplImage based IplImage* cvLoadImage(const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR ); // C: CvMat based CvMat* cvLoadImageM(const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR );
此处,就不列出python
的函数声明。随着2.x和3.x版本不断更新, Opencv的C++
版本数据结构和C
版本有较大差异,前者减少了指针的大量使用,用法更加便捷,因此建议多使用前者。以C++
版本函数进行分析,形参列表包括:
filename
: 待加载图像(包括:文件路径和文件名,图像在工程默认路径下的可省略文件路径);flags
: 标志符,指定图像加载颜色类型,默认值为1:
如果你喜欢使用imread("file.jpg")缺省参数的形式加载图像,务必要留意你所加载后的图像可能已经不是你原本想要的图像了!
从 Opencv源码枚举类型中也可以看到上述标识符含义:
// highgui.hpp enum { // 8bit, color or not IMREAD_UNCHANGED =-1, // 8bit, gray IMREAD_GRAYSCALE =0, // ?, color IMREAD_COLOR =1, // any depth, ? IMREAD_ANYDEPTH =2, // ?, any color IMREAD_ANYCOLOR =4 }; // highui_c.h enum { /* 8bit, color or not */ CV_LOAD_IMAGE_UNCHANGED =-1, /* 8bit, gray */ CV_LOAD_IMAGE_GRAYSCALE =0, /* ?, color */ CV_LOAD_IMAGE_COLOR =1, /* any depth, ? */ CV_LOAD_IMAGE_ANYDEPTH =2, /* ?, any color */ CV_LOAD_IMAGE_ANYCOLOR =4 };
Opencv已经支持目前很多图像格式,但是并非全部。主要包括:
*.bmp
, *.dib
(always supported)*.jpeg
, *.jpg
, *.jpe
(see the Notes section)*.jp2
,*.jpf
,*.jpx
(see the Notes section)*.png
(see the Notes section)*.webp
(see the Notes section)*.pbm
, *.pgm
, *.ppm
(always supported)*.sr
, *.ras
(always supported)TIFF files [Math Processing Error] -> [Math Processing Error] *.tiff
, *.tif
(see the Notes section)
Notes
对于常见的支持4通道的图像格式来说, Opencv读取结果是有差异的:
// 1.tif, 1.jp2 and 1.png are color images with 4 channels: R, G, B, A cv::Mat imageTif = cv::imread("E:\\1.tif"); // the default flags is 1 cv::Mat imageJp2 = cv::imread("E:\\1.jp2"); // the default flags is 1 cv::Mat imagePng = cv::imread("E:\\1.png"); // the default flags is 1 std::cout << imageTif.channels() << std::endl; // prints 3 std::cout << imageJp2.channels() << std::endl; // prints 3 std::cout << imagePng.channels() << std::endl; // prints 3 cv::Mat imageTif2 = cv::imread("E:\\1.tif", -1); // flags = -1 cv::Mat imageJp22 = cv::imread("E:\\1.jp2", -1); cv::Mat imagePng2 = cv::imread("E:\\1.png", -1); std::cout << imageTif2.channels() << std::endl; // prints 3 std::cout << imageJp22.channels() << std::endl; // prints 3 std::cout << imagePng2.channels() << std::endl; // prints 4
由此可见,目前 Opencv能够直接读取4通道图像并保留Alpha通道的貌似只有PNG格式,对于非PNG格式数据,需要保留Alpha通道的应用,如果坚持使用 Opencv库,建议转格式吧~
首先来看,imwrite函数的声明:
// c++: Mat based bool imwrite(const string& filename, InputArray img, const vector<int>& params=vector<int>() ); // C: CvMat and IplImage based int cvSaveImage(const char* filename, const CvArr* image, const int* params=0 );
仍旧以C++
版本为例,其形参列表为:
filename
:待保存图像名(包括:文件路径和文件名,图像在工程默认路径下的可省略文件路径);img
:待保存的图像对象;params
:特定图像存储编码参数设置,以类似pairs
类型的方式,(paramId_1, paramValue_1)
,(paramId_2, paramValue_2)
[Math Processing Error]…,其中paramId_1
就是标志符值,paramValue_1
标识符值对应的后续参数设置:vector<int> compression_params; compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION); // paramId_1, png compression compression_params.push_back(9);
在 Opencv中,主要对JPEG,PNG和PXM的编码方式进行了特别声明:
// highgui.hpp enum { IMWRITE_JPEG_QUALITY =1, // quality from 0 to 100, default value is 95. (The higher is the better) IMWRITE_PNG_COMPRESSION =16, // compression level from 0 to 9, default value is 3. (A higher value means a smaller size and longer compression time. Default value is 3.) IMWRITE_PNG_STRATEGY =17, IMWRITE_PNG_BILEVEL =18, IMWRITE_PNG_STRATEGY_DEFAULT =0, IMWRITE_PNG_STRATEGY_FILTERED =1, IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY =2, IMWRITE_PNG_STRATEGY_RLE =3, IMWRITE_PNG_STRATEGY_FIXED =4, IMWRITE_PXM_BINARY =32 // binary format flag: 0 or 1, default value is 1. }; // highui_c.h enum { CV_IMWRITE_JPEG_QUALITY =1, CV_IMWRITE_PNG_COMPRESSION =16, CV_IMWRITE_PNG_STRATEGY =17, CV_IMWRITE_PNG_BILEVEL =18, CV_IMWRITE_PNG_STRATEGY_DEFAULT =0, CV_IMWRITE_PNG_STRATEGY_FILTERED =1, CV_IMWRITE_PNG_STRATEGY_HUFFMAN_ONLY =2, CV_IMWRITE_PNG_STRATEGY_RLE =3, CV_IMWRITE_PNG_STRATEGY_FIXED =4, CV_IMWRITE_PXM_BINARY =32 };
上述的标识符含义,显而易见,就不累述。值得强调的是,imwrite函数支持存储的图像类型是有限的只包括:1,3,4通道的图像,但是对于不同的图像格式,也是有差异的:
Mat::convertTo()
和cvtColor()
函数进行转换后,再保存。当然,也可以使用通用的方法利用FileStorage
I/O操作,将图像存为XML或YAML格式。对于多通道图像,如果想对其每个通道单独进行保存,当然也是可行的,一方面自己可以根据图像的信息和图层信息写出相应的存储函数,另一方面 Opencv也提供了专门的函数split
可以将图像的每个通道提取出保存到vector
中:
PNG原图
cv::Mat img = imread( "C:\\Users\\Leo\\Desktop\\Panda.png", CV_LOAD_IMAGE_UNCHANGED ); std::vector<cv::Mat> imageChannels; cv::split( img, imageChannels ); cv::imwrite("E:\\0.jpg", imageChannels[0]); cv::imwrite("E:\\1.jpg", imageChannels[1]); cv::imwrite("E:\\2.jpg", imageChannels[2]); cv::imwrite("E:\\3.jpg", imageChannels[3]);
B G R A
附上 Opencv文档源码:
#include <vector> #include <stdio.h> #include <opencv2/opencv.hpp> using namespace cv; using namespace std; void createAlphaMat(Mat &mat) { CV_Assert(mat.channels() == 4); for (int i = 0; i < mat.rows; ++i) { for (int j = 0; j < mat.cols; ++j) { Vec4b& bgra = mat.at<Vec4b>(i, j); bgra[0] = UCHAR_MAX; // Blue bgra[1] = saturate_cast<uchar>((float (mat.cols - j)) / ((float)mat.cols) * UCHAR_MAX); // Green bgra[2] = saturate_cast<uchar>((float (mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX); // Red bgra[3] = saturate_cast<uchar>(0.5 * (bgra[1] + bgra[2])); // Alpha } } } int main(int argv, char **argc) { // Create mat with alpha channel Mat mat(480, 640, CV_8UC4); createAlphaMat(mat); vector<int> compression_params; compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION); compression_params.push_back(9); try { imwrite("alpha.png", mat, compression_params); } catch (runtime_error& ex) { fprintf(stderr, "Exception converting image to PNG format: %s\n", ex.what()); return 1; } fprintf(stdout, "Saved PNG file with alpha data.\n"); return 0; }
运行结果为:
标签:relevant phi 特定 图层 void xmlns not bool 更新
原文地址:https://www.cnblogs.com/gdut-gordon/p/9702922.html