Skip to content

Commit 34a1c2f

Browse files
V1.0
2021年5月30日,于四川大学华西校区。
1 parent 785b12f commit 34a1c2f

File tree

15 files changed

+7472
-0
lines changed

15 files changed

+7472
-0
lines changed

Dicom Viewer/Dicom_Viewer.py

Lines changed: 4775 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
# -*- coding: utf-8 -*-
2+
'''pyrcc5 -o images.py images.qrc'''
3+
'''pyuic5 window.ui -o main_window.py -x'''
4+
import os
5+
import sys
6+
7+
import numpy as np
8+
from PyQt5.QtWidgets import QMainWindow, QFileDialog, QGraphicsPixmapItem, QGraphicsScene, QListWidgetItem, QApplication, QMessageBox
9+
from PyQt5.QtGui import QImage, QPixmap, QIcon
10+
from PyQt5.QtCore import Qt, QSize
11+
from PyQt5.uic import loadUi
12+
13+
from Read_dcm import Get_dcm_array
14+
from Threads import ThreadIconlist
15+
16+
class Mainwindow(QMainWindow):
17+
def __init__(self):
18+
super(Mainwindow, self).__init__()
19+
loadUi(r'./window.ui', self)
20+
self.ui_setup()
21+
self.state()
22+
23+
24+
def ui_setup(self):
25+
self.widgetsave.setHidden(True)
26+
self.verticalScrollBar.setHidden(True)
27+
self.widgetLoading.setHidden(True)
28+
29+
def state(self):
30+
self.WL = 30
31+
self.WW = 400
32+
self.HUscale()
33+
self.matrix = 512
34+
self.save_format = 'jpg'
35+
self.save_path = '.'
36+
37+
38+
def HUscale(self):
39+
self.CTmin = self.WL - self.WW//2 + 1024
40+
self.CTmax = self.WL + self.WW//2 + 1024
41+
if self.CTmin < 0:
42+
self.CTmin = 0
43+
if self.CTmax > 4095:
44+
self.CTmax = 4095
45+
46+
def IconlistThread(self):
47+
self.icon_WW = self.WW
48+
self.icon_CTmin = self.CTmin
49+
self.icon_CTmax = self.CTmax
50+
self.widgetLoading.setVisible(True)
51+
self.progressBarLoading.setMaximum(self.dcm_read.len)
52+
self.progressBarLoading.setValue(0)
53+
self.threadiconlist = ThreadIconlist(self)
54+
self.threadiconlist.loading_signal.connect(self.Loadingprogressbar)
55+
self.threadiconlist.start()
56+
57+
def Loadingprogressbar(self, idx):
58+
self.progressBarLoading.setValue(idx+1)
59+
60+
def dcminfo(self):
61+
infolines = self.dcm_read.ds.formatted_lines()
62+
info = next(infolines)
63+
while True:
64+
try:
65+
infoline = next(infolines)
66+
info = info + '\n' + infoline
67+
except StopIteration:
68+
break
69+
self.textBrowser.setText(info)
70+
71+
def iconlist(self, idx):
72+
img = self.dcm_read.getitem(idx)
73+
img = np.clip(img, self.icon_CTmin, self.icon_CTmax)
74+
img = img.astype(np.int16)
75+
img = ((img-self.icon_CTmin)/self.icon_WW)*255
76+
img = img.astype(np.int8)
77+
image = QImage(img,img.shape[1], img.shape[0],img.shape[1],
78+
QImage.Format_Grayscale8)
79+
80+
pix = QPixmap.fromImage(image)
81+
pix = pix.scaled(128,128, Qt.KeepAspectRatio, Qt.SmoothTransformation)
82+
83+
item_icon = QListWidgetItem()
84+
item_icon.setSizeHint(QSize(150, 150))
85+
item_icon.setIcon(QIcon(pix))
86+
item_icon.setText(str(idx+1))
87+
self.listWidget.addItem(item_icon)
88+
self.listWidget.update()
89+
90+
def itemclicked(self):
91+
item = self.listWidget.selectedItems()[0]
92+
idx = int(item.text())
93+
self.lcdNumber.display(idx)
94+
self.verticalScrollBar.setValue(idx)
95+
self.draw(idx)
96+
97+
def openfolder(self):
98+
self.directory = QFileDialog.getExistingDirectory(self,"Choose Folder",r"C:\Users\Administrator\Desktop\\")
99+
if os.path.exists(self.directory):
100+
self.dcm_read = Get_dcm_array(self.directory, openobj = 'folder')
101+
if self.dcm_read.len:
102+
try:
103+
self.enable('folder')
104+
self.draw(1)
105+
self.IconlistThread()
106+
except PermissionError:
107+
self.openfolder()
108+
109+
def openfile(self):
110+
self.file_path, self.file_type = QFileDialog.getOpenFileName(self,"Choose a Dicom file",
111+
r"C:\Users\Administrator\Desktop\\",
112+
"Dicom files(*.dcm);;All files(*.*)")
113+
if self.file_path and self.file_type == 'Dicom files(*.dcm)':
114+
self.dcm_read = Get_dcm_array(self.file_path, openobj = 'file')
115+
self.enable('file')
116+
self.draw(1)
117+
self.IconlistThread()
118+
119+
def set_WW(self, ww):
120+
self.WW = ww
121+
self.HUscale()
122+
self.draw(self.idx)
123+
124+
def set_WL(self, wl):
125+
self.WL = wl
126+
self.HUscale()
127+
self.draw(self.idx)
128+
129+
def set_Matrix(self, matrix):
130+
self.matrix = matrix
131+
self.draw(self.idx)
132+
133+
def draw(self, idx):
134+
self.idx = idx
135+
136+
img = self.dcm_read.getitem(idx-1)
137+
img = np.clip(img, self.CTmin, self.CTmax)
138+
img = img.astype(np.int16)
139+
img = ((img-self.CTmin)/self.WW)*255
140+
141+
img = img.astype(np.int8)
142+
143+
image = QImage(img,img.shape[1], img.shape[0],img.shape[1],
144+
QImage.Format_Grayscale8)
145+
pix = QPixmap.fromImage(image)
146+
pix = pix.scaled(self.matrix, self.matrix, Qt.KeepAspectRatio, Qt.SmoothTransformation)
147+
item = QGraphicsPixmapItem(pix) #创建像素图元
148+
scene = QGraphicsScene() #创建场景
149+
scene.addItem(item)
150+
self.graphicsView.setScene(scene)
151+
self.dcminfo()
152+
153+
def choose_format(self, idx):
154+
format_list = ['jpg', 'png', 'bmp']
155+
self.save_format = format_list[idx]
156+
157+
def selectsavepath(self):
158+
self.save_path = QFileDialog.getExistingDirectory(self,"Choose Save Path",r"C:\Users\Administrator\Desktop\\")
159+
self.lineEditSavepath.setText(self.save_path)
160+
161+
def set_savepath(self, path):
162+
if os.path.exists(path):
163+
self.save_path = path
164+
self.pushButtonsave.setEnabled(True)
165+
elif path == '':
166+
self.save_path = '.'
167+
self.pushButtonsave.setEnabled(True)
168+
else:
169+
self.pushButtonsave.setEnabled(False)
170+
171+
def save_image(self):
172+
img = self.dcm_read.getitem(self.idx-1)
173+
img = np.clip(img, self.CTmin, self.CTmax)
174+
img = img.astype(np.int16)
175+
img = ((img-self.CTmin)/self.WW)*255
176+
img = img.astype(np.int8)
177+
image = QImage(img,img.shape[1], img.shape[0],img.shape[1],
178+
QImage.Format_Grayscale8)
179+
image.save(r'{}\{}-WW_{}-WL_{}.{}'.format(self.save_path, self.idx, self.WW, self.WL, self.save_format))
180+
181+
def enable(self, openobj):
182+
self.WW = self.dcm_read.WW
183+
self.WL = self.dcm_read.WL
184+
self.HUscale()
185+
186+
self.graphicsView.setEnabled(True)
187+
188+
self.horizontalSliderMatrix.setEnabled(True)
189+
190+
self.tabWidget.setEnabled(True)
191+
self.listWidget.setEnabled(True)
192+
self.textBrowser.setEnabled(True)
193+
194+
self.horizontalSliderWL.setEnabled(True)
195+
self.horizontalSliderWW.setEnabled(True)
196+
self.horizontalSliderWW.blockSignals(True)
197+
self.horizontalSliderWL.blockSignals(True)
198+
self.horizontalSliderWW.setValue(self.WW)
199+
self.horizontalSliderWL.setValue(self.WL)
200+
self.horizontalSliderWW.blockSignals(False)
201+
self.horizontalSliderWL.blockSignals(False)
202+
203+
204+
self.labelmatrix.setEnabled(True)
205+
self.labelww.setEnabled(True)
206+
self.labelwl.setEnabled(True)
207+
self.spinBoxMatrix.setEnabled(True)
208+
self.spinBoxWW.setEnabled(True)
209+
self.spinBoxWL.setEnabled(True)
210+
self.spinBoxWW.setValue(self.WW)
211+
self.spinBoxWL.setValue(self.WL)
212+
213+
self.actionOpen_Dicom_Folder.setEnabled(False)
214+
self.actionOpen_Dicom_File.setEnabled(False)
215+
216+
self.widgetsave.setVisible(True)
217+
if openobj == 'folder':
218+
self.lcdNumber.setVisible(True)
219+
self.lcdNumber.display(1)
220+
self.verticalScrollBar.setVisible(True)
221+
self.verticalScrollBar.setEnabled(True)
222+
self.verticalScrollBar.setMaximum(self.dcm_read.len)
223+
self.verticalScrollBar.setValue(1)
224+
225+
if openobj == 'file':
226+
self.lcdNumber.setHidden(True)
227+
self.verticalScrollBar.setHidden(True)
228+
229+
def close_confirm(self):
230+
reply = QMessageBox.question(self, '退出', '确定退出吗?', QMessageBox.Yes | QMessageBox.Cancel, QMessageBox.Cancel)
231+
if reply == QMessageBox.Yes:
232+
self.close()
233+
234+
def about(self):
235+
QMessageBox.about(self, 'About', '''Dicom Viewer 1.0 --2021-5-30\n
236+
本软件仅适用于Dicom文件的浏览和格式转换。\n
237+
制作者:张金源(Benny)
238+
239+
地 点:四川大学华西校区男生院男一舍235
240+
All Rights Reserved.''')
241+
242+
if __name__ == "__main__":
243+
app = QApplication(sys.argv)
244+
MainWindow = Mainwindow()
245+
MainWindow.showMaximized()
246+
MainWindow.show()
247+
sys.exit(app.exec_())

Dicom Viewer/Editable/Read_dcm.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# -*- coding: utf-8 -*-
2+
import os
3+
4+
from pydicom.filereader import dcmread
5+
6+
class Get_dcm_array():
7+
''''''
8+
def __init__(self, root, openobj):
9+
''''''
10+
self.openobj = openobj
11+
self.root = root
12+
self.len = 1
13+
if openobj == 'folder':
14+
self.dcm_list = os.listdir(root)
15+
self.dcm_list = [dcm for dcm in self.dcm_list if dcm[-4:]=='.dcm']
16+
17+
self.len = len(self.dcm_list)
18+
self.dcm_list.sort()
19+
20+
elif openobj == 'file':
21+
pass
22+
if self.len != 0:
23+
self.get_info()
24+
25+
def getitem(self, index):
26+
'''根据索引获取image'''
27+
if self.openobj == 'folder':
28+
dcm_name = self.dcm_list[index]
29+
dcm_path = self.root + '\\' + dcm_name
30+
elif self.openobj == 'file':
31+
dcm_path = self.root
32+
return self.get_dcm_array(dcm_path)
33+
34+
def get_ds_and_array(self, index):
35+
'''根据索引获取image'''
36+
if self.openobj == 'folder':
37+
dcm_name = self.dcm_list[index]
38+
dcm_path = self.root + '\\' + dcm_name
39+
elif self.openobj == 'file':
40+
dcm_path = self.root
41+
ds = dcmread(dcm_path)
42+
return ds, ds.pixel_array
43+
44+
def get_dcm_array(self, path):
45+
'''读取dcm,并转换像素为CT值'''
46+
ds = dcmread(path)
47+
self.ds = ds
48+
return ds.pixel_array
49+
50+
def get_info(self):
51+
if self.openobj == 'folder':
52+
path = self.root + '\\' + self.dcm_list[0]
53+
elif self.openobj == 'file':
54+
path = self.root
55+
ds = dcmread(path)
56+
self.WL = 40
57+
self.WW = 400
58+
try:
59+
self.WL = int(ds.WindowCenter)
60+
self.WW = int(ds.WindowWidth)
61+
except ValueError:
62+
self.WL = 40
63+
self.WW = 400
64+
except TypeError:
65+
self.WL = int(ds.WindowCenter[0])
66+
a = ds.WindowCenter[0]
67+
self.WW = int(ds.WindowWidth[0])
68+
except:
69+
self.WL = 40
70+
self.WW = 400
71+
72+
if __name__ == '__main__':
73+
path = r'E:\NBIA\L004\LDCT-and-Projection-data\L004\08-21-2018-84608\1.000000-Low Dose Images'
74+
dcm_read = Get_dcm_array(path, openobj = 'folder')
75+

0 commit comments

Comments
 (0)