{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# ImageJ Tutorials and Demo\n", "\n", "Welcome to the ImageJ tutorial series. These notebooks offer a hands-on series of lessons for learning ImageJ.\n", "\n", "* For a quick demo of what ImageJ can do, ___just scroll down___!\n", "\n", "* To dive in to the tutorials, click the links below. If ImageJ is new to you, please try the \"Using ImageJ\" notebooks first.\n", "\n", "* For a thorough academic overview of the ImageJ software stack, including its features, history, motivation and goals, see:\n", " > Rueden CT et al. \"[ImageJ2: ImageJ for the next generation of scientific image data](https://doi.org/10.1186%2Fs12859-017-1934-z).\" _BMC Bioinformatics_ __18:529__ (29 November 2017).\n", " \n", "* Learn more about ImageJ at [imagej.net](https://imagej.net/). Learn more about Jupyter Notebook at [jupyter.org](https://jupyter.org/).\n", " \n", "* See also [scikit-image tutorial notebooks](https://github.com/scikit-image/skimage-tutorials) and [SimpleITK tutorial notebooks](https://github.com/InsightSoftwareConsortium/SimpleITK-Notebooks).\n", "\n", "Feedback is very welcome! Please share your ideas on the [ImageJ Forum](http://forum.imagej.net/)!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", "
\n", "
\n", "
\n", "
\n", "

Using ImageJ

\n", "
    \n", "
  1. Fundamentals of ImageJ
  2. \n", "
  3. ImageJ Ops
  4. \n", "
  5. ImgLib2 Basics
  6. \n", "
  7. Tables
  8. \n", "
  9. Mixed World: Using ImageJ 1.x
  10. \n", "
  11. ImageJ with Python Kernel
  12. \n", "
\n", "
\n", "
\n", "

Extending ImageJ

\n", "
    \n", "
  1. Scripting: the easy way to extend ImageJ (incomplete)
  2. \n", "
  3. Extending ImageJ: Data Input and Output
  4. \n", "
  5. Extending ImageJ: Commands (placeholder)
  6. \n", "
  7. Extending ImageJ: Ops
  8. \n", "
  9. Extending ImageJ: Tools (placeholder)
  10. \n", "
\n", "
\n", "
\n", "
\n", "
\n", "

Advanced usage

\n", "
    \n", "
  1. SciJava in Detail
  2. \n", "
  3. ImgLib2 in Detail
  4. \n", "
\n", "
\n", "
\n", "

Advanced extensions

\n", "
    \n", "
  1. Creating a custom service (coming later)
  2. \n", "
  3. Customizing module execution (coming later)
  4. \n", "
  5. Creating a SCIFIO plugin (coming later)
  6. \n", "
\n", "
\n", "
\n", "
\n", "
\n", "
\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ImageJ Demo" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, we spin up an ImageJ. For more details on how this works, see the [Fundamentals of ImageJ](1-Using-ImageJ/1-Fundamentals.ipynb) notebook." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Added new repo: imagej.public\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "method": "display_data" }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "787efcd4-df44-483d-94d2-f256df468e64", "version_major": 2, "version_minor": 0 }, "method": "display_data" }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "ImageJ v2.0.0-rc-71 is ready to go." ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%classpath config resolver imagej.public https://maven.imagej.net/content/groups/public\n", "%classpath add mvn net.imagej imagej 2.0.0-rc-71\n", "ij = new net.imagej.ImageJ()\n", "\"ImageJ v${ij.getVersion()} is ready to go.\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Load some images" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[INFO] Populating metadata\n", "[INFO] Populating metadata\n", "[INFO] Populating metadata\n", "[INFO] Populating metadata\n" ] }, { "data": { "text/html": [ "
mandrillcells
" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sourcePath = \"https://imagej.net/images\"\n", "//sourcePath = System.getProperty(\"user.home\") + \"/data\"\n", "cells = ij.io().open(sourcePath + \"/FluorescentCells.jpg\")\n", "mandrill = ij.io().open(sourcePath + \"/baboon.jpg\")\n", "ij.notebook().display([[\"mandrill\": mandrill, \"cells\": cells]])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Compute and display per-channel histograms" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "method": "display_data" }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "e77cfaef-3916-4d81-82ea-8c3a88243be7", "version_major": 2, "version_minor": 0 }, "method": "display_data" }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%classpath add mvn org.knowm.xchart xchart 3.5.2\n", "\n", "import net.imglib2.FinalInterval\n", "import org.knowm.xchart.CategoryChart\n", "import org.knowm.xchart.CategoryChartBuilder\n", "\n", "// Set this to the image you want to analyze.\n", "image = mandrill \n", "\n", "xLen = image.dimension(0)\n", "yLen = image.dimension(1)\n", "cLen = image.dimension(2)\n", "\n", "// Create a chart.\n", "CategoryChart chart = new CategoryChartBuilder().width(800).height(400).\n", " title(\"Histogram\").xAxisTitle(\"Bin\").yAxisTitle(\"Count\").build();\n", "chart.getStyler().setPlotGridVerticalLinesVisible(false).setOverlapped(true)\n", "\n", "cNames = [\"red\", \"green\", \"blue\"]\n", "colors = [new java.awt.Color(0xED4337), new java.awt.Color(0x90D860), new java.awt.Color(0x7989FF)]\n", "for (c in 0..cLen - 1) {\n", " // Slice the image at this channel.\n", " slice = ij.op().transform().crop(image, FinalInterval.createMinSize(0, 0, c, xLen, yLen, 1))\n", " // Get the histogram.\n", " histogram = ij.op().image().histogram(slice)\n", "\n", " // Extract the counts and add them to the chart.\n", " counts = []\n", " for (value in histogram)\n", " counts.add(value.getRealDouble())\n", " chart.addSeries(cNames[c as int], (0..counts.size()-1), counts).setFillColor(colors[c as int])\n", "}\n", "org.knowm.xchart.BitmapEncoder.getBufferedImage(chart)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
imagemediandogtopHatblackTopHat
" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import net.imglib2.FinalInterval\n", "\n", "// N-dimensional crop.\n", "eyes = ij.op().transform().crop(mandrill, FinalInterval.createMinSize(85, 5, 0, 335, 110, 1), true)\n", "\n", "// Type conversion.\n", "eyes32 = ij.op().convert().float32(eyes)\n", "\n", "// Median filter.\n", "median = ij.op().run(\"create.img\", eyes32)\n", "neighborhood = new HyperSphereShape(4)\n", "ij.op().run(\"filter.median\", median, eyes32, neighborhood)\n", "\n", "// Difference of Gaussians.\n", "dogFormula = \"gauss(image, sigma1) - gauss(image, sigma2)\"\n", "dog = ij.op().eval(dogFormula, [\n", " \"image\": eyes32,\n", " \"sigma1\": [20, 20],\n", " \"sigma2\": [4, 4]\n", "])\n", "\n", "// Grayscale morphology operators.\n", "import net.imglib2.algorithm.neighborhood.HyperSphereShape\n", "topHat = ij.op().morphology().topHat(eyes, [neighborhood])\n", "blackTopHat = ij.op().morphology().blackTopHat(eyes, [neighborhood])\n", "\n", "ij.notebook().display([[\"image\":eyes, \"median\":median, \"dog\":dog, \"topHat\":topHat, \"blackTopHat\":blackTopHat]])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Fourier transform with lowpass filter" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/html": [ "
imagelowpass
" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import net.imglib2.util.Util\n", "import net.imglib2.FinalDimensions\n", "\n", "image = cells\n", "radius = 10\n", "\n", "def lowpass(fft, radius) {\n", " // Declare an array to hold the current position of the cursor.\n", " pos = new long[fft.numDimensions()]\n", "\n", " // Define origin as 0,0.\n", " long[] origin = [0, 0]\n", "\n", " // Define a 2nd 'origin' at bottom left of image.\n", " // This is a bit of a hack. We want to draw a circle around the origin,\n", " // since the origin is at 0,0 - the circle will 'reflect' to the bottom.\n", " long[] origin2 = [0, fft.dimension(1)]\n", "\n", " // Loop through all pixels.\n", " cursor = fft.localizingCursor()\n", " while (cursor.hasNext()) {\n", " cursor.fwd()\n", " cursor.localize(pos)\n", "\n", " // Calculate distance from 0,0 and bottom left corner\n", " // (so we can form the reflected semi-circle).\n", " dist = Util.distance(origin, pos)\n", " dist2 = Util.distance(origin2, pos)\n", "\n", " // If distance is above radius (cutoff frequency) set value of FFT to zero.\n", " if (dist > radius && dist2 > radius)\n", " cursor.get().setZero()\n", " }\n", "}\n", "\n", "// Perform fft of the input.\n", "fft = ij.op().filter().fft(image)\n", "\n", "// Filter it.\n", "lowpass(fft, 10)\n", "\n", "// Reverse the FFT.\n", "import net.imglib2.type.numeric.real.FloatType\n", "inverse = ij.op().run(\"create.img\", image, new FloatType())\n", "ij.op().filter().ifft(inverse, fft)\n", "\n", "// Display the result.\n", "ij.notebook().display([[\"image\":image, \"lowpass\":inverse]])" ] } ], "metadata": { "kernelspec": { "display_name": "Groovy", "language": "groovy", "name": "groovy" }, "language_info": { "codemirror_mode": "groovy", "file_extension": ".groovy", "mimetype": "", "name": "Groovy", "nbconverter_exporter": "", "version": "2.4.3" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": true, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": { "height": "calc(100% - 180px)", "left": "10px", "top": "150px", "width": "307px" }, "toc_section_display": true, "toc_window_display": true } }, "nbformat": 4, "nbformat_minor": 2 }