【问题标题】:Why Png Compression doesn't change destination size (C++)? OpenCV VS2010为什么 Png 压缩不会改变目标大小 (C++)? OpenCV VS2010
【发布时间】:2016-10-28 02:24:07
【问题描述】:

我已经使用从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::Scalar(200,200,200) 在图像上占据太多位置,算法可以将其设置为背景颜色,它是从图像中删除,因此图像应该占据很小的位置。因此,当它采用与常规 PNG 相同或更大的尺寸时,这没有任何意义。

【问题讨论】:

  • “我也找不到如何从 Mat 图像在内存中创建 PNG 对象。” ——你在哪里看的? imencodeimwrite 记录在同一页面上。
  • "该函数压缩图像并将其存储在调整大小以适应结果的内存缓冲区中。"他们不写这是 PNG 或 JPEG 压缩或它是什么类型的压缩 - 据我了解 - 你加载的图像不使用 OpenCV,这会将其转换为 Mat 类型的图像。它看起来不像 PNG 压缩。该页面上缺少工作示例。是什么样的压缩?
  • ext – File extension that defines the output format. ... See imwrite() for the list of supported formats and flags description. -- 与 imwrite 相同的格式集。
  • 等等,当我想将数据编码为特定格式(如 PNG)并保存在内存中时,为什么要定义扩展名?为什么我问 - 我可能想将数据发送到数据库而不是图像文件。
  • 因为它决定了使用的格式。它就在那里,在文档中说。我的猜测是他们已经需要为imwrite 这样做,并且他们在这里重用了该代码——对我来说很有意义。

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


【解决方案1】:

我不是这方面的专家,但尝试测试一些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;
}

【讨论】:

    猜你喜欢
    • 2012-07-02
    • 1970-01-01
    • 2014-06-11
    • 2018-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多