Opencv 图像读取与保存问题
csdh11 2025-04-23 23:18 6 浏览
本文仅对 Opencv图像读取与保存进行阐述,重在探讨图像读取与保存过程中应注意的细节问题。
1 图像读取
首先看一下,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 : 待载入图像(包含:文件路径和文件名称。图像在project默认路径下的可省略文件路径);
- flags : 标志符,指定图像载入颜色类型。默认值为1:
- IMREAD_UNCHANGED / CV_LOAD_IMAGE_UNCHANGED :不加改变的载入原图。
- IMREAD_GRAYSCALE / CV_LOAD_IMAGE_GRAYSCALE :图像转为灰度图(GRAY,1通道)。
- IMREAD_COLOR / CV_LOAD_IMAGE_COLOR :图像转为彩色图(BGR,3通道)。
- IMREAD_ANYDEPTH / CV_LOAD_IMAGE_ANYDEPTH :不论什么位深度。假设载入的图像不是16-bit位图或者32-bit位图。则转化为8-bit位图。
- IMREAD_ANYCOLOR / CV_LOAD_IMAGE_ANYCOLOR :不论什么彩色。单独使用的时候等价于 IMREAD_UNCHANGED / CV_LOAD_IMAGE_UNCHANGED 。
- > 0 :返回3通道的彩色图,可是假设是4通道(RGBA)。当中Alpha须要保留的话,不建议这么使用。由于一旦这么使用。就会导致Alpha通道被剥离掉,此时建议使用负值。
- = 0 :返回灰度图像。
- < 0 :返回具有Alpha通道的图像。
假设你喜欢使用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已经支持眼下非常多图像格式,可是并不是所有。
主要包含:
- Windows bitmaps -> *.bmp, *.dib (always supported)
- JPEG files -> *.jpeg, *.jpg, *.jpe (see the Notes section)
- JPEG 2000 files -> *.jp2,*.jpf,*.jpx (see the Notes section)
- Portable Network Graphics -> *.png (see the Notes section)
- WebP -> *.webp (see the Notes section)
- Portable image format -> *.pbm, *.pgm, *.ppm (always supported)
- Sun rasters -> *.sr, *.ras (always supported)
- TIFF files -> *.tiff, *.tif (see the Notes section)
- Notes
- 1 The function determines the type of an image by the content, not by the file extension.
- 2 On Microsoft Windows* OS and MacOSX*, the codecs shipped with an OpenCV image (libjpeg, libpng, libtiff, and libjasper) are used by default. So, OpenCV can always read JPEGs, PNGs, and TIFFs. On MacOSX, there is also an option to use native MacOSX image readers. But beware that currently these native image loaders give images with different pixel values because of the color management embedded into MacOSX.
- 3 On Linux*, BSD flavors and other Unix-like open-source operating systems, OpenCV looks for codecs supplied with an OS image. Install the relevant packages (do not forget the development files, for example, “libjpeg-dev”, in Debian* and Ubuntu*) to get the codec support or turn on the OPENCV_BUILD_3RDPARTY_LIBS flag in CMake.
- 4 In the case of color images, the decoded images will have the channels stored in B G R order.
对于常见的支持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库,建议转格式吧~
2 图像存储
首先来看,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:待保存图像名(包含:文件路径和文件名称,图像在project默认路径下的可省略文件路径);
- img:待保存的图像对象。
- params :特定图像存储编码參数设置。以相似pairs类型的方式。(paramId_1, paramValue_1)。(paramId_2, paramValue_2)…,当中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); // paramValue_2, compression level is 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通道的图像,可是对于不同的图像格式。也是有差异的:
- 对于单通道8-bit位图(或者16-bit位图( CV_16U/CV_16UC1 的PNG,JPEG 2000 和TIFF))或者3通道(通道顺序为:B G R )的图像,imwrite函数是都支持的。
- 对于格式,或者位深或者通道顺序与上面不一致的。能够使用函数Mat::convertTo()和cvtColor()函数进行转换后,再保存。当然,也能够使用通用的方法利用FileStorageI/O操作。将图像存为XML或YAML格式。
- 对于PNG图像,能够保存其Alpha通道,创建一个8-bit或者16-bit 4通道的位图(通道顺序为:B G R A )。假设是全透明的Alpha通道设置为0,反之不透明设置为255/65535。
对于多通道图像,假设想对其每一个通道单独进行保存,当然也是可行的。一方面自己能够依据图像的信息和图层信息写出相应的存储函数,还有一方面 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;
}
执行结果为:
好文要顶 关注我 收藏该文 微信分享
- 上一篇:最好用的视频播放软件,无广告、免费使用
- 下一篇:FFMPEG小白-day04
相关推荐
- Centos离线静默安装 oracle11g,步骤细验证成功
-
一、环境要求1.1.涉及工具及环境1)CentOS764位系统2)oracle安装包文件a)linux.x64_11gR2_database_1of2.zip...
- zabbix 5.0 ODBC监控Oracle
-
以下配置基于zabbix5.0.24完成,基于5.4测试无法提示找到libsqora.so.21.1类库文件,网上搜索了很多方法都无法解决。本次ODBC数据采集服务不在zabbix中部署,而是由单独...
- Windows环境中Oracle数据库ORA-01034错误的处理过程
-
摘要:今天一早发现公司的一台Oracle数据库无法访问,使用PL/SQL登录Oracle数据库,提示【ORA-12514:TNS:监听程序当前无法识别连接描述符中请求的服务】,后来经过修复后,并在服务...
- 部署单机oracle数据库,干货太多,我编辑都累
-
一、前言本次实施内容是,oracle单实例系统文件安装,操作系统为CentOS6.9,数据库版本11.2.0.4。二、oracle软件安装...
- 带你部署单机oracle数据库,超详细带图解说
-
一、前言本次实施内容是,oracle单实例系统文件安装,操作系统为CentOS6.9,数据库版本11.2.0.4。二、oracle软件安装...
- oracle用户创建及权限设置
-
权限:createsessioncreatetableunlimitedtablespaceconnectresource...
- 简单且优雅数据库操作-测试向
-
cmd打开命令行输入框sqlplus/nolog连接无用户数据库connectsys/zhwylanassysdba;连接sys用户的管理员身份showuser;显示当前用户目录...
- 手撸一个Oracle Rac(3)
-
(文章太长,只能分段发表,哎~)四、RAC维护一般命令1.查看集群状态grid用户执行crs_stat-t...
- 「运维经」第23章——忘记oracle密码
-
忘记oracle密码前提条件:你确保安装oracleserver主机的oracle用户密码你还记得。...
- 详解BarTender超过文件尾访问
-
Bartender标签打印机软件出现不能正常运行,在打开这个软件会出来一个窗口“尝试超过文件尾访问文件…….btw”的字样。解决方法:彻底卸载软件,删除软件所有的注册信息。方法一:可以采用360安全助...
- BarTender只打印口令密码去除教程
-
BarTender条码打印软件具有“只打印口令设置”功能,通过设置该口令密码可以防止操作人员随意变动模板内容。但是,如果您将BarTender只打印口令设置密码忘了怎么办?也许你会觉得卸载软件重装就O...
- Bartender怎么破解?Bartender如何安装图文教程讲解
-
什么是bartender?bartender是美国海鸥科技推出的一款条码打印软件bartender在150多个国家与地区已拥有上千万的用户,该软件在条码行业中得到众多群体使用和行业设备巨头认可并与...
- FFmpeg+SDL视频播放器-图形界面版
-
MFC知识创建MFC工程的方法...
- 技术|开源空间音频格式Eclipsa Audio登场,继HDR10+后Samsung再次硬杠Dolby
-
说到空间音频/沉浸式3D音效,你首先想到谁?DolbyAtmos、DTS:X还是Auro3D?如今新的“搅局者”出现了!韩系电视大厂Samsung与Google合作,推出空间音频格式Eclipsa...
- 视频怎么进行格式转换?6款视频转换MP4格式的免费软件!
-
在数字时代,视频格式的多样性为我们提供了丰富的观看和编辑选择,但同时也带来了格式不兼容的困扰:MOV、AVI、WMV、MKV……这些格式多多少少都会遇到因不兼容而无法播放或下载分享的场景。当你想要将视...
- 一周热门
- 最近发表
- 标签列表
-
- mydisktest_v298 (34)
- document.appendchild (35)
- 头像打包下载 (61)
- acmecadconverter_8.52绿色版 (39)
- word文档批量处理大师破解版 (36)
- server2016安装密钥 (33)
- mysql 昨天的日期 (37)
- parsevideo (33)
- 个人网站源码 (37)
- centos7.4下载 (33)
- mysql 查询今天的数据 (34)
- intouch2014r2sp1永久授权 (36)
- 先锋影音源资2019 (35)
- jdk1.8.0_191下载 (33)
- axure9注册码 (33)
- pts/1 (33)
- spire.pdf 破解版 (35)
- shiro jwt (35)
- sklearn中文手册pdf (35)
- itextsharp使用手册 (33)
- 凯立德2012夏季版懒人包 (34)
- 反恐24小时电话铃声 (33)
- 冒险岛代码查询器 (34)
- 128*128png图片 (34)
- jdk1.8.0_131下载 (34)