jpeg图像质量参数及icc信息提取
图像编码算法都有相应的质量参数,如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信息提取相关推荐
- CT一般扫描参数_CT图像质量参数
第五期内镜培训 理论+实操 助您进攻内镜行业! 名额有限,快点击原文报名 详情可点击下方图片查看 ▼ 来源:器械之家 在获取一幅CT图像后,最重要的问题是对图像可靠性.正确程度进行评价.成像系统整机性 ...
- 在NVIDIA A100 GPU上利用硬件JPEG解码器和NVIDIA nvJPEG库
在NVIDIA A100 GPU上利用硬件JPEG解码器和NVIDIA nvJPEG库 根据调查,普通人产生的1.2万亿张图像可以通过电话或数码相机捕获.这样的图像的存储,尤其是以高分辨率的原始格式, ...
- NVIDIA A100 GPUs上硬件JPEG解码器和NVIDIA nvJPEG库
NVIDIA A100 GPUs上硬件JPEG解码器和NVIDIA nvJPEG库 Leveraging the Hardware JPEG Decoder and NVIDIA nvJPEG Lib ...
- 【图像】jpg与jpeg的区别
大家在浏览网页时,总能看到各种各样的精美图片,将这些图片下载下来后,有可能是JPG格式,也可能是JPEG格式,当然还有其它PNG.GIF等格式,相对于PNG等格式来说,JPG格式的体积相对较小,这也是 ...
- JPG:文件格式系列科普之.JPEG/.JPG(转)
当我们在互联网上浏览内容时,总会看到各种各样的图片,比如在你刷IT之家时,所看到的绝大部分图片都是JPG格式的,这种图片格式之所以在互联网上广受欢迎,是因为相比于PNG.GIF格式,它的体积相对较小, ...
- jpg图片与jpeg图片格式的区别(没有区别,.jpg只是扩展名.jpeg的缩写)JPEG图像压缩(YUV4:2:0 缩减采样、缩减取样)(离散余弦变换 DCT算法)(量化)(熵编码)(霍夫曼哈夫曼)
文章目录 20191026 20220414 更新,更系统去了解里面的编码压缩流程 科普:关于图像格式JPG和JPEG你知多少? 一.前言 二.JPEG和JPG的关系 三.色彩空间转换 缩减取样 离散 ...
- java图像白平衡_Camera.Parameters 参数
public classCamera.Parameters extends Objectjava.lang.Object ↳ android.hardware.Camera.Parameters Cl ...
- 利用JPEG制作更快,更准确的神经网络
Uber AI Labs介绍了一种制作神经网络的方法,该方法通过破解libjpeg并利用JPEG表示来更快,更准确的完成图像处理的任务.本文来自Uber Engineering博客,LiveVideo ...
- 海康威视API-单帧数据捕获并保存成JPEG图片NET_DVR_CaptureJPEGPicture
函 数: BOOL NET_DVR_CaptureJPEGPicture(LONG lUserID, LONG lChannel, LPNET_DVR_JPEGPARA lpJpegPara, cha ...
最新文章
- RTD 比率式温度测量传感器设计思路
- php删除空标签_PHP如何去除Html所有标签、空格以及空白
- 栈应用之 括号匹配问题(Python 版)
- Linux-makefile
- no signatures that match those in shared user android.uid.system; ignoring!
- 自旋锁和互斥锁实例_自旋锁和互斥锁的实现以及使用区别
- [Swift]LeetCode483. 最小好进制 | Smallest Good Base
- php 安全包含文件系统,PHP_PHP四大安全策略,一、文件系统安全php如果具有r - phpStudy...
- 面向区块链的高效物化视图维护和可信查询
- iphone openssh
- Android 系统(94)---android系统属性(ro.com.google.clientidbase.ms)随卡适配
- 关于 JQuery 的克隆
- 从 Ops 到 NoOps,阿里文娱智能运维的关键:自动化应用容量管理
- c语言求统计硬币正反次数,C语言猜测硬币正反面
- AMEsim柱塞泵的建模学习
- java设计模式——adapter模式
- 学士后java单元项目答案_北大青鸟学士后java工程师第二单元项目源代码
- 锐捷S12010交换机配置端口镜像
- 分位数回归--基于R
- 记录一下unity3d资源加载Resources.Load资源加载的坑
热门文章
- Unity 2d 机器人的来回巡游
- 清华大学 博士后 原来入的计算机科学与技术 现在能入软件工程吗,清华大学软件学院...
- 【Shader特效10】体积雾特效的使用
- 百度、华为、京东、B站最新面试题汇集,含泪整理面经
- 如何将excel三列数据合为一列日期数据
- ANSYS有限元仿真分析:边界非线性 (接触Contact)
- 三星S5终于降临 4月上市开卖的新机盘点
- Windows11电脑丢失了数据该怎么恢复?
- mysql数据库误删后能恢复吗_MySQL 数据库误删除后的数据恢复
- 中国工商银行网上银行新B2C在线支付接口文档下载地址