项目中使用了DICOM文件保存图像,之前经常遇到DICOM内放置的是short类型或者float类型的二维图像,按照之前的代码处理JEPG压缩的DICOM文件,当然会出现问题;从网上查到资料,是由于JEPG需要解码器;
  把我处理的过程记录下来,以供大家参考;

JPEG格式

  JPEG的全称是JointPhotographicExpertsGroup(联合图像专家小组),它是一种常用的图像存储格式, jpg/jpeg是24位的图像文件格式,也是一种高效率的压缩格式,文件格式是JPEG(联合图像专家组)标准的产物,该标准由ISO与CCI TT(国际电报电话咨询委员会)共同制定,是面向连续色调静止图像的一种压缩标准。
  JPEG格式可以分为标准JPEG、渐进式JPEG和JPEG2000三种格式。

标准JPEG

  该类型的图片文件,在网络上应用较多,只有图片完全被加载和读取完毕之后,才能看到图片的全貌;它是一种很灵活的图片压缩方式,用户可以在压缩比和图片品质之间进行权衡。不过,通常来讲,其压缩比在10:1到40:1之间,压缩比越大,品质就越差,压缩比越小,品质就越好。JPEG格式压缩的主要是高频信息,对色彩的信息保留较好,适合应用于互联网,可减少图像的传输时间,可以支持24bit真彩色,也普遍应用于需要连续色调的图像。JPEG由于可以提供有损压缩,因此压缩比可以达到其他传统压缩算法无法比拟的程度。其压缩模式有以下几种:顺序式编码(SequentialEncoding),递增式编码(ProgressiveEncoding),无失真编码(LosslessEncoding)和阶梯式编码(HierarchicalEncoding)
  JPEG的压缩,分为四个步骤:
    (1)颜色转换:由于JPEG只支持YUV颜色模式,而不支持RGB颜色模式,所以在将彩色图像进行压缩之前,必须先对颜色模式进据转换。转换完成之后还需要进行数据采样。一般采用的采样比例是2:1:1或4:2:2。由于在执行了此项工作之后,每两行数据只保留一行,因此,采样后图像数据量将压缩为原来的一半。
    (2)DCT变换:DCT(DiscreteConsineTransform)是将图像信号在频率域上进行变换,分离出高频和低频信息的处理过程。然后再对图像的高频部分(即图像细节)进行压缩,以达到压缩图像数据的目的。首先将图像划分为多个8*8的矩阵。然后对每一个矩阵作DCT变换(变换公式此略)。变换后得到一个频率系数矩阵,其中的频率系数都是浮点数。
    (3)量化:由于在后面编码过程中使用的码本都是整数,因此需要对变换后的频率系数进行量化,将之转换为整数。由于进行数据量化后,矩阵中的数据都是近似值,和原始图像数据之间有了差异,这一差异是造成图像压缩后失真的主要原因。
    (4)编码:编码采用两种机制:一是0值的行程长度编码;二是熵编码(EntropyCoding)。在JPEG中,采用曲徊序列,即以矩阵对角线的法线方向作“之”字排列矩阵中的元素。这样做的优点是使得靠近矩阵左上角、值比较大的元素排列在行程的前面,而行程的后面所排列的矩阵元素基本上为0值。行程长度编码是非常简单和常用的编码方式,在此不再赘述。编码实际上是一种基于统计特性的编码方法。在JPEG中允许采用HUFFMAN编码或者算术编码。

渐进式JPEG

  该类型的图片是对标准JPEG格式的改进,当在网页上下载渐进式JPEG图片时,首先呈现图片的大概外貌,然后再逐渐呈现具体的细节部分,因而被称之为渐进式JPEG。

JPEG2002

  一种全新的图片压缩发,压缩品质更好,并且改善了无线传输时,因信号不稳定而造成的马赛克及位置错乱等问题。另外,作为JPEG的升级版,JPEG2000的压缩率比标准JPEG高约30%,同时支持有损压缩和无损压缩。它还支持渐进式传输,即,先传输图片的粗略轮廓,然后,逐步传输细节数据,使得图片由模糊到清晰逐步显示。此外,JPEG2000还支持感兴趣区域,也就是说,可以指定图片上感兴趣区域的压缩质量,还可以选择指定的部分先进行解压。

DCMTK解析JPEG格式DCM文件

  从DICOM文件的0x0002,0x0010的tag可以看到“JPEG lossless”;

  dcmjpeg提供了一个压缩/解压缩库以及可用工具。该模块包含一些类,可将DICOM图像对象在非压缩和JPEG压缩表示(传输协议)之间转换。无失真和有失真JPEG处理都被支持。这个模块实现了一族codec(编码解码器,由DcmCodec类派生而来),可以将这些codec在codec list中注册,codec list是由dcmdata模块保存的。
  主要接口类:
    DJEncoderRegistration: 一个singleton单例类,为所有支持的JPEG处理注册编码器。在djencode.h中定义。
    DJDecoderRegistration: 一个singleton单例类,为所有支持的JPEG处理注册解码器。在djdecode.h中定义。
    DJCodecEncoder: JPEG编码器的一个抽象codec类,在djcodece.h中定义
    DJCodecDecoder: JPEG解码器的一个抽象codec类。
在程序的开始位置,首先注册JPEG的解码器;

 DJEncoderRegistration::registerCodecs(ECC_lossyYCbCr,EUC_default, // UID generation (never create new UID's)OFFalse, // verbose0, 0, 0, true, ESS_444, true); // optimize huffman tableDJDecoderRegistration::registerCodecs();DJLSEncoderRegistration::registerCodecs();      //JPEG-LS encoder registerCodecsDJLSDecoderRegistration::registerCodecs();      //JPEG-LS decoder registerCodecs

  在程序的结束位置,释放JPEG的解码器;

DJEncoderRegistration::cleanup();
DJDecoderRegistration::cleanup();
DJLSEncoderRegistration::cleanup();     //JPEG-LS encoder cleanup
DJLSDecoderRegistration::cleanup();     //JPEG-LS decoder cleanup

  使用到的头文件如下:

#include <dcmtk/dcmjpeg/djdecode.h>  /* for dcmjpeg decoders */
#include <dcmtk/dcmjpeg/djencode.h>
#include <dcmtk/dcmjpls/djdecode.h>       //for JPEG-LS decode
#include <dcmtk/dcmjpls/djencode.h>       //for JPEG-LS encode

代码

#include <iostream>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>#include "dcmtk\config\osconfig.h"
#include "dcmtk\dcmdata\dctk.h"
#include <dcmtk/dcmjpeg/djdecode.h>  /* for dcmjpeg decoders */
#include <dcmtk/dcmjpeg/djencode.h>
#include <dcmtk/dcmjpls/djdecode.h>       //for JPEG-LS decode
#include <dcmtk/dcmjpls/djencode.h>       //for JPEG-LS encode
using namespace std;
using namespace cv;void ConvertDigitImageToGrayImageByWindowLevelAndWindowWidth(short* digitImage, short* grayImage, int size, int window_level, int window_width){double rate = 256.0 / window_width;for (size_t i = 0; i < size; i++){int tmp = 128.0 + (digitImage[i] - window_level)*rate;if (tmp < 0){tmp = 0;}else if (tmp > 255){tmp = 255;}grayImage[i] = tmp;}
}
int main()
{DJDecoderRegistration::registerCodecs();DJLSEncoderRegistration::registerCodecs();     //JPEG-LS encoder registerCodecsDJLSDecoderRegistration::registerCodecs();      //JPEG-LS decoder registerCodecsDcmFileFormat *myFileFormat = new DcmFileFormat;OFCondition cond = myFileFormat->loadFile("G:\\Data\\1.DCM");if (cond.good()){OFString patientName;if (myFileFormat->getDataset()->findAndGetOFString(DCM_PatientName, patientName).good())std::cout << "Patient Name: " << patientName << "\nTest successed.\n";else std::cout << "No Patient Name Data!\n";}else std::cout << "Error occurs when opening file, check path or filename.\n";short* pix_buf = new short[512 * 512];unsigned long size = 0;  DcmElement* pElement = nullptr;myFileFormat->getDataset()->chooseRepresentation(EXS_DeflatedLittleEndianExplicit, NULL);myFileFormat->getDataset()->findAndGetElement(DCM_PixelData, pElement);if (pElement != NULL) {size = pElement->getLength()/2;OFCondition cond = pElement->loadAllDataIntoMemory();if (cond.good()) {Uint16 * ptr;cond = pElement->getUint16Array(ptr);if (cond.good()) {ConvertDigitImageToGrayImageByWindowLevelAndWindowWidth((short*)ptr, pix_buf, size, 1000, 500);}}}Mat img = cv::Mat::zeros(512, 512, CV_8UC3);for (int i = 0; i < size; i++) {uchar* grayrowptr = img.ptr<uchar>(i / 512);//提取行指针grayrowptr[i % 512 * 3 + 0] = pix_buf[i];grayrowptr[i % 512 * 3 + 1] = pix_buf[i];grayrowptr[i % 512 * 3 + 2] = pix_buf[i];}cv::imwrite("G:\\Data\\gray_9zxr.bmp", img);imshow("Image", img);waitKey(0);system("pause");
}

  使用的DICOM文件中图像数据放到了元素组内,需要使用findAndGetElement获取;

  DCM文件中数值应该会大于256的灰度值,所以会造成图像的失真,使用窗宽和窗位调整图像显示灰度值,归一化在0-255的范围内,就会显示正常;

  代码使用的DICOM文件所在位置为:DICOM文件.rar

引用文献

1.jpeg图片格式详解

DICOM笔记-解析JPEG压缩格式DCM文件相关推荐

  1. 【转】DCMTK 开源库的学习笔记2:直接操作dcm文件中像素数据的尝试

    转自:https://blog.csdn.net/zssureqh/article/details/8785132 DCMTK官网给出了JPEG格式压缩的DCM文件解压缩的方法(http://supp ...

  2. 使用dcm4che对压缩的dcm文件进行解压

    上一篇文章说到了DCM文件的无损压缩 DICOM DCM4CHE影像压缩 本想着压缩了就大功告成 在使用的时候可以大大减少网络上传输的时间 提高网站性能 但是新的问题又出现了 问题如下 代码中获取文件 ...

  3. Directshow学习笔记六-----重新压缩一个AVI文件(个人学习总结,仅供参考)

    用DirectShow来压缩一个AVI文件 一. 选择一个压缩过滤器 有许多种方法可以压缩视频或者音频,比如: a. 本地DirectShow过滤器 b. 视频压缩管理编码器(VCM) c. 音频压缩 ...

  4. DICOM医学图像处理:DICOM存储操作之 “多幅JPG图像数据存入DCM文件”

    背景: 续上篇,继续介绍如何将多幅JPG图像数据存入DCM文件.即将有损压缩数据直接写入DCM文件,存储为Multi-frame形式. 多幅JPG图像数据存入DCM文件: 为了避免引起歧义,这里着重说 ...

  5. 【Android 内存优化】Android 工程中使用 libjpeg-turbo 压缩图片 ( 初始化压缩对象 | 打开文件 | 设置压缩参数 | 写入压缩图像数据 | 完成压缩 | 释放资源 )

    文章目录 一.使用 libjpeg-turbo 压缩图片流程 二.初始化 JPEG 压缩对象 三.打开文件 四.设置压缩参数 五.开始压缩 六.循环写入压缩数据 七.完成图片压缩及收尾 八.libjp ...

  6. windows截图c语言,window 截取屏幕,并实现jpeg压缩

    1)头文件 #include "stdafx.h" #include #include #include #pragma comment(lib,"jpeglib/lib ...

  7. 关于Hive中的存储格式及压缩格式详解

    最近面试,遇到了关于Hive的数据存储格式的问题,回答不尽人意,抽时间总结多看看关于Hive存储格式和压缩格式的内容. Hive底层数据是以HDFS文件的形式存储在Hadoop中的,选择一个合适的文件 ...

  8. Unity中的图片压缩格式选择

    图片格式 不同格式的本质区别在于压缩算法不一样,结果图片大小,还原度也各不相同. 常用图片格式有Png,Jpg,Tga,Psd等.平时主要用Png,Jpg. Jpg是有损压缩不透明,Png是无损压缩有 ...

  9. android视频压分辨率压缩,视频的文件格式、压缩格式、码率、分辨率

    首先,明确几个基本概念:视频的文件格式.压缩格式.码率.分辨率, 视频的文件格式有:mkv,mp4,flv,wmv,rmvb等: 视频的压缩格式有:h.263,h.264,mpeg-2,rmvb等: ...

最新文章

  1. stn专线和otn有什么区别_专线与干线运输的区别是什么?
  2. 失败如何助你升入最高管理层
  3. Scrum基础知识体系和感想
  4. 分成互质组 (信息学奥赛一本通-T1221)
  5. 【kafka】Number of alive brokers 0 does not meet the required replication factor 3
  6. 恋上数据结构完整笔记(第1季 + 第2季)
  7. 《JavaScript忍者秘籍》——1.3 跨浏览器注意事项
  8. oracle裸设备文件复制,Oracle Goldengate在HP平台裸设备文件系统OGG-01028处理
  9. Android添加受保护广播
  10. 牛客网项目1.7项目调试技巧
  11. QT软件开发: 基于QT设计的完整版视频播放器、多媒体播放器(mdk-sdk)
  12. Effective Kotlin 中文版
  13. 5G学习(一)5G通信概述
  14. arduino闪烁LED灯
  15. 【数据结构】开端序幕
  16. 《袁老师访谈录》第十一期|宗福季教授/香港科大(广州)信息枢纽署理院长【问诊未来·院长系列:拥抱数字化转型】...
  17. 英文版权声明_想避免版权问题,这些网站你一定需要
  18. RK3399——裸机大全
  19. 用selenium解决滑块验证码
  20. SQL语句后面加上for update的作用

热门文章

  1. FMEA软件——你们的FMEA还“活着”吗?
  2. 自动驾驶系统入门(四) - 车载摄像头
  3. 2022年最新《谷粒商城开发教程》:1 - 构建工程篇
  4. Oracle数据迁移MySQL
  5. Android Camera开发(一)之基础知识
  6. uboot通过u盘烧写linux内核,向Flash中烧写uboot和linux操作系统
  7. Camera2 学习(一)概览
  8. python存储mp3信息_【Python】 获取MP3信息replica
  9. Linux FTP搭建及其使用
  10. c语言中while与do while循环的主要区别是什么