add basic dicom diff support
This commit is contained in:
+2
-2
@@ -285,7 +285,7 @@ def series_split_by_tag(request, series_id: int, dicom_tag:str):
|
||||
print(image)
|
||||
ds = image.get_dicom_data()
|
||||
|
||||
print("2a", ds[dicom_tag])
|
||||
#print("2a", ds[dicom_tag])
|
||||
|
||||
if dicom_tag in ds:
|
||||
val = ds[dicom_tag].value
|
||||
@@ -295,7 +295,7 @@ def series_split_by_tag(request, series_id: int, dicom_tag:str):
|
||||
else:
|
||||
image_map[val].append(image)
|
||||
else:
|
||||
return [f"{dicom_tag} not found"]
|
||||
return [f"{dicom_tag} not found {image}"]
|
||||
|
||||
new_series = []
|
||||
case = series.case.all()
|
||||
|
||||
@@ -92,6 +92,9 @@
|
||||
<summary>
|
||||
Image details
|
||||
</summary>
|
||||
<form hx-post="{% url 'atlas:image_diff' %}"
|
||||
hx-target="#temp"
|
||||
>
|
||||
{% for image in series.get_images %}
|
||||
[{{ image.id }}] <a href='{% url "atlas:series_image_dicom" image.pk %}'>{{image.image.url}}</a>, pos: {{image.position}}, {{image.upload_filename}}
|
||||
|
||||
@@ -102,15 +105,34 @@
|
||||
|
||||
{{image.image_md5_hash}} ({{image.is_dicom}}) {{image.image_blake3_hash}}
|
||||
|
||||
<input type="checkbox" name="image-id" value="{{image.id}}">
|
||||
|
||||
<br />
|
||||
{% comment %} {{image.get_dicom_info|safe}}<br /> {% endcomment %}
|
||||
|
||||
{% endfor %}
|
||||
<button>Diff files</button>
|
||||
</form>
|
||||
<span id="temp"></span>
|
||||
</details>
|
||||
|
||||
<p>Total image size: {{series.get_total_image_size|filesizeformat}}</p>
|
||||
<p><a href="{% url 'atlas:series_download' pk=series.pk %}">Download images</a></p>
|
||||
</details>
|
||||
<span id="diff-controls">show <span id="diff-show-all" _="on click
|
||||
log '1'
|
||||
for row in .diff.rows
|
||||
show row
|
||||
end">all</span> <span id="diff-show-diff" _="
|
||||
on click
|
||||
log 'go'
|
||||
for row in <.diff tr/>
|
||||
log row.children[0].innerHTML
|
||||
if row.children[0].innerHTML is empty
|
||||
hide row
|
||||
end
|
||||
end
|
||||
">diff</span></span>
|
||||
|
||||
|
||||
<script>
|
||||
@@ -208,6 +230,14 @@
|
||||
|
||||
});
|
||||
|
||||
$("#diff-show-all").click(() => {
|
||||
console.log("Helol");
|
||||
})
|
||||
$("#diff-show-diff").click(() => {
|
||||
console.log("diff");
|
||||
})
|
||||
|
||||
|
||||
{% if editing_finding > 0 %}
|
||||
$("#hidden-form").show()
|
||||
setTimeout(function() {
|
||||
|
||||
@@ -214,6 +214,11 @@ urlpatterns = [
|
||||
views.series_order_dicom,
|
||||
name="series_order_dicom",
|
||||
),
|
||||
path(
|
||||
"images/<diff",
|
||||
views.image_diff,
|
||||
name="image_diff",
|
||||
),
|
||||
path(
|
||||
"series/<int:pk>/download",
|
||||
views.SeriesImagesZipView.as_view(),
|
||||
|
||||
+29
-1
@@ -17,6 +17,7 @@ from django.core.exceptions import (
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
||||
from django.views.generic import View
|
||||
from django.views.generic.detail import DetailView
|
||||
import pydicom
|
||||
from generic.mixins import SuperuserRequiredMixin
|
||||
|
||||
from django.views.generic.edit import CreateView, UpdateView, DeleteView, FormView
|
||||
@@ -116,7 +117,7 @@ import plotly.express as px
|
||||
from django.core.cache import cache
|
||||
from django.conf import settings
|
||||
|
||||
from helpers.images import image_as_base64
|
||||
from helpers.images import image_as_base64, print_dicom
|
||||
|
||||
import logging
|
||||
from copy import deepcopy
|
||||
@@ -130,6 +131,7 @@ import reversion
|
||||
from rest_framework import viewsets
|
||||
|
||||
import os
|
||||
import difflib
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -1039,6 +1041,32 @@ def series_order_dicom(request, pk):
|
||||
|
||||
return redirect("atlas:series_detail", pk=pk)
|
||||
|
||||
@login_required
|
||||
def image_diff(request):
|
||||
if request.htmx:
|
||||
|
||||
image_ids = request.POST.getlist("image-id")
|
||||
|
||||
first: SeriesImage = get_object_or_404(SeriesImage, pk=image_ids[0])
|
||||
second: SeriesImage = get_object_or_404(SeriesImage, pk=image_ids[1])
|
||||
|
||||
first_ds = pydicom.read_file(first.image.file)
|
||||
#del first_ds.PixelData
|
||||
#j1 = first_ds.to_json_dict()
|
||||
f = print_dicom(first_ds, join=False)
|
||||
|
||||
second_ds = pydicom.read_file(second.image.file)
|
||||
#del second_ds.PixelData
|
||||
#j2 = second_ds.to_json_dict()
|
||||
s = print_dicom(second_ds, join=False)
|
||||
|
||||
diff = difflib.HtmlDiff().make_table(f, s)
|
||||
|
||||
return HttpResponse(diff)
|
||||
|
||||
|
||||
return HttpResponse("Fail")
|
||||
|
||||
|
||||
@login_required
|
||||
def series_image_dicom(request, pk):
|
||||
|
||||
+11
-3
@@ -126,7 +126,7 @@ def pretty_print_dicom(dataset, indent=0):
|
||||
return "".join(l)
|
||||
|
||||
|
||||
def print_dicom(dataset, indent=0, include_tag_ids=True):
|
||||
def print_dicom(dataset, indent=0, include_tag_ids=True, join=True, join_text="\n<br/>"):
|
||||
"""Go through all items in the dataset and print them with custom format
|
||||
|
||||
Modelled after Dataset._pretty_str()
|
||||
@@ -142,7 +142,12 @@ def print_dicom(dataset, indent=0, include_tag_ids=True):
|
||||
if data_element.VR == "SQ": # a sequence
|
||||
l.append(f"{data_element.tag}: {indent_string}{data_element.name}")
|
||||
for sequence_item in data_element.value:
|
||||
l.append(print_dicom(sequence_item, indent + 1))
|
||||
l_ = print_dicom(sequence_item, indent + 1, join=join, join_text=join_text)
|
||||
if join:
|
||||
l.append(l_)
|
||||
else:
|
||||
l.extend(l_)
|
||||
|
||||
l.append(next_indent_string + "---------")
|
||||
else:
|
||||
if data_element.name in dont_print:
|
||||
@@ -152,7 +157,10 @@ def print_dicom(dataset, indent=0, include_tag_ids=True):
|
||||
if len(repr_value) > 50:
|
||||
repr_value = repr_value[:50] + "..."
|
||||
l.append(f"{data_element.tag}: {indent_string:s} {data_element.name:s} = {repr_value:s}")
|
||||
return "\n<br/>".join(l)
|
||||
if not join:
|
||||
return l
|
||||
|
||||
return join_text.join(l)
|
||||
|
||||
def get_image_dicom_hash(img, dataset=None, hash_type="md5", direct_pixel_data=True) -> (str, bool):
|
||||
if dataset is None:
|
||||
|
||||
@@ -1118,3 +1118,15 @@ table .peninsula-trainee::before {
|
||||
.show-on-hover:hover {
|
||||
opacity: 100%;
|
||||
}
|
||||
|
||||
.diff_add {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.diff_sub {
|
||||
color: red;
|
||||
}
|
||||
|
||||
tr:has(> td > a) {
|
||||
border: 1px blue solid
|
||||
}
|
||||
Reference in New Issue
Block a user