Skip to content

Commit c0e4f76

Browse files
authored
feat: add filters examples (#496)
* feat: add filters examples * feat: add example description * format
1 parent 86ac244 commit c0e4f76

2 files changed

Lines changed: 260 additions & 0 deletions

File tree

docs/examples/filters.html

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
<!doctype html>
2+
<html class="h-100 overflow-hidden">
3+
<head>
4+
<meta charset="UTF-8" />
5+
6+
<!-- Include the Larvitar script -->
7+
<script>
8+
// Check the host and set the script source dynamically
9+
const script = document.createElement("script");
10+
if (window.location.host === "larvitar.dvisionlab.com") {
11+
document.write(
12+
'<script src="https://larvitar.dvisionlab.com/assets/larvitar.js"><\/script>'
13+
);
14+
} else {
15+
document.write('<script src="../../dist/larvitar.js"><\/script>');
16+
}
17+
// Append the script to the document
18+
document.head.appendChild(script);
19+
</script>
20+
21+
<!-- Add the Bootstrap CSS and Prism CSS for code modal -->
22+
<link
23+
rel="stylesheet"
24+
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css"
25+
/>
26+
<link
27+
rel="stylesheet"
28+
href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css"
29+
/>
30+
31+
<!-- Include the CSS file -->
32+
<link rel="stylesheet" href="resources/styles.css" />
33+
34+
<!-- custom styles for the example -->
35+
<style></style>
36+
37+
<!-- Add the Bootstrap JS and Prism JS for code modal -->
38+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
39+
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
40+
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-javascript.min.js"></script>
41+
42+
<!-- Code to be displayed as source example code -->
43+
<!-- <script>
44+
document.addEventListener("DOMContentLoaded", () => {
45+
const showCodeBtn = document.getElementById("showCodeBtn");
46+
const codeSnippet = document.getElementById("codeSnippet");
47+
const copyCodeBtn = document.getElementById("copyCodeBtn");
48+
49+
// TODO Code snippet to be displayed and updated for the example
50+
const code = ``;
51+
52+
// Show the modal and populate code snippet
53+
showCodeBtn.addEventListener("click", () => {
54+
codeSnippet.textContent = code;
55+
Prism.highlightElement(codeSnippet); // Highlight the code
56+
const codeModal = new bootstrap.Modal(
57+
document.getElementById("codeModal")
58+
);
59+
codeModal.show();
60+
});
61+
62+
// Copy the code to clipboard
63+
copyCodeBtn.addEventListener("click", () => {
64+
navigator.clipboard.writeText(code);
65+
});
66+
});
67+
</script> -->
68+
69+
<title>Larvitar - Filters</title>
70+
</head>
71+
72+
<body class="h-100" style="background-color: #000000">
73+
<div class="row h-100">
74+
<div
75+
id="viewer"
76+
class="col-12 h-100"
77+
style="background-color: black"
78+
></div>
79+
<p style="position: absolute; top: 0px; color: white">
80+
Press "1" to remove filter
81+
</p>
82+
<p style="position: absolute; top: 20px; color: white">
83+
Press "2" to apply filter
84+
</p>
85+
<!-- <button id="showCodeBtn" class="open-button" style="position: absolute; top: 165px">
86+
Show Code
87+
</button> -->
88+
89+
<!-- Modal -->
90+
<div
91+
class="modal fade"
92+
id="codeModal"
93+
tabindex="-1"
94+
aria-labelledby="codeModalLabel"
95+
aria-hidden="true"
96+
>
97+
<div class="modal-dialog modal-lg modal-dialog-centered">
98+
<div class="modal-content">
99+
<div class="modal-header">
100+
<h5 class="modal-title" id="codeModalLabel">JavaScript Code</h5>
101+
<button
102+
type="button"
103+
class="btn-close"
104+
data-bs-dismiss="modal"
105+
aria-label="Close"
106+
></button>
107+
</div>
108+
<div class="modal-body" style="max-height: 70vh; overflow-y: auto">
109+
<pre><code id="codeSnippet" class="language-javascript"></code></pre>
110+
</div>
111+
<div class="modal-footer">
112+
<button id="copyCodeBtn" class="btn btn-success">
113+
Copy Code
114+
</button>
115+
<button
116+
type="button"
117+
class="btn btn-secondary"
118+
data-bs-dismiss="modal"
119+
>
120+
Close
121+
</button>
122+
</div>
123+
</div>
124+
</div>
125+
</div>
126+
127+
<!-- Spinner icon -->
128+
<div id="spinner"></div>
129+
</div>
130+
131+
<script>
132+
const spinner = document.getElementById("spinner");
133+
134+
// Show spinner
135+
function showSpinner() {
136+
spinner.style.display = "block";
137+
}
138+
139+
// Hide spinner
140+
function hideSpinner() {
141+
spinner.style.display = "none";
142+
}
143+
144+
// init all
145+
larvitar.initializeImageLoader();
146+
larvitar.registerMultiFrameImageLoader();
147+
larvitar.initializeCSTools();
148+
larvitar.store.initialize();
149+
larvitar.store.addViewport("viewer");
150+
151+
larvitar.addCustomKernel("sharpening.low.3", {
152+
Label: "Low",
153+
Size: 3,
154+
Kernel: [
155+
[-1, -1, -1],
156+
[-1, 8, -1],
157+
[-1, -1, -1]
158+
],
159+
modalities: ["CT", "MR"],
160+
type: "sharpening"
161+
});
162+
163+
// set log level to debug
164+
larvitar.setLogLevel("debug");
165+
166+
let demoFiles = [];
167+
168+
showSpinner();
169+
170+
async function resetFilter(multiFrameSerie, frameId) {
171+
larvitar.store.setImageFilter("viewer", "");
172+
const imageIds = Object.keys(multiFrameSerie.instances);
173+
const imageIdAtSlice = imageIds[frameId];
174+
const imageInstance = multiFrameSerie.instances[imageIdAtSlice];
175+
await larvitar.renderImage(multiFrameSerie, "viewer", {
176+
imageIndex: frameId,
177+
voi: {
178+
windowWidth: imageInstance.metadata.windowWidth,
179+
windowCenter: imageInstance.metadata.windowCenter
180+
}
181+
});
182+
}
183+
184+
async function applyFilter(multiFrameSerie, frameId) {
185+
await resetFilter(multiFrameSerie, frameId);
186+
187+
const element = document.getElementById("viewer");
188+
const image = larvitar.cornerstone.getEnabledElement(element)?.image;
189+
const filteredImage = larvitar.applyConvolutionFilter(
190+
image,
191+
"sharpening.low.3",
192+
true
193+
);
194+
larvitar.store.setImageFilter(element.id, "sharpening.low.3");
195+
larvitar.cornerstone.displayImage(element, filteredImage);
196+
larvitar.setImageCustomPreset(["viewer"], {
197+
ww: filteredImage.windowWidth,
198+
wl: filteredImage.windowCenter
199+
});
200+
}
201+
202+
async function renderSerie() {
203+
const seriesStack = await larvitar.readFiles(demoFiles);
204+
// render the first series of the study
205+
let seriesId = Object.keys(seriesStack)[0];
206+
let serie = seriesStack[seriesId];
207+
larvitar.populateImageManager(seriesId, serie);
208+
let manager = larvitar.getImageManager();
209+
let multiFrameSerie = manager[seriesId];
210+
211+
let frameId = 0;
212+
await larvitar.renderImage(multiFrameSerie, "viewer", {
213+
imageIndex: frameId
214+
});
215+
hideSpinner();
216+
larvitar.logger.debug("Image has been rendered");
217+
218+
larvitar.addDefaultTools("viewer");
219+
larvitar.setToolActive("Wwwc");
220+
221+
await larvitar.loadAndCacheImageStack(multiFrameSerie);
222+
223+
document.onkeypress = function (e) {
224+
e = e || window.event;
225+
switch (e.keyCode) {
226+
case 49: // 1
227+
resetFilter(multiFrameSerie, frameId);
228+
break;
229+
case 50: // 2
230+
applyFilter(multiFrameSerie, frameId);
231+
break;
232+
}
233+
};
234+
}
235+
236+
async function createFile(fileName, cb) {
237+
let response = await fetch("./demo/DSA/" + fileName);
238+
let data = await response.blob();
239+
let file = new File([data], fileName);
240+
demoFiles.push(file);
241+
cb();
242+
}
243+
244+
createFile("XA-DSA-Shutter.dcm", renderSerie);
245+
</script>
246+
</body>
247+
</html>

docs/guide/examples.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,19 @@ Key features covered in this example include:
249249

250250
[View Example ➔](https://larvitar.dvisionlab.com/examples/nrrd.html)
251251

252+
---
253+
254+
### 17. Applying Kernel Filters
255+
256+
This example demonstrates how to use kernel filters in Larvitar to enhance the visualization of medical images. Kernel filteres are applied to improve image quality or highlight specific features. Different kernels can be chosen to emphasize different image features, like edges or soft tissues.
257+
258+
Key features covered in this example include:
259+
260+
- Setting up a custom kernel with Larvitar
261+
- Applying an resetting filter to the rendered image
262+
263+
[View Example ➔](https://larvitar.dvisionlab.com/examples/filters.html)
264+
252265
<br></br>
253266

254267
<div style="text-align: center;">

0 commit comments

Comments
 (0)