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



原文发布时间为:2018-11-08
本文作者:gloomyfish
本文来自云栖社区合作伙伴“OpenCV学堂”,了解相关信息可以关注“OpenCV学堂”。
上一篇:OpenGL ES 实现可视化实时音频


下一篇:实战分析ARP***与欺骗