Last active
September 7, 2021 18:12
-
-
Save oeway/e5c980fbf6582f25fde795262a7e33ec to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<config lang="json"> | |
{ | |
"name": "ITK-VTK-Viewer", | |
"type": "web-worker", | |
"tags": [], | |
"ui": "", | |
"version": "0.1.2", | |
"cover": "", | |
"description": "This Plugin uses itk-vtk-viewer to visualize images in ImageJ.JS", | |
"icon": "extension", | |
"inputs": null, | |
"outputs": null, | |
"api_version": "0.1.8", | |
"env": "", | |
"permissions": [], | |
"requirements": [], | |
"dependencies": [] | |
} | |
</config> | |
<script lang="javascript"> | |
const PixelTypes = { | |
Unknown: 0, | |
Scalar: 1, | |
RGB: 2, | |
RGBA: 3, | |
Offset: 4, | |
Vector: 5, | |
Point: 6, | |
CovariantVector: 7, | |
SymmetricSecondRankTensor: 8, | |
DiffusionTensor3D: 9, | |
Complex: 10, | |
FixedArray: 11, | |
Array: 12, | |
Matrix: 13, | |
VariableLengthVector: 14, | |
VariableSizeMatrix: 15, | |
} | |
const numpy2itkType = { | |
int8: { | |
componentType: 'int8_t', | |
arrayType: Int8Array, | |
}, | |
uint8: { | |
componentType: 'uint8_t', | |
arrayType: Uint8Array, | |
}, | |
int16: { | |
componentType: 'int16_t', | |
arrayType: Int16Array, | |
}, | |
uint16: { | |
componentType: 'uint16_t', | |
arrayType: Uint16Array, | |
}, | |
int32: { | |
componentType: 'int32_t', | |
arrayType: Int32Array, | |
}, | |
uint32: { | |
componentType: 'uint32_t', | |
arrayType: Uint32Array, | |
}, | |
float32: { | |
componentType: 'float', | |
arrayType: Float32Array, | |
}, | |
float64: { | |
componentType: 'double', | |
arrayType: Float64Array, | |
}, | |
} | |
function ndarrayToItkImage(array) { | |
if (array._rtype !== 'ndarray') { | |
throw new Error('Invalid ndarray type: ' + array._rtype) | |
} | |
const { componentType, arrayType } = numpy2itkType[array._rdtype] | |
if ( | |
array._rshape.length === 2 || | |
(array._rshape.length == 3 && array._rshape[2] <= 4) | |
) { | |
const channels = array._rshape.length === 3 ? array._rshape[2] : 1 | |
let pixelType | |
if(channels === 1) | |
pixelType = PixelTypes.Scalar | |
else if(channels === 3) | |
pixelType = PixelTypes.RGB | |
else if(channels === 4) | |
pixelType = PixelTypes.RGBA | |
else | |
pixelType = PixelTypes.VariableLengthVector | |
return { | |
imageType: { | |
dimension: 2, | |
pixelType, | |
componentType, | |
components: channels, | |
}, | |
name: 'Image', | |
origin: [0.0, 0.0], | |
spacing: [1.0, 1.0], | |
direction: { | |
data: [1.0, 0.0, 0.0, 1.0], | |
}, | |
size: [array._rshape[1], array._rshape[0]], | |
data: new arrayType(array._rvalue), | |
} | |
} else if (array._rshape.length === 3) { | |
return { | |
imageType: { | |
dimension: 3, | |
pixelType: PixelTypes.Scalar, | |
componentType, | |
components: 1, | |
}, | |
name: 'Image', | |
origin: [0.0, 0.0, 0.0], | |
spacing: [1.0, 1.0, 1.0], | |
direction: { | |
data: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0], | |
}, | |
size: [array._rshape[2], array._rshape[1], array._rshape[0]], | |
data: new arrayType(array._rvalue), | |
} | |
} else if (array._rshape.length === 4) { | |
const channels = array._rshape[3] | |
let pixelType | |
if(channels === 1) | |
pixelType = PixelTypes.Scalar | |
else if(channels === 3) | |
pixelType = PixelTypes.RGB | |
else if(channels === 4) | |
pixelType = PixelTypes.RGBA | |
else | |
pixelType = PixelTypes.VariableLengthVector | |
return { | |
imageType: { | |
dimension: 3, | |
pixelType, | |
componentType, | |
components: array._rshape[3], | |
}, | |
name: 'Image', | |
origin: [0.0, 0.0, 0.0], | |
spacing: [1.0, 1.0, 1.0], | |
direction: { | |
data: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0], | |
}, | |
size: [array._rshape[2], array._rshape[1], array._rshape[0]], | |
data: new arrayType(array._rvalue), | |
} | |
} else { | |
throw new Error(`Unsupported shape: ${array._rshape}`) | |
} | |
} | |
class ImJoyPlugin { | |
async setup() { | |
const ij = await api.getWindow('ImageJ.JS') | |
await ij.addMenuItem({"label": "ITK/VTK Viewer (3D)", "callback": this.showInViewer}) | |
} | |
async showInViewer(img){ | |
if(!img){ | |
const ij = await api.getWindow('ImageJ.JS') | |
img = await ij.getImage({format: 'ndarray', all: true}) | |
} | |
img = ndarrayToItkImage(img) | |
const viewer = await api.createWindow({src: "https://unpkg.com/[email protected]/dist/index.html", name: "ITK/VTK Viewer", h: 15}) | |
await viewer.setImage(img) | |
await viewer.setUICollapsed(true) | |
} | |
async run(ctx) { | |
const img = ctx && ctx.data && ctx.data.image; | |
if(img) | |
await this.showInViewer(img); | |
else | |
await api.createWindow({src: "https://unpkg.com/[email protected]/dist/index.html", name: "ITK/VTK Viewer", h: 15}) | |
} | |
} | |
api.export(new ImJoyPlugin()) | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment