Guest User

Untitled

a guest
Jul 20th, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.20 KB | None | 0 0
  1. /**
  2. * Proof-of-concept script showing one whole slide image as an overlay on top
  3. * of another within QuPath.
  4. *
  5. * Note that this script simply overlays the *same* image that is currently open;
  6. * therefore it may not be immediately obvious that anything has happened.
  7. *
  8. * Uncomment the line
  9. * g2d.translate(1000, 1000)
  10. * if you want to convince yourself that something *has* actually happened,
  11. * and adjust the opacity slider as required.
  12. *
  13. * In practice, it will be more useful to overlay a *different* image...
  14. *
  15. * Note that you can also optionally bind the overlay display to the show/hide detections option.
  16. *
  17. * WARNING! This should work in QuPath v0.1.2, and possibly v0.1.3.
  18. * However, the API will definitely change in the future as overlays become
  19. * a more important part of the software... therefore be prepared to update any
  20. * code based on this.
  21. *
  22. * @author Pete Bankhead
  23. */
  24.  
  25. import javafx.application.Platform
  26. import qupath.lib.awt.common.AwtTools
  27. import qupath.lib.gui.viewer.QuPathViewer
  28. import qupath.lib.gui.viewer.overlays.AbstractImageDataOverlay
  29. import qupath.lib.images.ImageData
  30. import qupath.lib.images.servers.ImageServer
  31. import qupath.lib.images.servers.ImageServerProvider
  32. import qupath.lib.regions.ImageRegion
  33. import qupath.lib.scripting.QPEx
  34.  
  35. import java.awt.Graphics2D
  36. import java.awt.Shape
  37. import java.awt.geom.AffineTransform
  38. import java.awt.image.BufferedImage
  39. import java.awt.image.ImageObserver
  40.  
  41.  
  42. // Replace overlay in the Application thread
  43. Platform.runLater {
  44.  
  45. def viewer = QPEx.getCurrentViewer()
  46. def path = viewer.getServerPath()
  47.  
  48. def overlay = new WholeSlideImageOverlay(viewer, path, false)
  49.  
  50. // Remove any existing overlays of this kind (helpful during debugging...)
  51. viewer.getOverlayLayers().findAll({it.getClass().getName().contains('WholeSlideImageOverlay')}).each {
  52. viewer.removeOverlay(it)
  53. }
  54.  
  55. // Add the new overlay
  56. viewer.addOverlay(overlay)
  57. print 'Done!'
  58. }
  59.  
  60. /**
  61. * Create an overlay to display one whole slide image on top of another.
  62. */
  63. class WholeSlideImageOverlay extends AbstractImageDataOverlay {
  64.  
  65. private boolean initialized = false
  66. private QuPathViewer viewer
  67. private ImageServer<BufferedImage> server
  68. private AffineTransform transform
  69. private boolean bindToObjectDisplay
  70.  
  71. public WholeSlideImageOverlay(final QuPathViewer viewer, final String path, boolean bindToObjectDisplay) {
  72. super(viewer.getOverlayOptions(), viewer.getImageData())
  73. this.viewer = viewer
  74. this.server = ImageServerProvider.buildServer(path, BufferedImage.class)
  75. this.initialized = true
  76. this.bindToObjectDisplay = bindToObjectDisplay
  77. }
  78.  
  79. @Override
  80. boolean supportsImageDataChange() {
  81. return true
  82. }
  83.  
  84. /**
  85. * If the ImageData for the viewer is changed, remove the overlay.
  86. *
  87. * @param imageData
  88. */
  89. @Override
  90. public void setImageData(final ImageData<BufferedImage> imageData) {
  91. if (this.imageData == imageData || !initialized)
  92. return
  93. viewer.removeOverlay(this)
  94. this.server.close()
  95. }
  96.  
  97. @Override
  98. void paintOverlay(Graphics2D g2d, ImageRegion imageRegion, double downsampleFactor, ImageObserver observer, boolean paintCompletely) {
  99. // Don't do anything if opacity is zero
  100. if (getOpacity() == 0)
  101. return
  102.  
  103. // If we're binding this to the display of objects, don't paint if detections aren't visible
  104. // (this lets us toggle the overlay on & off with the 'h' shortcut)
  105. if (bindToObjectDisplay && !viewer.getOverlayOptions().showObjects)
  106. return
  107.  
  108. // Create a rectangle for the region
  109. Shape shape = AwtTools.getBounds(imageRegion)
  110.  
  111. // Apply transform... handy if using the same image, just to check *something* happens
  112. // g2d.translate(1000, 1000)
  113.  
  114. // Paint region with the help of the image region store (used for caching & painting)
  115. int z = viewer.getZPosition()
  116. int t = viewer.getTPosition()
  117. viewer.getImageRegionStore().paintRegion(
  118. server, g2d, g2d.getClip(), z, t, downsampleFactor,
  119. viewer.getImageRegionStore().getThumbnail(server, z, t, true),
  120. null, null)
  121.  
  122. }
  123.  
  124. }
Add Comment
Please, Sign In to add comment