我使用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具有相同的大小或甚至更多时,这没有任何意义。
答案 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;
}