OpenCV中原始图像加载与保存压缩技巧

Posted OpenCV学堂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV中原始图像加载与保存压缩技巧相关的知识,希望对你有一定的参考价值。

加载图像

OpenCV中关于图像读写有两个函数imread与imwrite,imread加载的时候支持灰度图像、彩色图像、原始图像加载,默认情况下通过imread加载的图像都是三通道的BGR彩色图像。
但是实际上OpenCV支持加载任意通道的图像,首先来仔细再看一下imread函数

Mat cv::imread(
    const String &  filename,
    int flags = IMREAD_COLOR 
)

在不修改第二个参数flags的默认值情况下,我们经常这样使用该函数:

Mat image = imread("D:/images/test.png");
if (image.empty()) {
    printf("could not load image...\n");
    return -1;
}

当我们需要把加载图像始终以灰度图像出现时候:

Mat gray = imread("D:/images/dannis2.jpg", IMREAD_GRAYSCALE);
if (gray.empty()) {
    printf("could not load image...\n");
    return -1;
}

当我们需要把具有透明通道或者任意通道的图像加载进来不做任何改变时候:

Mat anycolor = imread("D:/images/test1.png", IMREAD_ANYCOLOR);
if (anycolor.empty()) {
    printf("could not load image...\n");
    return -1;
}

保存与压缩图像

一般情况下保存图像调用imwrite只会设置两个参数,但是实际上它还有第三个默认参数可以设置,这个参数可以帮助调整图像的压缩质量与保存图像的位图深度与通道数目,当我们不想保存为默认的三通道彩色图像的时候,我们就需要使用第三个参数来对保存图像进行有针对性的写入图像文件。首先我们需要重新认识一下imwrite这个函数。

bool cv::imwrite(
    const String & filename,
    InputArray img,
    const std::vector<int> & params = std::vector<int>()
)

参数解释
filename
表示保存文件路径与名称,必须带图像文件扩展名
img
内存中Mat对象
params
保存图像文件时候需要优化的参数,默认为空

params解释

对于第三个参数params来说,当我们保存图像为不同格式时候,params参数的内容也是不一样的,当保存图像格式为PNG时候,调整压缩质量参数为

IMWRITE_PNG_COMPRESSION 
等级为0~9之间,值越大压缩时间越长,默认为1。值越大,图像大小越小!

当保存图像格式为JPG时候,调整压缩质量参数为

IMWRITE_JPEG_QUALITY 
等级为0~100之间,值越大图像质量越高,默认为95。值越大,图像大小也越大!

压缩与保存代码演示

保存为单通道灰度图像

// 保存为单通道灰度图像
vector<int> opts;
opts.push_back(IMWRITE_PAM_FORMAT_GRAYSCALE);
imwrite("D:/gray.png", gray, opts);
opts.clear();

保存为BGR彩色图像

imwrite("D:/image.png", image);

保存为PNG彩色压缩图像

Mat anycolor = imread("D:/images/test1.png", IMREAD_ANYCOLOR);
vector<int> opts;
opts.push_back(IMWRITE_PNG_COMPRESSION);
opts.push_back(9);
imwrite("D:/anycolor.png", anycolor, opts);

保存为JPG高压缩比图像

Mat src = imread("D:/images/lovely-girl.jpg", IMREAD_COLOR);
vector<int> opts;
opts.push_back(IMWRITE_JPEG_QUALITY);
opts.push_back(50);
opts.push_back(IMWRITE_JPEG_OPTIMIZE);
opts.push_back(1);
imwrite("D:/src.jpg", src, opts);

lovely-girl.jpg原图像大小:389KB
OpenCV压缩保存之后大小:128KB

对比压缩前后的两张图,发现图像质量并没有明显下降,证明OpenCV通过此方式可以有效降低图像大小,在网络传输时候节省带宽资源!

保存PNG带透明通道的彩色图像

// 保存为四通道彩色图像
Mat bgra;
cvtColor(anycolor, bgra, COLOR_BGR2BGRA);
int h = anycolor.rows;
int w = anycolor.cols;
for (int row = 0; row < h; row++) {
    for (int col = 0; col < w; col++) {
        Vec4b pixel = bgra.at<Vec4b>(row, col);
        pixel[3] = 127;
        bgra.at<Vec4b>(row, col) = pixel;
    }
}
imshow("alpha-demo", bgra);
opts.clear();
opts.push_back(IMWRITE_PAM_FORMAT_RGB_ALPHA);
imwrite("D:/bgra.png", bgra, opts);

总结

使用imread与imwrite两个函数进行图像读写的时候,特别需要注意缺省的最后一个参数,它们可以有效的帮助开发者解决各种图像加载与压缩保存需求。

操千曲而后晓声,观千剑而后识器

【推荐阅读】












坚其志,苦其心,劳其力

事无大小,必有所成


关注【OpenCV学堂】

长按或者扫码即可关注

截至到2018-11-07为止送书活动点赞前六位

+ 杨宏

+ 北海Plus

+刘豆豆

+铜

+大魔头

+李辉

我会第一时间加你们微信,邮寄图书

以上是关于OpenCV中原始图像加载与保存压缩技巧的主要内容,如果未能解决你的问题,请参考以下文章

机器视觉行业实践技巧 -- OpenCV技巧与方法:代码脚手架 -- 图像处理

机器视觉行业实践技巧 -- OpenCV技巧与方法:代码脚手架 -- 图像处理

JAVA 图像处理基于OpenCv与JVM-----加载保存图像

JAVA 图像处理基于OpenCv与JVM-----加载保存图像

使用 OpenCV 将 YUV 转换为有损压缩

在 OpenCV 中保存原始图像