diff --git a/OrthancExplorer.js b/OrthancExplorer.js
index 456cd22..52cdd13 100644
--- a/OrthancExplorer.js
+++ b/OrthancExplorer.js
@@ -67,63 +67,4 @@ $('#instance').live('pageshow', function() {
}
}
});
-});
-
-
-$('#study').live('pagebeforecreate', function() {
- var b = $('')
- .attr('data-role', 'button')
- .attr('href', '#')
- .attr('data-icon', 'search')
- .attr('data-theme', 'e')
- .text('Stone Web Viewer (for mammography)');
-
- b.insertBefore($('#study-delete').parent().parent());
- b.click(function() {
- if ($.mobile.pageData) {
- $.ajax({
- url: '../studies/' + $.mobile.pageData.uuid,
- dataType: 'json',
- cache: false,
- success: function(study) {
- var studyInstanceUid = study.MainDicomTags.StudyInstanceUID;
- window.open('../mammography-viewer/index.html?study=' + studyInstanceUid);
- }
- });
- }
- });
-});
-
-
-$('#series').live('pagebeforecreate', function() {
- var b = $('')
- .attr('data-role', 'button')
- .attr('href', '#')
- .attr('data-icon', 'search')
- .attr('data-theme', 'e')
- .text('Stone Web Viewer (for mammography)');
-
- b.insertBefore($('#series-delete').parent().parent());
- b.click(function() {
- if ($.mobile.pageData) {
- $.ajax({
- url: '../series/' + $.mobile.pageData.uuid,
- dataType: 'json',
- cache: false,
- success: function(series) {
- $.ajax({
- url: '../studies/' + series.ParentStudy,
- dataType: 'json',
- cache: false,
- success: function(study) {
- var studyInstanceUid = study.MainDicomTags.StudyInstanceUID;
- var seriesInstanceUid = series.MainDicomTags.SeriesInstanceUID;
- window.open('../mammography-viewer/index.html?study=' + studyInstanceUid +
- '&series=' + seriesInstanceUid);
- }
- });
- }
- });
- }
- });
});
\ No newline at end of file
diff --git a/dicom_sr_to_pdf.py b/dicom_sr_to_pdf.py
index 47450cd..2540cf8 100644
--- a/dicom_sr_to_pdf.py
+++ b/dicom_sr_to_pdf.py
@@ -4,9 +4,10 @@ from pydicom.dataset import FileMetaDataset
from pydicom.uid import MediaStorageDirectoryStorage, EncapsulatedPDFStorage, generate_uid
import matplotlib
matplotlib.use("Agg") # Use non-GUI backend to avoid Tkinter issues
-import matplotlib.pyplot as plt # Now import pyplot
+import matplotlib.pyplot as plt
from reportlab.pdfgen import canvas
from datetime import datetime, date
+import os
def extract_measurements(sr):
@@ -28,10 +29,10 @@ def extract_measurements(sr):
return measurements, probabilities
-def overlay_measurements(image, measurements, probabilities):
+def overlay_measurements(dcm_image_pixels, measurements, probabilities, image_path):
"""Overlays extracted measurements onto the mammography image."""
fig, ax = plt.subplots()
- ax.imshow(image, cmap='gray')
+ ax.imshow(dcm_image_pixels, cmap='gray')
# Draw each polyline
for i in range(0, len(measurements), 1):
@@ -44,11 +45,11 @@ def overlay_measurements(image, measurements, probabilities):
ax.axis("off")
# Save the overlay as an image
- plt.savefig("temp.png", bbox_inches='tight', pad_inches=0)
+ plt.savefig(image_path, bbox_inches='tight', pad_inches=0)
plt.close(fig)
-def create_pdf(temp_image_path, measurements, sr, pdf_path):
+def create_pdf(image_path, measurements, sr, pdf_path):
"""Creates a PDF with the mammography image and extracted measurements."""
c = canvas.Canvas(pdf_path)
@@ -63,7 +64,7 @@ def create_pdf(temp_image_path, measurements, sr, pdf_path):
# Reset font for other text
c.setFont("Helvetica", 12)
- # Add patient info to the PDF
+ # Add patient and study info to the PDF
c.drawString(70, 800, f"Patient ID: {sr.PatientID}")
c.drawString(70, 785, f"Patient name: {sr.PatientName}")
c.drawString(70, 770, f"Patient birth date: {formateted_datetime(sr.PatientBirthDate)}")
@@ -73,13 +74,13 @@ def create_pdf(temp_image_path, measurements, sr, pdf_path):
c.drawString(70, 700, f"Referring physician: {sr.ReferringPhysicianName}")
# Add the image to the PDF
- c.drawImage(temp_image_path, 70, 300)
+ c.drawImage(image_path, 70, 300)
c.save()
-# Convert DICOM date
-def formateted_datetime(dicom_date, dicom_time = None):
+def formateted_datetime(dicom_date, dicom_time = None):
+ """Convert DICOM date and time format."""
if dicom_date is None or dicom_date == '':
return ''
@@ -98,7 +99,8 @@ def formateted_datetime(dicom_date, dicom_time = None):
# Combined datetime
return f"{formatted_date} {formatted_time}"
-def create_dcm_pdf(sr, pdf_path):
+
+def create_dcm_pdf(sr, pdf_path, instance_uid):
ds = Dataset()
# Add general DICOM metadata
@@ -123,7 +125,7 @@ def create_dcm_pdf(sr, pdf_path):
ds.Manufacturer = "MammographyAI"
ds.ConversionType = "DI"
- ds.SOPInstanceUID = generate_uid()
+ ds.SOPInstanceUID = instance_uid
ds.SOPClassUID = EncapsulatedPDFStorage
# Open the PDF file and read it as binary data
@@ -156,8 +158,23 @@ def create_dcm_pdf(sr, pdf_path):
return ds
-def create(image, sr):
+
+def create(dcm_image_pixels, sr):
+ instance_uid = generate_uid()
+ temp_image_path = f"{instance_uid}.png"
+ temp_pdf_path = f"{instance_uid}.pdf"
+
measurements, probabilities = extract_measurements(sr)
- overlay_measurements(image, measurements, probabilities)
- create_pdf("temp.png", measurements, sr, "temp.pdf")
- return create_dcm_pdf(sr, "temp.pdf",)
\ No newline at end of file
+ overlay_measurements(dcm_image_pixels, measurements, probabilities, temp_image_path)
+ create_pdf(temp_image_path, measurements, sr, temp_pdf_path)
+ dcm_pdf = create_dcm_pdf(sr, temp_pdf_path, instance_uid)
+
+ print("Current Working Directory:", os.getcwd())
+
+ if os.path.exists(temp_image_path):
+ os.remove(temp_image_path)
+
+ if os.path.exists(temp_pdf_path):
+ os.remove(temp_pdf_path)
+
+ return dcm_pdf
\ No newline at end of file
diff --git a/mammography.py b/mammography.py
index 9081bb7..67c692e 100644
--- a/mammography.py
+++ b/mammography.py
@@ -24,6 +24,7 @@
import sys
import json
import orthanc
+import os
config = json.loads(orthanc.GetConfiguration()).get('Mammography', {})
venv = config.get('VirtualEnv')
@@ -32,61 +33,7 @@ if venv != None:
# https://orthanc.uclouvain.be/book/plugins/python.html#working-with-virtual-environments
sys.path.insert(0, venv)
-
-##
-## Install the Stone Web viewer
-##
-
-STONE_VERSION = '2024-08-31-StoneWebViewer-DICOM-SR'
-VIEWER_PREFIX = '/mammography-viewer/'
-
-import os
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
-VIEWER_DIR = os.path.join(SCRIPT_DIR, 'viewer')
-
-sys.path.append(os.path.join(SCRIPT_DIR, '..'))
-import download
-
-os.makedirs(VIEWER_DIR, exist_ok = True)
-
-download.get(os.path.join(VIEWER_DIR, '%s.zip' % STONE_VERSION),
- 'https://github.com/jodogne/orthanc-mammography/raw/master/viewer/%s.zip' % STONE_VERSION,
- 4815178, '86b52a17f86e4769d12e9ae680c4a99f')
-
-import zipfile
-stone_assets = zipfile.ZipFile(os.path.join(VIEWER_DIR, '%s.zip' % STONE_VERSION))
-
-MIME_TYPES = {
- '.css' : 'text/css',
- '.gif' : 'image/gif',
- '.html' : 'text/html',
- '.jpeg' : 'image/jpeg',
- '.js' : 'text/javascript',
- '.png' : 'image/png',
-}
-
-def serve_stone_web_viewer(output, uri, **request):
- if not uri.startswith(VIEWER_PREFIX):
- output.SendHttpStatusCode(404)
- elif request['method'] != 'GET':
- output.SendMethodNotAllowed('GET')
- else:
- try:
- path = '%s/%s' % (STONE_VERSION, uri[len(VIEWER_PREFIX):])
- extension = os.path.splitext(path) [1]
- if not extension in MIME_TYPES:
- mime = 'application/octet-stream'
- else:
- mime = MIME_TYPES[extension]
-
- with stone_assets.open(path) as f:
- output.AnswerBuffer(f.read(), mime)
- except:
- output.SendHttpStatusCode(500)
-
-
-orthanc.RegisterRestCallback('%s(.*)' % VIEWER_PREFIX, serve_stone_web_viewer)
-
##
## Load the deep learning model
diff --git a/viewer/2024-03-09-FirstDicomSR.png b/viewer/2024-03-09-FirstDicomSR.png
deleted file mode 100644
index c6304a2..0000000
Binary files a/viewer/2024-03-09-FirstDicomSR.png and /dev/null differ
diff --git a/viewer/2024-03-15-StoneWebViewer-DICOM-SR.zip b/viewer/2024-03-15-StoneWebViewer-DICOM-SR.zip
deleted file mode 100644
index 932bb18..0000000
Binary files a/viewer/2024-03-15-StoneWebViewer-DICOM-SR.zip and /dev/null differ
diff --git a/viewer/2024-08-31-StoneWebViewer-DICOM-SR.zip b/viewer/2024-08-31-StoneWebViewer-DICOM-SR.zip
deleted file mode 100644
index 1f95c53..0000000
Binary files a/viewer/2024-08-31-StoneWebViewer-DICOM-SR.zip and /dev/null differ