将图像的rgb数据转成DICOM医学图像格式

dcmtk官方文档:https://support.dcmtk.org/docs/
dcmtk最新源码下载:https://www.dcmtk.org/en/dcmtk/dcmtk-software-development/
dcmtk旧版本源码下载:https://dicom.offis.de/download/dcmtk/

用DCMTK库实现将图像转成dcm格式

dcmtk库的编译这里就不叙述了,网上有很多这方面的详细内容。直接上代码:

#include <iostream>
#include "opencv2/opencv.hpp"
#include "dcmtk/config/osconfig.h"
#include "dcmtk/dcmdata/dctk.h"
#include "dcmtk/dcmimgle/dcmimage.h"
#include "dcmtk/dcmdata/libi2d/i2djpgs.h"
#include "dcmtk/dcmjpeg/djencode.h"
#include "dcmtk/dcmjpeg/djrplol.h"using namespace std;
bool ToDicom()
{DcmFileFormat dicomfile;DcmDataset *dataset = dicomfile.getDataset();Uint32 all_len = 0;E_TransferSyntax ts = EXS_LittleEndianExplicit;cv::Mat mt = cv::imread("test.jpg");cv::cvtColor(mt, mt, cv::COLOR_BGR2RGB);/*	添加患者信息	*/dataset->putAndInsertUint16(DCM_AccessionNumber, 0);dataset->putAndInsertString(DCM_PatientName, "李与白", true);dataset->putAndInsertString(DCM_PatientID, "201210409217");dataset->putAndInsertString(DCM_PatientBirthDate, "19900612");dataset->putAndInsertString(DCM_PatientSex, "男");dataset->putAndInsertString(DCM_PatientAge, "32");dataset->putAndInsertString(DCM_InstitutionName, "四川大学华西医院");dataset->putAndInsertString(DCM_InstitutionalDepartmentName, "InstitutionalDepartmentName");/*	添加Study信息	*/dataset->putAndInsertString(DCM_StudyDate, "StudyDate");dataset->putAndInsertString(DCM_StudyTime, "StudyTime");dataset->putAndInsertString(DCM_StudyDescription, "StudyDescription");char uid[100];dcmGenerateUniqueIdentifier(uid, SITE_STUDY_UID_ROOT);dataset->putAndInsertString(DCM_StudyInstanceUID, uid);dataset->putAndInsertString(DCM_StudyID, "SF11240921450001");/*	添加Series信息	*/dataset->putAndInsertString(DCM_SeriesDate, "SeriesDate");dataset->putAndInsertString(DCM_SeriesTime, "SeriesTime");dataset->putAndInsertString(DCM_SeriesDescription, "SeriesDescription");memset(uid, 0, sizeof(char) * 100);dcmGenerateUniqueIdentifier(uid, SITE_SERIES_UID_ROOT);dataset->putAndInsertString(DCM_SeriesInstanceUID, uid);/*	添加Image信息	*/dataset->putAndInsertString(DCM_PlanarConfiguration, "0");dataset->putAndInsertString(DCM_ImageType, "ORIGINAL\\PRIMARY\\AXIAL");dataset->putAndInsertString(DCM_ContentDate, "ContentDate");dataset->putAndInsertString(DCM_ContentTime, "ContentTime");dataset->putAndInsertString(DCM_InstanceCreationDate, "20231125");//年月日dataset->putAndInsertString(DCM_InstanceCreationTime, "090750");//09:07:50dataset->putAndInsertString(DCM_AcquisitionDate, "20231126");dataset->putAndInsertString(DCM_AcquisitionTime, "090751");dataset->putAndInsertString(DCM_InstanceNumber, "1");dataset->putAndInsertString(DCM_PixelSpacing, "0.3\\0.3");dataset->putAndInsertString(DCM_WindowCenter, "600"); //源图像的窗位dataset->putAndInsertString(DCM_WindowWidth, "800");//源图像的窗宽dataset->putAndInsertString(DCM_RescaleIntercept, "0");//灰度偏移dataset->putAndInsertString(DCM_RescaleSlope, "1");dataset->putAndInsertString(DCM_NumberOfFrames, "1");dataset->putAndInsertUint16(DCM_SamplesPerPixel, 3);dataset->putAndInsertUint16(DCM_Rows, mt.rows);dataset->putAndInsertUint16(DCM_Columns, mt.cols);dataset->putAndInsertUint16(DCM_BitsAllocated, 8);dataset->putAndInsertUint16(DCM_BitsStored, 8);dataset->putAndInsertUint16(DCM_HighBit, 7);dataset->putAndInsertUint8Array(DCM_PixelData, (Uint8*)mt.data, mt.channels()*mt.total());dataset->putAndInsertOFStringArray(DCM_PhotometricInterpretation, "RGB");if (dataset->canWriteXfer(ts)){OFCondition status = dicomfile.saveFile("test.dcm", ts);if (status.good()){std::cout << "save ok" << std::endl;return true;}else{std::cerr << "Error saving DICOM file: " << status.text() << std::endl;return false;}}else{cout << "can not write" << endl;return false;}
}int main()
{ToDicom();system("pause");return 0;
}

代码中用到了opencv图像处理库,主要是方便读取图像数据,而且可以通过opencv将其支持的任何格式转成dcm格式。

如果转换后的dcm图像打不开则可以用dcmdump.exe进行调试:

  1. 进入到dcmdump.exe所在文件夹
  2. 在地址栏输入cmd回车
  3. 在弹出的提示符中输入:

dcmdump.exe d:/test.dcm

然后回车就能看到文件信息
在这里插入图片描述

对未编码的dcm文件进行编码或改变其编码方式

int main()
{DJEncoderRegistration::registerCodecs(); // 注册JPEG编解码器DcmFileFormat fileformat;if (fileformat.loadFile("test.dcm").good()){DcmDataset *dataset = fileformat.getDataset();DcmItem *metaInfo = fileformat.getMetaInfo();// 创建数据集的无损JPEG版本if (dataset->chooseRepresentation(EXS_JPEGProcess14SV1, NULL).good() && dataset->canWriteXfer(EXS_JPEGProcess14SV1)){// store in lossless JPEG formatOFCondition status = fileformat.saveFile("test_jpeg.dcm", EXS_JPEGProcess14SV1);if (status.good())std::cout << "encode jpeg ok" << std::endl;elsestd::cout << "encode jpeg err" << std::endl;}elsestd::cout << "chooseRepresentation err" << std::endl;}DJEncoderRegistration::cleanup();system("pause");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/180232.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++二分查找、离线算法:最近的房间

作者推荐 利用广度优先或模拟解决米诺骨牌 本文涉及的基础知识点 二分查找算法合集 题目 一个酒店里有 n 个房间&#xff0c;这些房间用二维整数数组 rooms 表示&#xff0c;其中 rooms[i] [roomIdi, sizei] 表示有一个房间号为 roomIdi 的房间且它的面积为 sizei 。每一…

mitmproxy安装以及模拟接口数据返回

使用pycharm直接安装&#xff0c;pip install mitmproxy 安装成功后直接使用命令mitmdump --version查看版本 然后自己本地下载https://mitmproxy.org/downloads/#10.1.1/ 之后一步步安装即可 安装成功后这里会出现一个.mitmproxy文件 双击这个文件进入开始安装证书 我…

【闲读 1】量子论引出对认知的思考

文章目录 一、物理学的两朵乌云故事量子力学的世界 二、 波粒二象性三、量子不确定性四、感知尺度 混沌学院课程《【物理学思维】第四节 量子论》&#xff0c;观后感。 一、物理学的两朵乌云故事 19世纪末&#xff0c;著名的物理学家开尔文爵士&#xff08;温度单位命民&…

vue2通过权限控制tab标签显示和隐藏

vue2通过权限控制tab标签显示和隐藏 1、前言2、v-if实现自定义控制 1、前言 在开发过程中&#xff0c;我们可能会遇到这样一个场景&#xff1a;根据不同权限对tab栏内容进行控制&#xff0c;这时候用自定义指令v-permission就达不到我们想要的效果&#xff0c;其是将当前节点的…

图书管理系统源码,图书管理系统开发,图书借阅系统源码整体功能演示

用户登录 基础资料 操作员管理 超期罚金设置 读者分类 读者管理 图书分类 图书管理 图书借还管理 图书借取 图书还去 图书借还查询 读者借书排行 用户登录 运行View目录下Login文件夹下的Index.csthml出现登录界面&#xff0c;输入用户名密码分别是admin密码admin12…

IDEA删除的文件怎么找回更新

一、 查找本地历史记录IDEA在进行代码版本管理时&#xff0c;会自动创建本地历史记录&#xff0c;如果我们误删了文件&#xff0c;可以通过查找本地历史记录来找回文件。 1.在项目中&#xff0c;选中被删文件的父级目录&#xff0c;“File”->“Local History”->“Show…

智能优化算法应用:基于头脑风暴算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于头脑风暴算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于头脑风暴算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.头脑风暴算法4.实验参数设定5.算法结果6.参考…

Linux:文件系统初步理解

文章目录 文件的初步理解C语言中对文件的接口系统调用的接口位图的理解open调用接口 文件和进程的关系进程和文件的低耦合 如何理解一切皆文件&#xff1f; 本篇总结的是关于Linux中文件的各种知识 文件的初步理解 在前面的文章中有两个观点&#xff0c;1. 文件 内容 属性&…

算法通关村-----数据流的中位数

数据流的中位数 问题描述 中位数是有序整数列表中的中间值。如果列表的大小是偶数&#xff0c;则没有中间值&#xff0c;中位数是两个中间值的平均值。 例如 arr [2,3,4] 的中位数是 3 。 例如 arr [2,3] 的中位数是 (2 3) / 2 2.5 。 实现 MedianFinder 类: MedianFin…

yolov8-seg 分割推理流程

目录 一、分割检测 二、图像预处理 二、推理 三、后处理与可视化 3.1、后处理 3.2、mask可视化 四、完整pytorch代码 一、分割检测 注&#xff1a;本篇只是阐述推理流程&#xff0c;tensorrt实现后续跟进。 yolov8-pose的tensorrt部署代码稍后更新&#xff0c;还是在仓…

探索数字化转型项目的基础

从消费品到特种化学品&#xff0c;数字化转型正在各行各业中逐渐普及。然而&#xff0c;尽管使用智能化设备、连接解决方案和数据分析对改造升级制造运营模式有巨大帮助&#xff0c;但起步过程&#xff08;奠定一个良好的基础来支撑工厂的可访问性、可靠性、可维护性、可扩展性…

java中IO知识点概念

这里写自定义目录标题 内存中的数据以电子信号的形式表示&#xff0c;而磁盘中的数据是以磁场的方向表示。1.流的分类2.File类3.流的API 关键4.理解缓冲的作用-一次性多拿些读写文件的时候为什么要有缓冲流 -意义是什么缓冲流的使用 5.路径问题6.文件的创建7.内存和磁盘存储本质…

【3D程序软件】SideFX与上海道宁一直为设计师提供程序化 3D动画和视觉效果工具,旨在创造高质量的电影效果

Houdini是一个 从头开始构建的程序系统 使艺术家能够自由工作 创建多次迭代 并与同事快速共享工作流程 Houdini FX为 视觉特效艺术家创作故事片 广告或视频游戏 凭借其基于程序节点的工作流程 Houdini FX可让 您更快地创建更多内容 从而缩短时间并 在所有创意任务中…

ESP Multi-Room Music 方案:支持音频实时同步播放 实现音乐互联共享

项目背景 随着无线通信技术的发展&#xff0c;针对不同音频应用领域的无线音频产品正不断涌现。近日&#xff0c;乐鑫科技推出了基于 Wi-Fi 的多扬声器互联共享音乐通信协议——ESP Multi-Room Music 方案。该方案使用乐鑫自研的基于 Wi-Fi 局域网的音频同步播放技术&#xff…

51单片机使用串口查看程序执行的数据

51单片机使用串口查看程序执行的数据 1.概述 这篇文章介绍利用串口输出程序执行的数据&#xff0c;辅助我们调试程序&#xff0c;提高代码定位问题的效率。 2.硬件电路原理 3.串口助手查看程序数据 输出串口数据的方式分为CPU查询方式和中断方式。他们各有优缺点&#xff0…

源码剖析 Spring Security 的实现原理

Spring Security 是一个轻量级的安全框架&#xff0c;可以和 Spring 项目很好地集成&#xff0c;提供了丰富的身份认证和授权相关的功能&#xff0c;而且还能防止一些常见的网络攻击。我在工作中有很多项目都使用了 Spring Security 框架&#xff0c;但基本上都是浅尝辄止&…

Java 8 中 ReentrantLock 与 Synchronized 的区别

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

《微信小程序开发从入门到实战》学习三十五

4.2 云开发JSON数据库 4.2.3 权限控制 在云开发控制台可以对数据库中的数据进行操作&#xff0c; 在小程序端和云函数可以分别使用小程序API和服务端API对数据中的数据进行操作。 以上操作受到权限控制。 对数据库进行查询属于读操作&#xff0c;增删改操作属于写操作。 …

Day44力扣打卡

打卡记录 给小朋友们分糖果 II&#xff08;容斥原理 隔板法&#xff09; 链接 def c2(n):return n * (n - 1) // 2 if n > 1 else 0class Solution:def distributeCandies(self, n: int, limit: int) -> int:return c2(n 2) - 3 * c2(n - limit 1) 3 * c2(n - 2 * …

uniapp+微信小程序监听返回事件

代码附在最后 适用场景&#xff1a;uniapp开发微信小程序 需求是我点击列表进入数据信息的详情界面&#xff0c;点击详情界面的收藏&#xff0c;返回上一界面后&#xff0c;更新列表中的收藏情况。 目录 一、使用onUnload监听页面卸载 二、使用getCurrentPages()获取当前页…