如何用JavaScript结合Papaya通过多份DICOM文件生成表面文件?
Hey there! Let's figure out how to generate surface files from your DICOM images using JavaScript, replacing Mango Viewer.exe. Looking at your existing Papaya Viewer code, we can extend it with additional libraries to handle surface extraction—since Papaya is primarily a viewer, it doesn't have built-in surface generation tools out of the box.
Here's a step-by-step solution using ITK.js (a powerful JavaScript medical imaging library) alongside your Papaya setup:
First, let's update your HTML to include ITK.js, which will handle DICOM parsing, segmentation, and surface generation:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head> <link rel="stylesheet" type="text/css" href="papaya.css" /> <script type="text/javascript" src="papaya.js"></script> <!-- Add ITK.js for medical image processing --> <script src="https://cdn.jsdelivr.net/npm/itk@2.3.0/dist/umd/itk.js"></script> <title>Papaya Viewer</title> </head> <body> <div class="papaya" data-params="params"></div> <script type="text/javascript"> var finalImages = []; var images = window.opener.imageIds; for (var i = 0; i < images.length; i++) { if (images[i].substr(0, 8) == "dicomweb") { temp = images[i].substr(9, images[i].length); finalImages.push("http:" + temp); } } var params = []; params["images"] = [finalImages]; params["surfaces"] = []; // Initialize Papaya viewer first papaya.Container.init(); // Core function to generate surface from DICOM sequence async function generateDICOMSurface() { try { // 1. Fetch all DICOM files from your URLs const dicomBuffers = await Promise.all( finalImages.map(url => fetch(url).then(res => res.arrayBuffer())) ); const dicomArrays = dicomBuffers.map(buf => new Uint8Array(buf)); // 2. Read DICOM sequence into a 3D volume using ITK.js const { image, webWorker } = await itk.readDicomArrayBufferSeries(null, dicomArrays); webWorker.terminate(); // Clean up the worker // 3. Segment the volume (adjust thresholds based on your tissue type) // Example: Threshold for bone (HU values ~200 to 3000) const lowerThreshold = 200; const upperThreshold = 3000; const { binaryImage } = await itk.binaryThreshold( null, image, lowerThreshold, upperThreshold, 1, 0 ); // 4. Extract surface using Marching Cubes algorithm const { mesh } = await itk.marchingCubes(null, binaryImage, 0.5); // 5. Export as STL (common 3D surface format; supports OBJ/VTK too) const stlBuffer = await itk.writeMeshArrayBuffer(null, mesh, 'STL'); const stlBlob = new Blob([stlBuffer], { type: 'application/sla' }); // Trigger download of the surface file const downloadLink = document.createElement('a'); downloadLink.href = URL.createObjectURL(stlBlob); downloadLink.download = 'dicom-surface.stl'; document.body.appendChild(downloadLink); downloadLink.click(); document.body.removeChild(downloadLink); URL.revokeObjectURL(downloadLink.href); // Optional: Add the surface to Papaya viewer (requires format conversion) // Check Papaya docs for surface parameter formatting if you want to display it // params["surfaces"].push({ url: downloadLink.href, color: [1, 0, 0] }); // papaya.viewer.Viewer.getInstance().loadSurfaces(params["surfaces"]); } catch (error) { console.error('Error generating surface:', error); alert('Failed to generate surface. Check console for details.'); } } // Run surface generation once the page loads window.onload = generateDICOMSurface; </script> </body> </html>
Key Details to Note:
- ITK.js Functions: This library handles the heavy lifting: reading DICOM sequences, thresholding to isolate your target tissue, running the Marching Cubes algorithm to create a triangular mesh, and exporting the mesh to a surface file.
- Threshold Tuning: Adjust
lowerThresholdandupperThresholdbased on the tissue you want to extract. Use HU (Hounsfield Unit) values:- Bone: ~200 to 3000
- Soft tissue: ~-50 to 150
- Lung: ~-1000 to -500
- CORS Considerations: Ensure your DICOM server allows cross-origin requests (CORS), otherwise the
fetchcalls will fail. - Performance: Processing large DICOM sequences may take time—ITK.js uses Web Workers under the hood to avoid blocking the main thread.
内容的提问来源于stack exchange,提问作者Nikhil Ghuse
相关产品推荐
相关产品推荐

