Skip to content

Commit e88d720

Browse files
committed
Hollow meshes only for faster mode
1 parent 639e2e6 commit e88d720

File tree

3 files changed

+33
-21
lines changed

3 files changed

+33
-21
lines changed

brainchop-webworker.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,11 @@ async function inferenceFullVolumePhase2(
624624
const argMaxTime = performance.now()
625625
console.log(' Try tf.argMax for fullVolume ..')
626626
if (isScalar) {
627-
const input = tf.softmax(curTensor[i], -1) // shape: [..., C], with C >= 2
627+
// const input = tf.softmax(curTensor[i], -1) // shape: [..., C], with C >= 2
628+
629+
const temperature = 1.2 // >1 softens, <1 sharpens
630+
const input = tf.softmax(curTensor[i].div(temperature), -1)
631+
628632
const shape = input.shape
629633
const lastDim = shape.length - 1
630634
// Slice the last dimension to keep only channels 1 and onward (ignore channel 0)
@@ -743,7 +747,7 @@ async function inferenceFullVolumePhase2(
743747
console.log(' outLabelVolume final shape after resizing : ', outLabelVolume.shape)
744748

745749
if (isScalar) {
746-
const thresh = tf.scalar(0.04); // threshold
750+
const thresh = tf.scalar(0.10); // threshold
747751
const scale255 = tf.scalar(255.0); // if you still need the scaling step
748752
const mask = outLabelVolume.greaterEqual(thresh).toFloat();
749753
outLabelVolume = outLabelVolume.mul(mask);

index.html

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,6 @@
6565
</footer>
6666
<dialog id="remeshDialog">
6767
<form method="dialog">
68-
<p>
69-
<label>
70-
Hollow:
71-
<select id="hollowSelect" title="hollow meshes require less material but may be fragile">
72-
<option value="0" selected>False: solid</option>
73-
<option value="-2">2mm</option>
74-
<option value="-3">3mm</option>
75-
<option value="-4">4mm</option>
76-
<option value="-8">8mm</option>
77-
<option value="-16">16mm</option>
78-
</select>
79-
</label>
80-
</p>
8168
<p>
8269
<label>
8370
Quality:
@@ -90,6 +77,19 @@
9077
<p id="largestClusterGroup">
9178
<label>&nbsp;Largest cluster only</label><input type="checkbox" id="largestCheck" unchecked/>
9279
</p>
80+
<p id="hollowGroup">
81+
<label>
82+
&nbsp;Hollow:
83+
<select id="hollowSelect" title="hollow meshes require less material but may be fragile">
84+
<option value="0" selected>False: solid</option>
85+
<option value="-2">2mm</option>
86+
<option value="-3">3mm</option>
87+
<option value="-4">4mm</option>
88+
<option value="-8">8mm</option>
89+
<option value="-16">16mm</option>
90+
</select>
91+
</label>
92+
</p>
9393
<p id="bubbleGroup">
9494
<label>&nbsp;Fill bubbles</label><input type="checkbox" id="bubbleCheck" unchecked/>
9595
</p>

main.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { isChrome, localSystemDetails } from "./brainchop-telemetry.js"
44
import MyWorker from "./brainchop-webworker.js?worker"
55
import { Niimath } from "@niivue/niimath"
66
import {
7-
antiAliasCuberille,
7+
antiAliasCuberille, cuberille,
88
setPipelinesBaseUrl as setCuberillePipelinesUrl
99
} from "@itk-wasm/cuberille"
1010
import {
@@ -240,6 +240,8 @@ async function main() {
240240
const opacity = 1.0 - (0.5 * Number(isBetterQuality))
241241
largestCheck.disabled = isBetterQuality
242242
largestClusterGroup.style.opacity = opacity
243+
hollowGroup.style.opacity = opacity
244+
hollowSelect.disabled = isBetterQuality
243245
bubbleCheck.disabled = isBetterQuality
244246
bubbleGroup.style.opacity = opacity
245247
closeMM.disabled = isBetterQuality
@@ -262,7 +264,7 @@ async function main() {
262264
//mesh with specified isosurface
263265
let isoValue = 0.5
264266
if (nv1.volumes[nv1.volumes.length - 1].hdr.intent_code === 0) {
265-
isoValue = 222 //isScalar
267+
isoValue = 240 //isScalar
266268
}
267269
//const largestCheckValue = largestCheck.checked
268270
let reduce = Math.min(Math.max(Number(shrinkPct.value) / 100, 0.01), 1)
@@ -299,10 +301,10 @@ async function main() {
299301
const volIdx = nv1.volumes.length - 1
300302
let hdr = nv1.volumes[volIdx].hdr
301303
let img = nv1.volumes[volIdx].img
302-
let hollowInt = Number(hollowSelect.value )
304+
/*let hollowInt = Number(hollowSelect.value )
303305
if (hollowInt < 0){
304306
const vol = nv1.volumes[volIdx]
305-
const niiBuffer = await nv1.saveImage({volumeByIndex: nv1.volumes.length - 1}).buffer
307+
const niiBuffer = await nv1.saveImage({volumeByIndex: nv1.volumes.length - 1})
306308
const niiBlob = new Blob([niiBuffer], { type: 'application/octet-stream' })
307309
const niiFile = new File([niiBlob], 'input.nii')
308310
niimath.setOutputDataType('input') // call before setting image since this is passed to the image constructor
@@ -318,13 +320,19 @@ async function main() {
318320
})
319321
hdr = outVol.hdr
320322
img = outVol.img
321-
}
323+
}*/
322324
loadingCircle.classList.remove("hidden")
323325
meshProcessingMsg.classList.remove("hidden")
324326
meshProcessingMsg.textContent = "Generating mesh from segmentation"
325327
const itkImage = nii2iwi(hdr, img, false)
326328
itkImage.size = itkImage.size.map(Number)
327-
const { mesh } = await antiAliasCuberille(itkImage, { noClosing: true })
329+
let mesh
330+
if (nv1.volumes[nv1.volumes.length - 1].hdr.intent_code === 0) {
331+
({ mesh } = await cuberille(itkImage, { isoSurfaceValue: 240 }))
332+
} else {
333+
({ mesh } = await antiAliasCuberille(itkImage, { noClosing: true }))
334+
}
335+
328336
meshProcessingMsg.textContent = "Generating manifold"
329337
const { outputMesh: repairedMesh } = await repair(mesh, { maximumHoleArea: 50.0 })
330338
meshProcessingMsg.textContent = "Keep largest mesh component"

0 commit comments

Comments
 (0)