【问题标题】:OpenCV cvSaveImage Jpeg Compression FactorOpenCV cvSaveImage Jpeg 压缩系数
【发布时间】:2010-10-22 12:16:23
【问题描述】:

我正在使用 OpenCV 并使用 cvSaveImage 函数将其保存为 jpeg,但我无法找到它使用的 Jpeg 压缩因子。

  1. 什么是 cvSaveImage(...) 的 Jpeg 压缩系数
  2. 使用 cvSaveImage(...) 时如何传递压缩系数

【问题讨论】:

    标签: c++ image opencv jpeg


    【解决方案1】:
    1. 您可能可以通过在源代码中四处寻找:http://opencvlibrary.svn.sourceforge.net/viewvc/opencvlibrary/
    2. 你不能,因为函数不接受这样的参数。如果您想控制压缩,那么我能想到的最简单的方法是首先使用 cvSaveImage()(或您选择的其他无损格式)将您的图像保存为位图,然后使用另一个图像库将其转换为 JPEG所需的压缩系数。

    【讨论】:

      【解决方案2】:

      目前 cvSaveImage() 被声明为只接受两个参数:

      int cvSaveImage( const char* filename, const CvArr* image );
      

      但是,“latest tested snapshot”有:

        #define CV_IMWRITE_JPEG_QUALITY 1
        #define CV_IMWRITE_PNG_COMPRESSION 16
        #define CV_IMWRITE_PXM_BINARY 32
      
        /* save image to file */
        CVAPI(int) cvSaveImage( const char* filename, const CvArr* image,
                                const int* params CV_DEFAULT(0) );
      

      我一直无法找到任何文档,但我浏览这段代码的印象是,您将构建一个 int 值数组来传递第三个参数:

      int p[3];
      p[0] = CV_IMWRITE_JPEG_QUALITY;
      p[1] = desired_quality_value;
      p[2] = 0;
      

      我不知道质量值是如何编码的,而且我从未尝试过,所以请谨慎购买。

      编辑:

      对此有点好奇,我下载并构建了最新的 OpenCV 主干版本,并且能够通过这段一次性代码确认上述内容:

      #include "cv.h"
      #include "highgui.h"
      int main(int argc, char **argv)
      {
          int p[3];
          IplImage *img = cvLoadImage("test.jpg");
      
          p[0] = CV_IMWRITE_JPEG_QUALITY;
          p[1] = 10;
          p[2] = 0;
      
          cvSaveImage("out1.jpg", img, p);
      
          p[0] = CV_IMWRITE_JPEG_QUALITY;
          p[1] = 100;
          p[2] = 0;
      
          cvSaveImage("out2.jpg", img, p);
      
          exit(0);
      }
      

      我的“test.jpg”为 2,054 KB,创建的“out1.jpg”为 182 KB,“out2.jpg”为 4,009 KB。

      假设您可以使用 Subversion 存储库中提供的最新代码,您的状态应该很好。

      顺便说一句,质量参数的范围是0-100,默认是95。

      【讨论】:

      • 它会降低图像质量并真正扭曲图像。请提出任何可以减小文件大小而不影响图像质量的解决方案。
      【解决方案3】:

      OpenCV 现在 has a parameter 设置 jpeg 质量。我不确定这是什么时候引入的,但大概是在 2.0 之后的某个时候。

      const int JPEG_QUALITY = 80;
      
      Mat src;
      // put data in src
      
      vector<int> params;
      params.push_back(CV_IMWRITE_JPEG_QUALITY);
      params.push_back(JPEG_QUALITY);
      
      imwrite("filename.jpg", src, params);
      

      如果你使用的是 C++0x,你可以使用这个更短的符号:

      imwrite("filename.jpg", src, vector<int>({CV_IMWRITE_JPEG_QUALITY, JPEG_QUALITY});
      

      【讨论】:

        【解决方案4】:
        imwrite("filename.jpeg",src,(vector<int>){CV_IMWRITE_JPEG_QUALITY, 20});
        
        • filename.jpeg 将输出文件名
        • src 是读取包含变量的源图像
        • (vector&lt;int&gt;) 类型转换
        • {CV_IMWRITE_JPEG_QUALITY, 20} 要作为 Param_ID 和 imwrite 函数中的 Param_value 传递的元素数组

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-06-20
          • 2017-04-07
          • 2010-10-16
          • 1970-01-01
          • 2014-02-02
          • 2011-03-29
          • 2010-11-29
          相关资源
          最近更新 更多