DCMTK 中源代码中使用 Overlay 的例子
在查找 Dicom 中的 Overlay 相关的 Tag 使用方法时,基本上网上能找到的都是 Overlay Tag 的说明。使用 DCMTK 对 Overlay 读写的实例代码很少。
- 收集的几个三方库关于 overlay 的使用
leadtools 关于 overlay 使用
https://www.leadtools.com/help/sdk/v21/dicom/api/class-example.html#!pydicom关于 overlay 使用
https://pydicom.github.io/pydicom/dev/old/working_with_overlays.htmlciods关于 overlay 使用
https://dicom.innolitics.com/ciods/ct-image/overlay-plane/60xx0050clearcanvas 关于 overlay 使用
https://documentation.clearcanvas.ca/Documentation/DevelopersGuide/1_5_SP1/index.html?add_a_dicom_bitmap_overlay_plane.htm
- 示例源代码
后来,发现最好的示例代码,就是 DCMTK 的 源代码,而源代码中最好的示例,就是下面的一个类:DVPSOverlay。为了避免再次找源代码,就直接把源代码摘抄如下:
/*** Copyright (C) 1998-2018, OFFIS e.V.* All rights reserved. See COPYRIGHT file for details.** This software and supporting documentation were developed by** OFFIS e.V.* R&D Division Health* Escherweg 2* D-26121 Oldenburg, Germany*** Module: dcmpstat** Author: Marco Eichelberg** Purpose:* classes: DVPSOverlay**/#include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
#include "dcmtk/dcmpstat/dvpsov.h"
#include "dcmtk/ofstd/ofstring.h"
#include "dcmtk/dcmpstat/dvpsdef.h" /* for constants and macros *//* --------------- class DVPSOverlay --------------- */DVPSOverlay::DVPSOverlay()
: overlayGroup(0)
, overlayRows(DCM_OverlayRows)
, overlayColumns(DCM_OverlayColumns)
, overlayType(DCM_OverlayType)
, overlayOrigin(DCM_OverlayOrigin)
, overlayBitsAllocated(DCM_OverlayBitsAllocated)
, overlayBitPosition(DCM_OverlayBitPosition)
, overlayData(DCM_OverlayData)
, overlayDescription(DCM_OverlayDescription)
, overlayLabel(DCM_OverlayLabel)
{
}DVPSOverlay::DVPSOverlay(const DVPSOverlay& copy)
: overlayGroup(copy.overlayGroup)
, overlayRows(copy.overlayRows)
, overlayColumns(copy.overlayColumns)
, overlayType(copy.overlayType)
, overlayOrigin(copy.overlayOrigin)
, overlayBitsAllocated(copy.overlayBitsAllocated)
, overlayBitPosition(copy.overlayBitPosition)
, overlayData(copy.overlayData)
, overlayDescription(copy.overlayDescription)
, overlayLabel(copy.overlayLabel)
{
}DVPSOverlay::~DVPSOverlay()
{
}OFCondition DVPSOverlay::read(DcmItem &dset, Uint8 ovGroup, Uint8 asGroup)
{OFCondition result = EC_Normal;DcmStack stack;if (asGroup==0xFF) asGroup=ovGroup;overlayGroup = asGroup;Uint16 gtag = 0x6000 + ovGroup;overlayRows.setGTag(gtag);overlayColumns.setGTag(gtag);overlayType.setGTag(gtag);overlayOrigin.setGTag(gtag);overlayBitsAllocated.setGTag(gtag);overlayBitPosition.setGTag(gtag);overlayData.setGTag(gtag);overlayDescription.setGTag(gtag);overlayLabel.setGTag(gtag);READ_FROM_DATASET(DcmUnsignedShort, EVR_US, overlayRows)READ_FROM_DATASET(DcmUnsignedShort, EVR_US, overlayColumns)READ_FROM_DATASET(DcmCodeString, EVR_CS, overlayType)READ_FROM_DATASET(DcmSignedShort, EVR_SS, overlayOrigin)READ_FROM_DATASET(DcmUnsignedShort, EVR_US, overlayBitsAllocated)READ_FROM_DATASET(DcmUnsignedShort, EVR_US, overlayBitPosition)READ_FROM_DATASET(DcmOverlayData, EVR_OverlayData, overlayData)READ_FROM_DATASET(DcmLongString, EVR_LO, overlayDescription)READ_FROM_DATASET(DcmLongString, EVR_LO, overlayLabel)/* Now perform basic sanity checks and adjust use flags */if (overlayRows.getLength() == 0){result=EC_IllegalCall;DCMPSTAT_WARN("presentation state contains an overlay with overlayRows absent or empty");}else if (overlayRows.getVM() != 1){result=EC_IllegalCall;DCMPSTAT_WARN("presentation state contains an overlay with overlayRows VM != 1");}if (overlayColumns.getLength() == 0){result=EC_IllegalCall;DCMPSTAT_WARN("presentation state contains an overlay with overlayColumns absent or empty");}else if (overlayColumns.getVM() != 1){result=EC_IllegalCall;DCMPSTAT_WARN("presentation state contains an overlay with overlayColumns VM != 1");}if (overlayType.getLength() == 0){result=EC_IllegalCall;DCMPSTAT_WARN("presentation state contains an overlay with overlayType absent or empty");}else if (overlayType.getVM() != 1){result=EC_IllegalCall;DCMPSTAT_WARN("presentation state contains an overlay with overlayType VM != 1");}if (overlayOrigin.getLength() == 0){result=EC_IllegalCall;DCMPSTAT_WARN("presentation state contains an overlay with overlayOrigin absent or empty");}else if (overlayOrigin.getVM() != 2){result=EC_IllegalCall;DCMPSTAT_WARN("presentation state contains an overlay with overlayOrigin VM != 2");}if (overlayBitsAllocated.getLength() == 0){result=EC_IllegalCall;DCMPSTAT_WARN("presentation state contains an overlay with overlayBitsAllocated absent or empty");}else if (overlayBitsAllocated.getVM() != 1){result=EC_IllegalCall;DCMPSTAT_WARN("presentation state contains an overlay with overlayBitsAllocated VM != 1");}if (overlayBitPosition.getLength() == 0){result=EC_IllegalCall;DCMPSTAT_WARN("presentation state contains an overlay with overlayBitPosition absent or empty");}else if (overlayBitPosition.getVM() != 1){result=EC_IllegalCall;DCMPSTAT_WARN("presentation state contains an overlay with overlayBitPosition VM != 1");}/* in a presentation state object, the overlay data must always be present in this group */if (overlayData.getLength() == 0){result=EC_IllegalCall;DCMPSTAT_WARN("presentation state contains an overlay with overlayData absent or empty");}return result;
}OFCondition DVPSOverlay::write(DcmItem &dset)
{OFCondition result = EC_Normal;DcmElement *delem=NULL;Uint16 repeatingGroup = 0x6000 + overlayGroup;ADD_REPEATING_ELEMENT_TO_DATASET(DcmUnsignedShort, overlayRows, repeatingGroup)ADD_REPEATING_ELEMENT_TO_DATASET(DcmUnsignedShort, overlayColumns, repeatingGroup)ADD_REPEATING_ELEMENT_TO_DATASET(DcmCodeString, overlayType, repeatingGroup)ADD_REPEATING_ELEMENT_TO_DATASET(DcmSignedShort, overlayOrigin, repeatingGroup)ADD_REPEATING_ELEMENT_TO_DATASET(DcmUnsignedShort, overlayBitsAllocated, repeatingGroup)ADD_REPEATING_ELEMENT_TO_DATASET(DcmUnsignedShort, overlayBitPosition, repeatingGroup)if (overlayData.getLength() >0){ADD_REPEATING_ELEMENT_TO_DATASET(DcmOverlayData, overlayData, repeatingGroup)}if (overlayDescription.getLength() >0){ADD_REPEATING_ELEMENT_TO_DATASET(DcmLongString, overlayDescription, repeatingGroup)}if (overlayLabel.getLength() >0){ADD_REPEATING_ELEMENT_TO_DATASET(DcmLongString, overlayLabel, repeatingGroup)}return result;
}OFBool DVPSOverlay::isSuitableAsShutter(unsigned long x, unsigned long y)
{// check that overlay is Graphic, not ROI.if (isROI()) return OFFalse;// check if overlay origin is 1\1Sint16 originX=0;Sint16 originY=0;OFCondition result = overlayOrigin.getSint16(originX,0);if (result==EC_Normal) result = overlayOrigin.getSint16(originY,1);if ((result != EC_Normal)||(originX != 1)||(originY != 1)) return OFFalse;// check if overlay size matches given image sizeUint16 rows=0;Uint16 columns=0;result = overlayRows.getUint16(rows,0);if (result==EC_Normal) result = overlayColumns.getUint16(columns,0);if (result==EC_Normal) return ((columns==x)&&(rows==y));return OFFalse;
}const char *DVPSOverlay::getOverlayLabel()
{char *c = NULL;if (EC_Normal == overlayLabel.getString(c)) return c; else return NULL;
}const char *DVPSOverlay::getOverlayDescription()
{char *c = NULL;if (EC_Normal == overlayDescription.getString(c)) return c; else return NULL;
}OFBool DVPSOverlay::isROI()
{OFString aString;if (EC_Normal == overlayType.getOFString(aString,0)){return (aString == "ROI");}return OFFalse;
}OFCondition DVPSOverlay::getValues(Sint16& originX,Sint16& originY,Uint16& sizeX,Uint16& sizeY)
{OFCondition result = overlayOrigin.getSint16(originX,1);if (result.good()) result = overlayOrigin.getSint16(originY,0);if (result.good()) result = overlayColumns.getUint16(sizeX,0);if (result.good()) result = overlayRows.getUint16(sizeY,0);return result;
}
DCMTK 中源代码中使用 Overlay 的例子相关推荐
- C语言主程序如何引用外部源代码中的函数
Introduction 代码要实现比较复杂的功能时,往往会包含非常多的函数. 当我们想再向其中添加其他功能或修改一些功能时,主程序所在的源代码会越来越冗长,查找并准确地修改某功能对应的函数也变得十分 ...
- 如何单独编译Android源代码中的模块
第一次下载好Android源代码工程后,我们通常是在android源代码工程目录下执行make命令,经过漫长的等待之后,就可以得到Android系统镜像system.img了.以后如果我们修改了And ...
- 什么工具可以分析php源代码,PHP_一个可以找出源代码中所有中文的工具,一个可以找出源代码中所有中 - phpStudy...
一个可以找出源代码中所有中文的工具 一个可以找出源代码中所有中文的工具 填写需要查找的路径$sf即可. 功能 1 找出所有中文 2 忽略注释语句中的中文 3 可添加需要忽略的文件和文件夹 4 生成日志 ...
- Java8中Lambda表达式的10个例子
Java8中Lambda表达式的10个例子 例1 用Lambda表达式实现Runnable接口 Java代码 //Before Java 8: new Thread(new Runnable() ...
- 【转】如何单独编译Android源代码中的模块--不错
原文网址:http://blog.csdn.net//article/details/6566662/ 第一次下载好Android源代码工程后,我们通常是在Android源代码工程目录下执行make命 ...
- openLayers3 中实现多个Overlay
openLayers3 中实现多个Overlay 此篇的目的是为了记录下用Overlay的一些操作. 其实实现多个就是创建多个div,然后给每个div绑定Overlay. 1 //页面加载完函数 -- ...
- “源代码中禁止显示”概述
检查代码之后,您可能确定代码是正确的.也可能是以下情况,即某些冲突的优先级较低,因此不会在当前的开发周期中修复.无论出于何种原因,以下操作通常是有用的,即指出相应警告不适用,以使小组成员了解代码已经过 ...
- pytorch tensor查找0_在PyTorch中Tensor的查找和筛选例子
本文源码基于版本1.0,交互界面基于0.4.1 import torch 按照指定轴上的坐标进行过滤 index_select() 沿着某tensor的一个轴dim筛选若干个坐标 >>&g ...
- python爬虫基础教程115_Python解析网页源代码中的115网盘链接实例
本文实例讲述了python解析网页源代码中的115网盘链接的方法.分享给大家供大家参考.具体方法分析如下: 其中的1.txt,是网页http://bbs.pediy.com/showthread.ph ...
最新文章
- 腾讯!阿里!大二男生斩获4家头部科技公司实习offer!完整经验总结!
- 观峰雨个人空间 2010 STOCK ADVICE !
- Python自动化开发 - RESTful API
- qt实现窗口拖动的两种思路
- TCP/IP学习笔记-Qt中的ReuseAddressHint以及SO_REUSEADDR,以为组播常用场景分析
- 使用php-fpm状态页观察当前的php-fpm状态
- rect函数_Python基础入门(9):从函数到高级魔法方法--阿里云天池
- EasyUi-1 拖放
- 蓝桥杯2014c++真题:切面条
- Java中OutOfMemoryError(内存溢出)的情况及解决办法
- *(绝对可以安装成功的HUAWEI eNSP模拟器)计算机网络实验(华为eNSP模拟器)——第一章 华为eNSP安装教程
- 信息流广告的发展前景!
- ROSLAUNCH 的.launch/XML 语法
- 没学历可以学IT吗?
- Flutter的原理及美团的实践(下,100%好评
- python研究背景和意义_一研究背景和意义
- 基于多种分隔符进行字符串的分割
- 推荐一款截屏翻译工具|截屏提取文字|划词翻译
- 动手写一个HTML5的无限循环滚动焦点图
- 安卓手机硬件信息修改 Device ID Changer 2020