|
12 | 12 | }, |
13 | 13 | { |
14 | 14 | "cell_type": "code", |
15 | | - "execution_count": 1, |
| 15 | + "execution_count": null, |
16 | 16 | "id": "59e8a2c3", |
17 | 17 | "metadata": { |
18 | 18 | "execution": { |
|
27 | 27 | }, |
28 | 28 | "outputs": [], |
29 | 29 | "source": [ |
30 | | - "import libcarna" |
| 30 | + "import libcarna\n", |
| 31 | + "import numpy as np\n", |
| 32 | + "import scipy.ndimage as ndi" |
31 | 33 | ] |
32 | 34 | }, |
33 | 35 | { |
|
85 | 87 | }, |
86 | 88 | { |
87 | 89 | "cell_type": "code", |
88 | | - "execution_count": 3, |
| 90 | + "execution_count": null, |
89 | 91 | "id": "ed16156a", |
90 | 92 | "metadata": { |
91 | 93 | "execution": { |
|
166 | 168 | } |
167 | 169 | ], |
168 | 170 | "source": [ |
169 | | - "GEOMETRY_TYPE_VOLUME = 2\n", |
| 171 | + "GEOMETRY_TYPE_VOLUME = 1\n", |
170 | 172 | "\n", |
171 | 173 | "# Create and configure frame renderer\n", |
172 | 174 | "mip = libcarna.mip(GEOMETRY_TYPE_VOLUME, cmap='jet', sr=500)\n", |
|
607 | 609 | "Note that we use `dvr.replicate()` when adding the previously defined DVR to the renderer. This is because each\n", |
608 | 610 | "rendering stage can only be added to one renderer, hence, we replicate it this time. Of course, we could have used the\n", |
609 | 611 | "`dvr.replicate()` method the first time that we added the DVR to a renderer, too, but this is not mandatory. All\n", |
610 | | - "rendering stages provide such a method." |
| 612 | + "rendering stages provide such a method.\n", |
| 613 | + "\n", |
| 614 | + "## Segmentation\n", |
| 615 | + "\n", |
| 616 | + "Perform segmentation of the nuclei by applying an intensity threshold:" |
| 617 | + ] |
| 618 | + }, |
| 619 | + { |
| 620 | + "cell_type": "code", |
| 621 | + "execution_count": null, |
| 622 | + "id": "417a2589", |
| 623 | + "metadata": { |
| 624 | + "vscode": { |
| 625 | + "languageId": "plaintext" |
| 626 | + } |
| 627 | + }, |
| 628 | + "outputs": [], |
| 629 | + "source": [ |
| 630 | + "data_denoised = ndi.gaussian_filter(data, 1)" |
| 631 | + ] |
| 632 | + }, |
| 633 | + { |
| 634 | + "cell_type": "code", |
| 635 | + "execution_count": null, |
| 636 | + "id": "b8af663f", |
| 637 | + "metadata": { |
| 638 | + "vscode": { |
| 639 | + "languageId": "plaintext" |
| 640 | + } |
| 641 | + }, |
| 642 | + "outputs": [], |
| 643 | + "source": [ |
| 644 | + "GEOMETRY_TYPE_MASK = 2\n", |
| 645 | + "\n", |
| 646 | + "seg = libcarna.volume(\n", |
| 647 | + " GEOMETRY_TYPE_MASK,\n", |
| 648 | + " ndi.gaussian_filter(data, 10) > 10_000,\n", |
| 649 | + " parent=volume,\n", |
| 650 | + " spacing=volume.spacing,\n", |
| 651 | + ")\n", |
| 652 | + "\n", |
| 653 | + "libcarna.imshow(\n", |
| 654 | + " libcarna.animate(\n", |
| 655 | + " libcarna.animate.swing_local(camera, amplitude=22),\n", |
| 656 | + " n_frames=50,\n", |
| 657 | + " ).render(\n", |
| 658 | + " libcarna.renderer(600, 450, [\n", |
| 659 | + " dvr.replicate(),\n", |
| 660 | + " libcarna.mask_renderer(GEOMETRY_TYPE_MASK),\n", |
| 661 | + " ]),\n", |
| 662 | + " camera,\n", |
| 663 | + " ),\n", |
| 664 | + ")" |
| 665 | + ] |
| 666 | + }, |
| 667 | + { |
| 668 | + "cell_type": "markdown", |
| 669 | + "id": "97991990", |
| 670 | + "metadata": {}, |
| 671 | + "source": [ |
| 672 | + "## Pointwise Annotations" |
| 673 | + ] |
| 674 | + }, |
| 675 | + { |
| 676 | + "cell_type": "code", |
| 677 | + "execution_count": null, |
| 678 | + "id": "9931ba22", |
| 679 | + "metadata": { |
| 680 | + "vscode": { |
| 681 | + "languageId": "plaintext" |
| 682 | + } |
| 683 | + }, |
| 684 | + "outputs": [], |
| 685 | + "source": [ |
| 686 | + "data_max = ndi.maximum_filter(data_denoised, size=5)\n", |
| 687 | + "detections = np.where(\n", |
| 688 | + " np.logical_and(\n", |
| 689 | + " data_denoised == data_max,\n", |
| 690 | + " data_denoised >= 30_000,\n", |
| 691 | + " )\n", |
| 692 | + ")" |
| 693 | + ] |
| 694 | + }, |
| 695 | + { |
| 696 | + "cell_type": "code", |
| 697 | + "execution_count": null, |
| 698 | + "id": "537cfdd2", |
| 699 | + "metadata": { |
| 700 | + "vscode": { |
| 701 | + "languageId": "plaintext" |
| 702 | + } |
| 703 | + }, |
| 704 | + "outputs": [], |
| 705 | + "source": [ |
| 706 | + "GEOMETRY_TYPE_OPAQUE = 3\n", |
| 707 | + "\n", |
| 708 | + "ball = libcarna.meshes.create_ball(5)\n", |
| 709 | + "red = libcarna.material('solid', color=libcarna.color.RED)\n", |
| 710 | + "\n", |
| 711 | + "for xyz in zip(*detections):\n", |
| 712 | + " libcarna.geometry(\n", |
| 713 | + " GEOMETRY_TYPE_OPAQUE,\n", |
| 714 | + " parent=volume,\n", |
| 715 | + " features={\n", |
| 716 | + " libcarna.mesh_renderer.ROLE_DEFAULT_MESH: ball,\n", |
| 717 | + " libcarna.mesh_renderer.ROLE_DEFAULT_MATERIAL: red,\n", |
| 718 | + " },\n", |
| 719 | + " ).translate(\n", |
| 720 | + " *volume.transform_from_voxels_into(volume).point(xyz)\n", |
| 721 | + " )\n", |
| 722 | + "\n", |
| 723 | + "libcarna.imshow(\n", |
| 724 | + " libcarna.animate(\n", |
| 725 | + " libcarna.animate.swing_local(camera, amplitude=22),\n", |
| 726 | + " n_frames=50,\n", |
| 727 | + " ).render(\n", |
| 728 | + " libcarna.renderer(600, 450, [\n", |
| 729 | + " dvr.replicate(),\n", |
| 730 | + " libcarna.opaque_renderer(GEOMETRY_TYPE_OPAQUE),\n", |
| 731 | + " ]),\n", |
| 732 | + " camera,\n", |
| 733 | + " ),\n", |
| 734 | + ")" |
611 | 735 | ] |
612 | 736 | } |
613 | 737 | ], |
|
0 commit comments