图像编码算法都有相应的质量参数,如hevc编码中的qp值(值越大,压缩率越高),jpeg中的quality(对应到DCT变换后的量化程度)。最近看了看如何根据jpeg图像中的量化文件统计其quality参数,记录下过程。

jpeg文件中可以携带icc颜色配置信息,这个参数告诉显示器用什么色域来显示图像,如下图文件中包含了Adobe RGB色彩描述文件,icc文件大小通常为几百个字节,嵌入在APP2 marker(0xe2)中。

我的环境:linux centos、libjpeg turbo库
Talk is cheap, Show me your code…

#include <stdio.h>
#include <math.h>#include "jpeglib.h"
#include <setjmp.h>
#include "turbojpeg.h"
#include "cdjpeg.h"//标准亮度分量量化表
static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {16,  11,  10,  16,  24,  40,  51,  61,12,  12,  14,  19,  26,  58,  60,  55,14,  13,  16,  24,  40,  57,  69,  56,14,  17,  22,  29,  51,  87,  80,  62,18,  22,  37,  56,  68, 109, 103,  77,24,  35,  55,  64,  81, 104, 113,  92,49,  64,  78,  87, 103, 121, 120, 101,72,  92,  95,  98, 112, 100, 103,  99
};//标准色度分量量化表
static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {17,  18,  24,  47,  99,  99,  99,  99,18,  21,  26,  66,  99,  99,  99,  99,24,  26,  56,  99,  99,  99,  99,  99,47,  66,  99,  99,  99,  99,  99,  99,99,  99,  99,  99,  99,  99,  99,  99,99,  99,  99,  99,  99,  99,  99,  99,99,  99,  99,  99,  99,  99,  99,  99,99,  99,  99,  99,  99,  99,  99,  99
};const char *subsampName[TJ_NUMSAMP] = {"4:4:4", "4:2:2", "4:2:0", "Grayscale", "4:4:0", "4:1:1"
};const char *colorspaceName[TJ_NUMCS] = {"RGB", "YCbCr", "GRAY", "CMYK", "YCCK"
};//读取JPG文件的质量参数
int ReadJpegInfo(const char *filename, char *icc_filename)
{FILE * infile = fopen(filename, "rb");fseek(infile,0,SEEK_END);       //把文件指针移到文件末尾size_t sz = ftell(infile);      //获取文件指针相对文件首的偏移数fseek(infile,0,SEEK_SET);       //把文件指针移到文件头unsigned char* buffer = new unsigned char[sz];fread(buffer,1,sz,infile);fclose(infile);//如果不是JPG格式的文件返回-1if(buffer==NULL || sz <= 2 || 0xFF != (unsigned char)buffer[0] || 0xD8 != (unsigned char)buffer[1]){return -1;}struct jpeg_decompress_struct cinfo;struct jpeg_error_mgr jerr;cinfo.err = jpeg_std_error(&jerr);jpeg_create_decompress(&cinfo);jpeg_mem_src(&cinfo,(unsigned char*)buffer, sz);jpeg_save_markers(&cinfo, JPEG_APP0 + 2, 0xFFFF);jpeg_read_header(&cinfo, TRUE);int tmp_quality = 0;int linear_quality = 0;const int aver_times = 64;int times = 0;int aver_quality = 0;long temp1 = 0;long temp2 = 0;//get jpeg file infoint src_width = cinfo.image_width;int src_height = cinfo.image_height;//int jpegSubsamp = getSubsamp(cinfo);//int jpegHorSamp = cinfo.h_samp_factor;//int jpegVerSamp = cinfo.v_samp_factor;int jpegColorspace = 1;     //defaultswitch (cinfo.jpeg_color_space) {case JCS_GRAYSCALE:  jpegColorspace = TJCS_GRAY;  break;case JCS_RGB:        jpegColorspace = TJCS_RGB;  break;case JCS_YCbCr:      jpegColorspace = TJCS_YCbCr;  break;case JCS_CMYK:       jpegColorspace = TJCS_CMYK;  break;case JCS_YCCK:       jpegColorspace = TJCS_YCCK;  break;default:             jpegColorspace = -1;  break;}printf("Input Image:  %d x %d pixels, %s colorspace\n", src_width, src_height, colorspaceName[jpegColorspace]);//量化表反推,取平均值for(int i = 0; i < DCTSIZE2; i++){temp1 = cinfo.quant_tbl_ptrs[0]->quantval[i];temp2 = cinfo.quant_tbl_ptrs[1]->quantval[i];printf("DCTQUA1[%d] = %ld, DCTQUA2[%d] = %ld\n", i, temp1, i, temp2);if(temp1 < 32767L && temp1 > 0){linear_quality = ceil((float)(temp1 * 100L - 50L)/std_luminance_quant_tbl[i]);     //100L表示long intif(linear_quality == 1) tmp_quality = 1;else if(linear_quality == 100) tmp_quality = 50;else if(linear_quality > 100)tmp_quality = ceil((float)5000 / linear_quality);elsetmp_quality = 100 - ceil((float)linear_quality/2);aver_quality += tmp_quality;times++;if(aver_times == times){aver_quality = aver_quality / aver_times;break;}}}if (icc_filename != NULL) {FILE *icc_file;JOCTET *icc_profile;unsigned int icc_len;if ((icc_file = fopen(icc_filename, "wb")) == NULL) {printf("can't open %s\n", icc_filename);}if (jpeg_read_icc_profile(&cinfo, &icc_profile, &icc_len)) {printf("icc_len = %d\n", icc_len);if (fwrite(icc_profile, icc_len, 1, icc_file) < 1) {printf("can't read ICC profile from %s\n", icc_filename);free(icc_profile);fclose(icc_file);}free(icc_profile);fclose(icc_file);}else{printf("no icc file found\n");}//else if (cinfo.err->msg_code != JWRN_BOGUS_ICC)//    printf("no ICC profile data in JPEG file\n");}jpeg_destroy_decompress(&cinfo);return aver_quality;
}
// g++ -L /opt/libjpeg-turbo/lib64 -lturbojpeg -ljpeg get_jpg_quality.cpp -o quality
// ./quality xxx.jpg
int main(int argc, char **argv)
{if(argc != 2){printf("parameter number should set to 2\n");return -1;}char icc_filename[100] = {0};sprintf(icc_filename, "%s.icc", argv[1]);printf("quality: %d\n", ReadJpegInfo(argv[1], icc_filename));return 0;
}

运行结果如下,计算得到quality为92.

参考
[1] libjpeg-turbo/libjpeg-turbo

jpeg图像质量参数及icc信息提取相关推荐

  1. CT一般扫描参数_CT图像质量参数

    第五期内镜培训 理论+实操 助您进攻内镜行业! 名额有限,快点击原文报名 详情可点击下方图片查看 ▼ 来源:器械之家 在获取一幅CT图像后,最重要的问题是对图像可靠性.正确程度进行评价.成像系统整机性 ...

  2. 在NVIDIA A100 GPU上利用硬件JPEG解码器和NVIDIA nvJPEG库

    在NVIDIA A100 GPU上利用硬件JPEG解码器和NVIDIA nvJPEG库 根据调查,普通人产生的1.2万亿张图像可以通过电话或数码相机捕获.这样的图像的存储,尤其是以高分辨率的原始格式, ...

  3. NVIDIA A100 GPUs上硬件JPEG解码器和NVIDIA nvJPEG库

    NVIDIA A100 GPUs上硬件JPEG解码器和NVIDIA nvJPEG库 Leveraging the Hardware JPEG Decoder and NVIDIA nvJPEG Lib ...

  4. 【图像】jpg与jpeg的区别

    大家在浏览网页时,总能看到各种各样的精美图片,将这些图片下载下来后,有可能是JPG格式,也可能是JPEG格式,当然还有其它PNG.GIF等格式,相对于PNG等格式来说,JPG格式的体积相对较小,这也是 ...

  5. JPG:文件格式系列科普之.JPEG/.JPG(转)

    当我们在互联网上浏览内容时,总会看到各种各样的图片,比如在你刷IT之家时,所看到的绝大部分图片都是JPG格式的,这种图片格式之所以在互联网上广受欢迎,是因为相比于PNG.GIF格式,它的体积相对较小, ...

  6. jpg图片与jpeg图片格式的区别(没有区别,.jpg只是扩展名.jpeg的缩写)JPEG图像压缩(YUV4:2:0 缩减采样、缩减取样)(离散余弦变换 DCT算法)(量化)(熵编码)(霍夫曼哈夫曼)

    文章目录 20191026 20220414 更新,更系统去了解里面的编码压缩流程 科普:关于图像格式JPG和JPEG你知多少? 一.前言 二.JPEG和JPG的关系 三.色彩空间转换 缩减取样 离散 ...

  7. java图像白平衡_Camera.Parameters 参数

    public classCamera.Parameters extends Objectjava.lang.Object ↳ android.hardware.Camera.Parameters Cl ...

  8. 利用JPEG制作更快,更准确的神经网络

    Uber AI Labs介绍了一种制作神经网络的方法,该方法通过破解libjpeg并利用JPEG表示来更快,更准确的完成图像处理的任务.本文来自Uber Engineering博客,LiveVideo ...

  9. 海康威视API-单帧数据捕获并保存成JPEG图片NET_DVR_CaptureJPEGPicture

    函 数: BOOL NET_DVR_CaptureJPEGPicture(LONG lUserID, LONG lChannel, LPNET_DVR_JPEGPARA lpJpegPara, cha ...

最新文章

  1. RTD 比率式温度测量传感器设计思路
  2. php删除空标签_PHP如何去除Html所有标签、空格以及空白
  3. 栈应用之 括号匹配问题(Python 版)
  4. Linux-makefile
  5. no signatures that match those in shared user android.uid.system; ignoring!
  6. 自旋锁和互斥锁实例_自旋锁和互斥锁的实现以及使用区别
  7. [Swift]LeetCode483. 最小好进制 | Smallest Good Base
  8. php 安全包含文件系统,PHP_PHP四大安全策略,一、文件系统安全php如果具有r - phpStudy...
  9. 面向区块链的高效物化视图维护和可信查询
  10. iphone openssh
  11. Android 系统(94)---android系统属性(ro.com.google.clientidbase.ms)随卡适配
  12. 关于 JQuery 的克隆
  13. 从 Ops 到 NoOps,阿里文娱智能运维的关键:自动化应用容量管理
  14. c语言求统计硬币正反次数,C语言猜测硬币正反面
  15. AMEsim柱塞泵的建模学习
  16. java设计模式——adapter模式
  17. 学士后java单元项目答案_北大青鸟学士后java工程师第二单元项目源代码
  18. 锐捷S12010交换机配置端口镜像
  19. 分位数回归--基于R
  20. 记录一下unity3d资源加载Resources.Load资源加载的坑

热门文章

  1. Unity 2d 机器人的来回巡游
  2. 清华大学 博士后 原来入的计算机科学与技术 现在能入软件工程吗,清华大学软件学院...
  3. 【Shader特效10】体积雾特效的使用
  4. 百度、华为、京东、B站最新面试题汇集,含泪整理面经
  5. 如何将excel三列数据合为一列日期数据
  6. ANSYS有限元仿真分析:边界非线性 (接触Contact)
  7. 三星S5终于降临 4月上市开卖的新机盘点
  8. Windows11电脑丢失了数据该怎么恢复?
  9. mysql数据库误删后能恢复吗_MySQL 数据库误删除后的数据恢复
  10. 中国工商银行网上银行新B2C在线支付接口文档下载地址