为什么Png压缩不会改变目标大小(C ++)? OpenCV VS2010

时间:2016-06-25 16:56:26

标签: c++ image visual-studio-2010 opencv

我使用compression_params.push_back(1);compression_params.push_back(9);的各种值测试了此代码,但PNG图像的大小始终相同。 1950x1080(包含谷歌地图的截图 - 不是卫星照片)有2,36 MB(2 477 230字节。这是正常的需要这么多。我认为如果不包含照片,png图像尺寸很小。

vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
compression_params.push_back(1);

try {
    imwrite("RGB_1.png", source, compression_params);
}
catch (runtime_error& ex) {
    fprintf(stderr, "Exception converting image to PNG format: %s\n", ex.what());
    return 1;
}

为什么?另外,我无法找到如何在内存中创建PNG对象(以将编码数据保存在缓冲区中)。这意味着,我想将更多图像保存到一个文件(例如数据库)中,因此我需要转换为缓冲区,然后将添加缓冲区保存到文件中。是否可以在OpenCV中使用它?欢迎您的提示。

我认为PNG应该支持某些功能,其中算法自动选择背景颜色,所以如果你看到一些cv :: Scallar(200,200,200)在图像上占据太多位置,算法可以将其设置为背景颜色,它是从图像中删除,因此图像应占用较小的位置。因此,当它与常规PNG具有相同的大小或甚至更多时,这没有任何意义。

1 个答案:

答案 0 :(得分:0)

我不是这方面的专家,但试图测试一些compression_params也许你会通过测试下面的代码找到答案。

可能添加以下几行就可以了。

    compression_params.push_back(IMWRITE_PNG_STRATEGY);
    compression_params.push_back(IMWRITE_PNG_STRATEGY_DEFAULT);

或者您可以尝试其他替代方案documentation

我也打开了issue

#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <string>

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 argc, char** argv )
{
    // Create mat with alpha channel
    Mat mat(480, 640, CV_8UC4);
    createAlphaMat(mat);

    vector<int> compression_params;
    compression_params.push_back(IMWRITE_PNG_COMPRESSION);
    compression_params.push_back(0);
    compression_params.push_back(IMWRITE_PNG_STRATEGY);
    compression_params.push_back(IMWRITE_PNG_STRATEGY_DEFAULT);
    for (int i = 0; i < 10; i++)
    {
        compression_params[1] = i;
        imwrite(format("alpha%d.png",i), mat, compression_params);
    }
    return 0;
}