123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- const parser = require('dicom-parser');
- const fsp = require('fs-promise');
- const iconv = require("iconv-lite")
- const filePath = '/Users/fuyu/DX/837DCB82.dcm';
- // const filePath = '/Users/fuyu/Desktop/MR/MR1912090041/1.2.392.200036.9125.2.138612190166.20191209000532/517D6718/7F8E6EC3.dcm';
- // const filePath = '/Users/fuyu/Downloads/5805957747722467ffe1bbbf31e81a1c';
- // const filePath = '/Users/fuyu/Downloads/d1137941cbce83e442eb2978989d059c';
- // const filePath = '/Users/fuyu/Downloads/7380ed924937d0aee73be14f32f75706';
- let test = async url => {
- const fileBuffer = await fsp.readFile(url);
- const dataSet = parser.parseDicom(fileBuffer);
- const patientName = dataSet.string(patientTag.patientName)
- // console.log(iconv.decode(patientName, 'UTF-8'))
- const charset = getCharSet(dataSet)
- console.log(patientName, iconv.decode(patientName, 'GB2312'), charset)
- // console.log(dataSet.string('x00080005'));
- // [patientTag, studyTag, seriesTag, imageTag].forEach(tags => {
- // for (let key in tags) {
- // console.log(key, dataSet.string(tags[key]))
- // }
- // })
- // const charset = getCharSet(dataSet)
- // const originalString = dataSet.string;
- // dataSet.string = (tag, index) => {
- // let value = originalString.call(dataSet, tag, index);
- // if (value != null && value != 'undefined') {
- // console.log('charset', charset)
- // let _value = iconv.decode(value, 'UTF-8');
- // // console.log()
- // if (_value != null && _value != 'undefined') {
- // return _value.replace(/['^']+/g, '')
- // }
- // return _value;
- // } else {
- // return value;
- // }
- // };
- // let text = dataSet.string('x0008103e')
- // console.log(text, iconv.decode(text, 'ISO_IR 100'))
- }
- const chatSetMap = {
- 'ISO_IR 6': 'UTF-8',
- 'ISO_IR 192': 'UTF-8',
- 'ISO_IR 100': 'ISO-8859-1',
- 'ISO_IR 101': 'ISO-8859-2',
- 'ISO_IR 109': 'ISO-8859-3',
- 'ISO_IR 110': 'ISO-8859-4',
- 'ISO_IR 144': 'ISO-8859-5',
- 'ISO_IR 127': 'ISO-8859-6',
- 'ISO_IR 126': 'ISO-8859-7',
- 'ISO_IR 138': 'ISO-8859-8',
- 'ISO_IR 148': 'ISO-8859-9',
- }
- const getCharSet = dataSet => {
- let specificCharacterSet = dataSet.string('x00080005');
- console.log(specificCharacterSet, 'specificCharacterSet')
- let charset = 'GB2312'
- if (specificCharacterSet) {
- charset = chatSetMap[specificCharacterSet] || charset
- }
- return charset
- }
- // GB2312
- // //xml文件编码方式,以支持中文显示。
- // if (!csetString.empty())
- // encString = "GB2312";
- test(filePath)
- const patientTag = {
- 'patientName': 'x00100010', //患者姓名 PN
- 'patientId': 'x00100020', //患者ID LO
- 'birthDate': 'x00100030', //患者出生日期 DA
- 'birthTime': 'x00100032', //患者出生时间 TM
- 'patientSex': 'x00100040', //患者性别 CS
- 'pregnancy': 'x001021c0', //怀孕状态 US
- 'weight': 'x00101030', //患者体重 DS
- 'institutionName': 'x00080080', //生产厂家 US
- 'institutionCode': 'x00080082', //生产厂家代码 US
- 'patientAge': 'x00101010' //做检查时刻的患者年龄 AS
- };
- // 'patientName': {
- // 'tag': 'x00100010',
- // 'vr': 'PN',
- // 'description': 'Patient’s Name',
- // 'comment': '患者姓名'
- // }, //患者姓名 PN
- const studyTag = {
- 'accessionNumber': 'x00080050', //检查号(RIS的生成序号) SH
- 'studyId': 'x00200010', //检查ID SH
- 'studyUid': 'x0020000d', //检查实例号 唯一标记 UI
- 'studyDate': 'x00080020', //检查日期(检查开始的日期) DA
- 'studyTime': 'x00080030', //检查时间(检查开始的时间) TM
- 'modalities': 'x00080061', //一个检查中含有的不同检查类型 CS
- 'partExamined': 'x00080015', //检查的部位 CS
- 'description': 'x00081030', //检查的描述 LO
- 'patientAge': 'x00101010', //做检查时刻的患者年龄 AS
- 'institutionName': 'x00080080', //生产厂家 US
- 'institutionCode': 'x00080082', //生产厂家代码 US
- };
- const seriesTag = {
- 'seriesNumber': 'x00200011', //序列号:识别不同检查的号码.
- 'seriesUid': 'x0020000e', //序列实例号:唯一标记不同序列的号码.
- 'modality': 'x00080060', //检查模态(MRI/CT/CR/DR)
- 'description': 'x0008103e', //检查描述和说明
- 'seriesDate': 'x00080021', //检查日期
- 'seriesTime': 'x00080031', //检查时间
- 'imagePosition': 'x00200032', //图像位置:图像的左上角在空间坐标系中的x,y,z坐标,单位是毫米. 如果在检查中,则指该序列中第一张影像左上角的坐标.
- 'imageOrientation': 'x00200037', //图像方位:
- 'sliceThickness': 'x00180050', //层厚
- 'spacingSlices': 'x00180088', //层与层之间的间距,单位为mm
- 'sliceLocation': 'x00201041', //实际的相对位置,单位为mm.
- 'MRAcquisition': 'x00180023', //
- 'partExamined': 'x00180015', //身体部位.
- };
- const imageTag = {
- 'imageType': 'x00080008', //图片类型 CS
- 'imageId': 'x00080018', //实例UID
- 'contentDate': 'x00080023', //影像拍摄的日期 DA
- 'contentTime': 'x00080033', //影像拍摄的时间 TM
- 'imageNumber': 'x00200013', //图像码 IS
- 'pixel': 'x00280002', //图像上的采样率. US
- 'rows': 'x00280010', //图像的总行数,行分辨率 US
- 'columns': 'x00280011', //图像的总列数,列分辨率 US
- 'pixelSpacing': 'x00280030', //像素间距(像素中心之间的物理间距) DS
- 'bitsStored': 'x00280101', //存储的位数:有12到16列举值.存储每一个像素用的位数.每一个样本应该有相同值.
- 'highBit': 'x00280102', //高位. DS
- 'pixelRepresentation': 'x00280103', //像素数据的表现类型:这是一个枚举值,分别为十六进制数0000和0001.0000H = 无符号整数,0001H = 2的补码. DS
- 'windowCenter': 'x00281050', //窗位 DS
- 'windowWidth': 'x00281051', //窗宽 DS
- 'rescaleIntercept': 'x00281052', //截距:如果表明不同模态的LUT颜色对应表不存在时,则使用方程Units = m*SV + b,计算真实的像素值到呈现像素值。其中这个值为表达式中的b
- 'rescaleSlope': 'x00281053', //斜率.这个值为表达式中的m。
- 'rescaleType': 'x00281054', //输出值的单位.这是一个枚举值,
- 'imagePosition': 'x00200032', //图像位置 DS
- 'imageOrientation': 'x00200037', //图像方位 DS
- 'SOPInstanceUID': 'x00080018', //图像方位 DS
- 'numberOfFrames': 'x00280008', //图像frame张数 DS
- 'cineRate': 'x00180040' //图像播放速率
- }
- /** Image Tag*/
- //00080008 Image Type 图片类型 CS
- //00080018 SOP Instance UID SOP实例UID
- //00080023 Content Date 影像拍摄的日期 DA
- //00080033 Content Time 影像拍摄的时间. TM
- //00200013 Image/Instance Number 图像码(辨识图像的号码) IS
- //00280002 Samples Per Pixel 图像上的采样率. US
- /**
- * MONOCHROME1,MONOCHROME2.
- * 用来判断图像是否是彩色的,
- * MONOCHROME1/2是灰度图,
- * RGB则是真彩色图,还有其他.
- */
- //00280004 Photometric Interpretation: 光度计的解释,对于CT图像,用两个枚举值 CS
- //00280010 Rows 图像的总行数,行分辨率. US
- //00280011 Columns 图像的总列数,列分辨率. US
- //00280030 Pixel Spacing 像素间距(像素中心之间的物理间距) DS
- //00280100 Bits Allocated 分配的位数(存储每一个像素值时分配的位数) US
- //00280101 Bits Stored: 存储的位数(有12到16列举值 US
- //00280102 High Bit 高位 US
- //00280103 Pixel Representation 像素数据的表现类型(枚举值,分别为十六进制数0000和0001) US
- //00281050 Window Center 窗位 DS
- //00281051 Window Width 窗宽 DS
- //00281052 Rescale Intercept 截距 DS
- //00281053 Rescale Slope 斜率 DS
- //00281054 Rescale Type 输出值的单位 LO
- /**图像的左上角在空间坐标系中的x,y,z坐标,单位是毫米. 如果在检查中,则指该序列中第一张影像左上角的坐标*/
- //00200032 Image Position 图像位置 DS
- //00200037 Image Orientation 图像方位 DS
- //00180050 Slice Thickness 层厚 DS
- //00180088 Spacing Between Slices 层与层之间的间距,单位为mm DS
- //00201041 Slice Location 实际的相对位置,单位为mm. DS
- //00180023 MR Acquisition CS
- //00180015 Body Part Examined 身体部位 CS
- const patientWADO = {
- 'patientName': ['00100010', 'PN'], //患者姓名 PN
- 'patientId': ['00100020', 'LO'], //患者ID LO
- 'birthDate': ['00100030', 'DA'], //患者出生日期 DA
- 'birthTime': ['00100032', 'TM'], //患者出生时间 TM
- 'patientSex': ['00100040', 'CS'], //患者性别 CS
- 'pregnancy': ['001021c0', 'US'], //怀孕状态 US
- 'weight': ['00101030', 'DS'], //患者体重 DS
- 'institutionName': ['00080080', 'US'], //生产厂家 US
- 'institutionCode': ['00080082', 'US'], //生产厂家代码 US
- 'patientAge': ['00101010', 'AS'] //做检查时刻的患者年龄 AS
- }
- const studyWADO = {
- 'accessionNumber': ['00080050', 'SH'], //检查号(RIS的生成序号) SH
- 'studyId': ['00200010', 'SH'], //检查ID SH
- 'studyUid': ['0020000d', 'UI'], //检查实例号 唯一标记 UI
- 'studyDate': ['00080020', 'DA'], //检查日期(检查开始的日期) DA
- 'studyTime': ['00080030', 'TM'], //检查时间(检查开始的时间) TM
- 'modalities': ['00080061', 'CS'], //一个检查中含有的不同检查类型 CS
- 'partExamined': ['00080015', 'CS'], //检查的部位 CS
- 'description': ['00081030', 'LO'], //检查的描述 LO
- 'patientAge': ['00101010', 'AS'] //做检查时刻的患者年龄 AS
- }
- const seriesWADO = {
- 'seriesNumber': ['00200011', 'IS'], //序列号:识别不同检查的号码.
- 'seriesUid': ['0020000e', 'UI'], //序列实例号:唯一标记不同序列的号码.
- 'modality': ['00080060', 'CS'], //检查模态(MRI/CT/CR/DR)
- 'description': ['0008103e', 'LO'], //检查描述和说明
- 'seriesDate': ['00080021', 'DA'], //检查日期
- 'seriesTime': ['00080031', 'DA'], //检查时间
- 'imagePosition': ['00200032', 'DS'], //图像位置:图像的左上角在空间坐标系中的x,y,z坐标,单位是毫米. 如果在检查中,则指该序列中第一张影像左上角的坐标.
- 'imageOrientation': ['00200037', 'DS'], //图像方位:
- 'sliceThickness': ['00180050', 'DS'], //层厚
- 'spacingSlices': ['00180088', 'DS'], //层与层之间的间距,单位为mm
- 'sliceLocation': ['00201041', 'DS'], //实际的相对位置,单位为mm.
- 'MRAcquisition': ['00180023', 'CS'], //
- 'partExamined': ['00180015', 'CS'], //身体部位.
- };
- const imageWADO = {
- 'imageType': ['00080008', 'CS'], //图片类型 CS
- 'imageId': ['00080018', 'UI'], //实例UID UI
- 'contentDate': ['00080023', 'DA'], //影像拍摄的日期 DA
- 'contentTime': ['00080033', 'TM'], //影像拍摄的时间 TM
- 'imageNumber': ['00200013', 'IS'], //图像码 IS
- 'pixel': ['00280002', 'US'], //图像上的采样率. US
- 'rows': ['00280010', 'US'], //图像的总行数,行分辨率 US
- 'columns': ['00280011', 'US'], //图像的总列数,列分辨率 US
- 'pixelSpacing': ['00280030', 'DS'], //像素间距(像素中心之间的物理间距) DS
- 'bitsStored': ['00280101', 'US'], //存储的位数:有12到16列举值.存储每一个像素用的位数.每一个样本应该有相同值. US
- 'highBit': ['00280102', 'DS'], //高位. DS
- 'pixelRepresentation': ['00280103', 'DS'], //像素数据的表现类型:这是一个枚举值,分别为十六进制数0000和0001.0000H = 无符号整数,0001H = 2的补码. DS
- 'windowCenter': ['00281050', 'DS'], //窗位 DS
- 'windowWidth': ['00281051', 'DS'], //窗宽 DS
- 'rescaleIntercept': ['00281052', 'DS'], //截距:如果表明不同模态的LUT颜色对应表不存在时,则使用方程Units = m*SV + b,计算真实的像素值到呈现像素值。其中这个值为表达式中的b
- 'rescaleSlope': ['00281053', 'DS'], //斜率.这个值为表达式中的m。
- 'rescaleType': ['00281054', 'DS'], //输出值的单位.这是一个枚举值,
- 'imagePosition': ['00200032', 'DS'], //图像位置 DS
- 'imageOrientation': ['00200037', 'DS'], //图像方位 DS
- 'SOPInstanceUID': ['00080018', 'DS'], //图像方位
- 'numberOfFrames': ['00280008', 'IS'] //图像frame张数 DS
- }
- // export {
- // patientTag,
- // studyTag,
- // seriesTag,
- // imageTag,
- // patientWADO,
- // studyWADO,
- // seriesWADO,
- // imageWADO
- // }
- // tag VR VM Description
- // 00080005 CS 1-n SpecificCharacterSet
- // 00080020 DA 1-1 StudyDate
- // 00080030 TM 1-1 StudyTime
- // 00080050 SH 1-1 AccessionNumbe
- // 00080056 CS 1-1 InstanceAvailability
- // 00080061 CS 1-n ModalitiesInStudy
- // 00080090 PN 1-1 ReferringPhysicianName
- // 00081190 UR 1-1 RetrieveURL
- // 00090010 LO 1-1 SpecificCharacterSet
- // 00091002 UN 1-1 SpecificCharacterSet
- // 00100010 PN 1-1 PatientName
- // 00100020 LO 1-1 PatientId
- // 00100021 LO 1-1 IssuerOfPatientID
- // 00100030 DT 1-1 PatientBirthDate
- // 00100040 CS 1-1 PatientSex
- // 00101002 SQ 1-1 OtherPatientIDsSequence
- // 0020000D UI 1-1 StudyInstanceUID
- // 00200010 SH 1-1 StudyID
- // 00201206 IS 1-1 NumberOfStudyRelatedSeries
- // 00201208 IS 1-1 NumberOfStudyRelatedInstances
- // { // Result 1
- // "00080005": {
- // "vr": "CS",
- // "Value": [ "ISO_IR 192" ]
- // },
- // "00080020": {
- // "vr": "DT",
- // "Value": [ "20130409" ]
- // },
- // "00080030": {
- // "vr": "TM",
- // "Value": [ "131600.0000" ]
- // },
- // "00080050": {
- // "vr": "SH",
- // "Value": [ "11235813" ]
- // },
- // "00080056": {
- // "vr": "CS",
- // "Value": [ "ONLINE" ]
- // },
- // "00080061": {
- // "vr": "CS",
- // "Value": [
- // "CT",
- // "PET"
- // ]
- // },
- // "00080090": {
- // "vr": "PN",
- // "Value": [
- // {
- // "Alphabetic": "^Bob^^Dr."
- // }
- // ]
- // },
- // "00081190": {
- // "vr": "UR",
- // "Value": [ "http://wado.nema.org/studies/
- // 1.2.392.200036.9116.2.2.2.1762893313.1029997326.945873" ]
- // },
- // "00090010": {
- // "vr": "LO",
- // "Value": [ "Vendor A" ]
- // },
- // "00091002": {
- // "vr": "UN",
- // "InlineBinary": [ "z0x9c8v7" ]
- // },
- // "00100010": {
- // "vr": "PN",
- // "Value": [
- // {
- // "Alphabetic": "Wang^XiaoDong",
- // "Ideographic": "王^小東"
- // }
- // ]
- // },
- // "00100020": {
- // "vr": "LO",
- // "Value": [ "12345" ]
- // },
- // "00100021": {
- // "vr": "LO",
- // "Value": [ "Hospital A" ]
- // },
- // "00100030": {
- // "vr": "DT",
- // "Value": [ "19670701" ]
- // },
- // "00100040": {
- // "vr": "CS",
- // "Value": [ "M" ]
- // },
- // "00101002": {
- // "vr": "SQ",
- // "Value": [
- // {
- // "00100020": {
- // "vr": "LO",
- // "Value": [ "54321" ]
- // },
- // "00100021": {
- // "vr": "LO",
- // "Value": [ "Hospital B" ]
- // }
- // },
- // {
- // "00100020": {
- // "vr": "LO",
- // "Value": [ "24680" ]
- // },
- // "00100021": {
- // "vr": "LO",
- // "Value": [ "Hospital C" ]
- // }
- // }
- // ]
- // },
- // "0020000D": {
- // "vr": "UI",
- // "Value": [ "1.2.392.200036.9116.2.2.2.1762893313.1029997326.945873" ]
- // },
- // "00200010": {
- // "vr": "SH",
- // "Value": [ "11235813" ]
- // },
- // "00201206": {
- // "vr": "IS",
- // "Value": [ 4 ]
- // },
- // "00201208": {
- // "vr": "IS",
- // "Value": [ 942 ]
- // }
- // }
|