Инструменты пользователя

Инструменты сайта


converterdicom

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
converterdicom [2021/04/27 04:25]
sector
converterdicom [2023/01/29 05:35] (текущий)
sector
Строка 1: Строка 1:
-====== Меняем кодировку в DICOM и конвертируем кириллицу в латиницу. ======+====== Меняем кодировку в DICOM и конвертируем кириллицу в латиницу, пишем в базу и отправляем в ORTHANC. ======
 Есть у нас рентген аппарат у которого в xml файле написана кодировка ISO-8859-5, а русские символы в Windows-1251. Есть у нас рентген аппарат у которого в xml файле написана кодировка ISO-8859-5, а русские символы в Windows-1251.
-Изменим тег с кодировкой и конвертируем кириkлицу в латиницу с помощью python и отправим это все дело в ORTHANC. +Изменим тег с кодировкой и конвертируем кириллицу в латиницу с помощью python и отправим это все дело в ORTHANC. 
 + 
 +[[https://github.com/AndreyGutov/DicomConverter.git|Ссылка на gitHub]] 
    
 +=== Создадим базу данных: ===
  
-ОСТОРОЖНО ! ГОВНОКОД ! +<code | INI>
  
 +-- phpMyAdmin SQL Dump
 +-- version 5.0.4deb2
 +-- https://www.phpmyadmin.net/
 +--
 +-- Хост: localhost:3306
 +-- Время создания: Июн 16 2022 г., 10:49
 +-- Версия сервера: 10.5.15-MariaDB-0+deb11u1
 +-- Версия PHP: 7.4.28
 +
 +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
 +START TRANSACTION;
 +SET time_zone = "+00:00";
 +
 +
 +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
 +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
 +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
 +/*!40101 SET NAMES utf8mb4 */;
 +
 +--
 +-- База данных: `DicomConvert`
 +--
 +
 +-- --------------------------------------------------------
 +
 +--
 +-- Структура таблицы `DicomSend`
 +--
 +
 +CREATE TABLE `DicomSend` (
 +  `id` int(11) NOT NULL,
 +  `FileName` text NOT NULL,
 +  `SendDate` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
 +  `PatientName` text NOT NULL
 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
 +
 +--
 +-- Индексы сохранённых таблиц
 +--
 +
 +--
 +-- Индексы таблицы `DicomSend`
 +--
 +ALTER TABLE `DicomSend`
 +  ADD PRIMARY KEY (`id`);
 +
 +--
 +-- AUTO_INCREMENT для сохранённых таблиц
 +--
 +
 +--
 +-- AUTO_INCREMENT для таблицы `DicomSend`
 +--
 +ALTER TABLE `DicomSend`
 +  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
 +COMMIT;
 +
 +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
 +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
 +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
 +
 +</code>
 +
 +=== Подключимся к базе: ===
  
 <code | INI> <code | INI>
  
-# -*- codingutf-8 -*-+cat connector.py 
 + 
 +import mysql.connector 
 +cnx = mysql.connector.connect(user='DicomConvert', password='d85El4459kqOq2q0', 
 +                              host='127.0.0.1', 
 +                              database='DicomConvert', 
 +                              use_pure=False) 
 +</code> 
 + 
 +=== Сам скрипт конвертации и отправки=== 
 + 
 +<code | INI> 
 + 
 +cat dicomSend.py 
 import glob import glob
 import subprocess import subprocess
 import os import os
 import signal import signal
-import fileinput 
 import sys import sys
 import time import time
-import transliterate - https://gist.github.com/ledovsky/6398962 +import fileinput 
-reload(sys) +import connector 
-sys.setdefaultencoding('utf-8')+import transliterate
  
-path="/mnt/data/raid1/sendDCM/" 
  
-for filepath in glob.iglob(path+'*.[dD][cC][mM]'):+server = '192.168.1.43 4242# Сервер и порт куда будем посылать снимки 
 +fileList = open("/root/python/files_to_copy", "r"# файл со списком изображений(построчно), пример(/root/DCM/555_777.DCM) 
  
-    a=filepath +from datetime import datetime 
-    b=a.split('/')[5]+nowdatetime.now()
  
-    c=subprocess.Popen("dcm2xml +M +Wb " + filepath + " "+ path  + b + ".xml", shell=True+while True: 
-    c.communicate()+        lineFileList fileList.readline(
 +        if not lineFileList: 
 +                break 
 +        filePath=lineFileList.strip(
 +        fileName=filePath.split('/')[-1]
  
-    def replaceAll(file,searchExp,replaceExp): +        cursor = connector.cnx.cursor() 
-        for line in fileinput.input(file, inplace=1): +        select_query = (f"select * from DicomSend where FileName=%s"
-            if searchExp in line: +        cursor.execute(select_query,[fileName]
-                line = line.replace(searchExp,replaceExp+        row = cursor.fetchone()
-            sys.stdout.write(line)+
  
-    replaceAll(filepath + ".xml","ISO-8859-5","WINDOWS-1251")+        if row == None:
  
-    fullpathxml path +'.xml'+                dcmToXml=subprocess.Popen("dcm2xml ++Wb "+ filePath + " " + filePath + ".xml", shell=True) 
 +                dcmToXml.communicate() 
 +                fin = open(filePath + ".xml",encoding = "WINDOWS-1251"
 +                fout = open(filePath +".xml.mod", "wt"
 +                for line in fin: 
 +                        fout.write( line.replace('ISO-8859-5', 'UTF-8') ) 
 +                fin.close() 
 +                fout.close()
  
-    import xml.etree.ElementTree as ET +                fullpathxml = filePath +'.xml.mod'
-    tree = ET.parse(fullpathxml)+
  
-    PatientName=tree.findall('data-set/element[@name="PatientName"]')[0].text +                import xml.etree.ElementTree as ET 
-    BodyPE=tree.findall('data-set/element[@name="BodyPartExamined"]')[0].text +                tree ET.parse(fullpathxml)
-    if BodyPE: +
-        BodyPE=BodyPE +
-    else: +
-        BodyPE="Не заполнено"+
  
-    ViewPos=tree.findall('data-set/element[@name="ViewPosition"]')[0].text +                PatientName=tree.findall('data-set/element[@name="PatientName"]')[0].text 
-    if ViewPos+                if PatientName
-        ViewPos=ViewPos +                        PatientNameTrans=transliterate.transliterate(PatientName) 
-    else: +                else: 
-        ViewPos="Не заполнено"+                        PatientNameTrans="NameErr"
  
-    PatientNameTrans= transliterate.transliterate(PatientName) +                tree.findall('data-set/element[@name="PatientName"]')[0].text PatientNameTrans
-    BodyPETrans= transliterate.transliterate(BodyPE) +
-    ViewPosTranstransliterate.transliterate(ViewPos)+
  
-    PatientNameClean=tree.findall('data-set/element[@name="PatientName"]')[0].text = PatientNameTrans +                BodyPE=tree.findall('data-set/element[@name="BodyPartExamined"]')[0].text 
-    BodyPEClean=tree.findall('data-set/element[@name="BodyPartExamined"]')[0].text = BodyPETrans +                if BodyPE: 
-    ViewPosClean=tree.findall('data-set/element[@name="ViewPosition"]')[0].text = ViewPosTrans+                        BodyPETrans=transliterate.transliterate(BodyPE) 
 +                else: 
 +                        BodyPETrans="BodyErr" 
 + 
 +                tree.findall('data-set/element[@name="BodyPartExamined"]')[0].text = BodyPETrans 
 + 
 +                try: 
 +                        ViewPos=tree.findall('data-set/element[@name="ViewPosition"]')[0].text 
 +                        ViewPosTrans=transliterate.transliterate(ViewPos) 
 +                except: 
 +                        ViewPosTrans="ViewErr" 
 + 
 +                tree.findall('data-set/element[@name="ViewPosition"]')[0].text = ViewPosTrans 
 + 
 +                tree.write(fullpathxml) 
 + 
 +                xmlToDcm=subprocess.Popen("xml2dcm -f "+ fullpathxml + " "+ fullpathxml +".dcm", shell=True) 
 +                xmlToDcm.communicate() 
 + 
 +                dcmSend=subprocess.Popen("dcmsend -nuc +ma "+server+" "+fullpathxml+".dcm", shell=True, text=True, stderr=subprocess.PIPE) 
 +                data=dcmSend.communicate() 
 +                for line in data: 
 +                        if line: 
 +                                line = line.strip() 
 +                line=line.split(':')[0] 
 +                if line=='W': 
 +                        cursor = connector.cnx.cursor() 
 +                        insert_query=(f"INSERT INTO DicomSend (id, FileName, SendDate, PatientName) values(NULL, %s, NULL, %s)"
 +                        cursor.execute(insert_query,[fileName, PatientNameTrans]) 
 +                        connector.cnx.commit() 
 +                        fullpath='/'.join(fullpathxml.split('/')[:-1]) 
 +                        for xmlpath in glob.iglob(os.path.join(fullpath, '*.xml')): 
 +                                os.remove(xmlpath) 
 +                        for modpath in glob.iglob(os.path.join(fullpath, '*.mod')): 
 +                                os.remove(modpath) 
 +                        for moddcmpath in glob.iglob(os.path.join(fullpath, '*.mod.dcm')): 
 +                                os.remove(moddcmpath) 
 +                else: 
 +                        print('ERROR. ORTHANC NOT ANSWER = ',now) 
 +        else: 
 +                print('RECORD IS DUPLICATED = ', now) 
 + 
 +</code> 
 + 
 +=== Скрипт в крон для запуска конвертера: === 
 + 
 +  * Проверяем, работает ли конвертер в данные момент.  
 +  * синхронизируем хранилище сервера с рабочей станцией мед. оборудования (на рабочих станциях хранилища со снимками у меня расшарены, а на сервере примонтированы в каталог /mnt). 
 +  * создаем файл со списком изображений. 
 +  * пишем лог. 
 + 
 +<code | INI> 
 + 
 +#!/bin/bash 
 + 
 +#!/bin/sh 
 +if ps -ef | grep -v grep | grep dicomSend.py ; then 
 +        rsync -azvp --exclude 2020/ --exclude test.txt --exclude *.tgz /mnt/data/raid1/DicomShare/Roentgen /mnt/data/raid1/sendDCM/
 +        rsync -azvp --exclude 2020/ --exclude test.txt --exclude *.tgz /mnt/data/raid1/DicomShare/MRT /mnt/data/raid1/sendDCM/
 +        exit 0 
 +else 
 +        rsync -azvp --exclude 2020/ --exclude test.txt --exclude *.tgz /mnt/data/raid1/DicomShare/Roentgen /mnt/data/raid1/sendDCM/
 +        rsync -azvp --exclude 2020/ --exclude test.txt --exclude *.tgz /mnt/data/raid1/DicomShare/MRT /mnt/data/raid1/sendDCM/
 +        find /mnt/data/raid1/sendDCM/ -type f  -mmin -2880 -a -iname "*.dcm" > /root/python/files_to_copy ; 
 +        python /root/python/dicomSend.py >> /root/python/log/dicomConvert.log ; 
 +        exit 0 
 +fi 
 + 
 +</code> 
 + 
 +=== Транслитерация: === 
 + 
 +<code | INI> 
 +cat transliterate.py 
 + 
 +# -*- coding: utf-8 -*-
  
-    tree.write(fullpathxml)+def transliterate(name): 
 +   """ 
 +   Автор: LarsKort 
 +   Дата: 16/07/2011; 1:05 GMT-4; 
 +   Не претендую на "хорошесть" словарика. В моем случае и такой пойдет, 
 +   вы всегда сможете добавить свои символы и даже слова. Только 
 +   это нужно делать в обоих списках, иначе будет ошибка. 
 +   """ 
 +   # Слоаврь с заменами 
 +   slovar = {'а':'a','б':'b','в':'v','г':'g','д':'d','е':'e','ё':'yo', 
 +      'ж':'zh','з':'z','и':'i','й':'i','к':'k','л':'l','м':'m','н':'n', 
 +      'о':'o','п':'p','р':'r','с':'s','т':'t','у':'u','ф':'f','х':'h', 
 +      'ц':'c','ч':'ch','ш':'sh','щ':'sch','ъ':'','ы':'y','ь':'','э':'e', 
 +      'ю':'u','я':'ya', 'А':'A','Б':'B','В':'V','Г':'G','Д':'D','Е':'E','Ё':'YO', 
 +      'Ж':'ZH','З':'Z','И':'I','Й':'I','К':'K','Л':'L','М':'M','Н':'N', 
 +      'О':'O','П':'P','Р':'R','С':'S','Т':'T','У':'U','Ф':'F','Х':'H', 
 +      'Ц':'C','Ч':'CH','Ш':'SH','Щ':'SCH','Ъ':'','Ы':'y','Ь':'','Э':'E', 
 +      'Ю':'U','Я':'YA',',':'','?':'',' ':' ','~':'','!':'','@':'','#':'', 
 +      '$':'','%':'','^':' ','&':'','*':'','(':'',')':'','-':'','=':'','+':'', 
 +      ':':'',';':'','<':'','>':'','\'':'','"':'','\\':'','/':'','№':'', 
 +      '[':'',']':'','{':'','}':'','ґ':'','ї':'', 'є':'','Ґ':'g','Ї':'i', 
 +      'Є':'e', '—':''}
  
-    d=subprocess.Popen("xml2dcm -f "+path + b + ".xml "+ path + b +".mod", shell=True) +   # Циклически заменяем все буквы в строке 
-    time.sleep(5) +   for key in slovar
-    e=subprocess.Popen("dcmsend -nuc +ma orthanc.medcorp.local 4242 "+ path + b +".mod", shell=True) +      name = name.replace(key, slovar[key]
-    time.sleep(5) +   return name
-    e.communicate() +
-    os.remove(filepath) +
-    for xmlpath in glob.iglob(os.path.join(path, '*.xml'))+
-        os.remove(xmlpath+
-    for modpath in glob.iglob(os.path.join(path, '*.mod')):+
  
  
 </code> </code>
converterdicom.1619497515.txt.gz · Последнее изменение: 2021/04/27 04:25 — sector

Яндекс.Метрика