578 lines
42 KiB
Plaintext
578 lines
42 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Tutorial on Monday, 9 December 2024 \n",
|
||
"\n",
|
||
"Will be in PC Pool 9, Werthmannstraße 4. This is next door (south of) the Universitäts Bibliothek."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import numpy as np\n",
|
||
"import matplotlib.pyplot as plt"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# From programming to ‘computer-assisted science’\n",
|
||
"\n",
|
||
"You now know the basics of programming in Python.\n",
|
||
"\n",
|
||
"You must practice, practice, practice to really learn this stuff. [Advent of code](https://adventofcode.com).\n",
|
||
"\n",
|
||
"The best way to practice is to use Python to do something YOU want.\n",
|
||
"\n",
|
||
"We are now moving towards \"computer-assisted science\". Our focus will become more on the ideas and tools to achieve specific tasks rather than on programming directly. Of course, knowing how to program itself is a hugely valuable skill in this endeavor and we are still here to help you with that."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Image analysis\n",
|
||
"\n",
|
||
"Images are a rich source of information, usually very intuitive for humans to understand.\n",
|
||
"\n",
|
||
"Computer vision is a vast field with incredible progress\n",
|
||
"\n",
|
||
"Nevertheless, our visual system is typically much better at “seeing” (image comprehension) than any computer."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Why would we want to use computer vision in Biology?\n",
|
||
"\n",
|
||
"High throughput\n",
|
||
"\n",
|
||
"Eliminate human subjectivity\n",
|
||
"\n",
|
||
"Reproducibility\n",
|
||
"\n",
|
||
"Create new types of experiments with online image processing"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Image analysis depends on images\n",
|
||
"\n",
|
||
"Typically, the image processing task can be made much easier by spending time to optimize the image acquisition (lighting, contrast, focus, and so on)\n",
|
||
"\n",
|
||
"“much easier” could mean “nearly trivial and fast” from “difficult and slow” or even “possible” from “impossible”"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Example – Virtual Reality for Freely Moving Animals\n",
|
||
"\n",
|
||
"Stowers JR*, Hofbauer M*, Bastien R, Griessner J⁑, Higgins P⁑, Farooqui S⁑, Fischer RM, Nowikovsky K, Haubensak W, Couzin ID, Tessmar-Raible K✎, Straw AD✎. Virtual Reality for Freely Moving Animals. *Nature Methods* 14, 995–1002 (2017) [doi:10.1038/nmeth.4399](https://doi.org/10.1038/nmeth.4399) See also https://www.youtube.com/watch?v=e_BxdbNidyQ&feature=youtu.be\n",
|
||
"\n",
|
||
"![vr-fig1.jpg](vr-fig1.jpg)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Image representations\n",
|
||
"\n",
|
||
"Computer images are just arrays of data\n",
|
||
"\n",
|
||
"Monochrome images are 2D arrays (h, w)\n",
|
||
"\n",
|
||
"Color images can be represented as 3D arrays (h,w,channel). (Actually “2.5 D” – just 3x 2D arrays: red, green, blue)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"In Python, `numpy` (`np` for short) is the most common way to manipulate arrays of numbers. Here we will create an 8x8 pixel image and put it in the variable `check`.\n",
|
||
"\n",
|
||
"Images have way too much data to operate efficiently with pure Python"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 8,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"array([[0., 1., 0., 1., 0., 1., 0., 1.],\n",
|
||
" [1., 0., 1., 0., 1., 0., 1., 0.],\n",
|
||
" [0., 1., 0., 1., 0., 1., 0., 1.],\n",
|
||
" [1., 0., 1., 0., 1., 0., 1., 0.],\n",
|
||
" [0., 1., 0., 1., 0., 1., 0., 1.],\n",
|
||
" [1., 0., 1., 0., 1., 0., 1., 0.],\n",
|
||
" [0., 1., 0., 1., 0., 1., 0., 1.],\n",
|
||
" [1., 0., 1., 0., 1., 0., 1., 0.]])"
|
||
]
|
||
},
|
||
"execution_count": 8,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"# Create a variable called `check` which will contain an 8x8 array of numbers.\n",
|
||
"check = np.zeros((8, 8))\n",
|
||
"check[::2, 1::2] = 1\n",
|
||
"check[1::2, ::2] = 1\n",
|
||
"check"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"image/png": "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",
|
||
"text/plain": [
|
||
"<Figure size 640x480 with 1 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"# Now lets view our 8x8 pixel image:\n",
|
||
"plt.imshow(check, cmap='gray');"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Key basic image analysis primitives\n",
|
||
"\n",
|
||
"- Arithmetic (add, subtract, divide, multiply)\n",
|
||
"- Thresholding (greater than, less than)\n",
|
||
"- argmax and argmin\n",
|
||
"- Connected components (“labels”)\n",
|
||
"- Morphological operations, e.g. erosion and dilation\n",
|
||
"- Edge detection\n",
|
||
"- Smoothing, sharpening\n",
|
||
"\n",
|
||
"Visit http://scikit-image.org/docs/stable/auto_examples/index.html"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Key image analysis tasks\n",
|
||
"\n",
|
||
"- Classification\n",
|
||
"\n",
|
||
"- Counting\n",
|
||
"\n",
|
||
"- Detection (and localization)\n",
|
||
"\n",
|
||
"- Tracking\n",
|
||
"\n",
|
||
"- Measuring"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Computer vision compared to human vision\n",
|
||
"\n",
|
||
"We effortlessly “see” and comprehend visual scenery.\n",
|
||
"\n",
|
||
"Brain development evolved over millions of years.\n",
|
||
"\n",
|
||
"We know a lot about vision, but still big questions remain.\n",
|
||
"\n",
|
||
"![zebras](https://upload.wikimedia.org/wikipedia/commons/3/3a/Zebras_Serengeti.JPG)\n",
|
||
"Photo: https://commons.wikimedia.org/wiki/File:Zebras_Serengeti.JPG\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Raw image representation\n",
|
||
"\n",
|
||
"- In typical image monochrome files, each pixel is stored as a single byte\n",
|
||
"- Each stored byte represents the brightness of each pixel\n",
|
||
"- A byte is 8 bits\n",
|
||
"- Decimal: 0..255\n",
|
||
"- Binary: 0000 0000..1111 1111\n",
|
||
"- For color images, each pixel is stored as 3 bytes: (Red, Green, Blue) intensity\n",
|
||
"\n",
|
||
"![decimal-hex-binary](https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/CPT-Numbers-Conversion.svg/505px-CPT-Numbers-Conversion.svg.png)\n",
|
||
"Diagram: https://commons.wikimedia.org/wiki/File:CPT-Numbers-Conversion.svg\n",
|
||
"\n",
|
||
"See also https://en.wikibooks.org/wiki/A-level_Computing/AQA/Paper_2/Fundamentals_of_data_representation/Number_bases"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"A conversion table for the first 16 integers:\n",
|
||
"\n",
|
||
"| Binary | Decimal | Hex |\n",
|
||
"|--------|---------|-----|\n",
|
||
"| 0000 | 0 | 0 |\n",
|
||
"| 0001 | 1 | 1 |\n",
|
||
"| 0010 | 2 | 2 |\n",
|
||
"| 0011 | 3 | 3 |\n",
|
||
"| 0100 | 4 | 4 |\n",
|
||
"| 0101 | 5 | 5 |\n",
|
||
"| 0110 | 6 | 6 |\n",
|
||
"| 0111 | 7 | 7 |\n",
|
||
"| 1000 | 8 | 8 |\n",
|
||
"| 1001 | 9 | 9 |\n",
|
||
"| 1010 | 10 | A |\n",
|
||
"| 1011 | 11 | B |\n",
|
||
"| 1100 | 12 | C |\n",
|
||
"| 1101 | 13 | D |\n",
|
||
"| 1110 | 14 | E |\n",
|
||
"| 1111 | 15 | F |\n",
|
||
"\n",
|
||
"So, one can write a single byte (8 bits) always with exactly two hex digits. This is why hex digits are often used when discussing low-level memory usage in computers. With such 8 bit numbers, 255 (decimal) is `FF` (hex). When writing hex, often the number starts with `0x`."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 10,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"True"
|
||
]
|
||
},
|
||
"execution_count": 10,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"0xFF == 255"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 11,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"15"
|
||
]
|
||
},
|
||
"execution_count": 11,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"0b1111"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 12,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"True"
|
||
]
|
||
},
|
||
"execution_count": 12,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"0b1111 == 0x0F"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 13,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"'0b11111111'"
|
||
]
|
||
},
|
||
"execution_count": 13,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"bin(255)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 14,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"'0xff'"
|
||
]
|
||
},
|
||
"execution_count": 14,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"hex(255)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 15,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"16"
|
||
]
|
||
},
|
||
"execution_count": 15,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"0x10"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 16,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"'0x10'"
|
||
]
|
||
},
|
||
"execution_count": 16,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"hex(16)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 17,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"'0b10000'"
|
||
]
|
||
},
|
||
"execution_count": 17,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"bin(16)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 18,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"'0xf'"
|
||
]
|
||
},
|
||
"execution_count": 18,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"hex(15)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 19,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"'0b1111'"
|
||
]
|
||
},
|
||
"execution_count": 19,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"bin(15)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Compressed Image formats\n",
|
||
"\n",
|
||
"- Lossy compression: JPG, GIF, most movie codecs\n",
|
||
"- Lossless compression: PNG, TIFF, BMP\n",
|
||
"\n",
|
||
"- With modern movie formats, the codecs (compressor & decompressor) are independent from the file format (e.g. mp4, avi or mkv). The file format is mostly a \"container\". Common codecs for video are h264/avc, h265/hevc, vp8, vp9, or av1.\n",
|
||
"\n",
|
||
"- Similar consideration applies to audio. There are specific audio formats (WAV) and also codecs for audio data which specify how the data is stored in a container like MP4 or AVI \"video\" files."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Limits of images with 8 bits per channel\n",
|
||
"\n",
|
||
"- 8 bits is not a large [dynamic range](https://en.wikipedia.org/wiki/Dynamic_range)\n",
|
||
"- Typically, a \"good exposure\" means filling the range of available intensity values. Can be checked by a histogram of pixel intensity.\n",
|
||
"- Higher “bit depth” formats also exist (e.g. 16 bit images) and are often used in scientific computing (e.g. many TIFF images). Theses are often called HDR High Dynamic Range image.\n",
|
||
"\n",
|
||
"![camera](camera.png)\n",
|
||
"Image: https://github.com/scikit-image/scikit-image/blob/master/skimage/data/camera.png"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 20,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"(512, 512)\n",
|
||
"uint8\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"import skimage # \"pip install scikit-image\"\n",
|
||
"x = skimage.data.camera()\n",
|
||
"print(x.shape)\n",
|
||
"print(x.dtype)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 22,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Requirement already satisfied: scikit-image in /Users/andrew/anaconda3/envs/pm21-dragon/lib/python3.11/site-packages (0.24.0)\n",
|
||
"Requirement already satisfied: numpy>=1.23 in /Users/andrew/anaconda3/envs/pm21-dragon/lib/python3.11/site-packages (from scikit-image) (1.26.4)\n",
|
||
"Requirement already satisfied: scipy>=1.9 in /Users/andrew/anaconda3/envs/pm21-dragon/lib/python3.11/site-packages (from scikit-image) (1.14.1)\n",
|
||
"Requirement already satisfied: networkx>=2.8 in /Users/andrew/anaconda3/envs/pm21-dragon/lib/python3.11/site-packages (from scikit-image) (3.4.2)\n",
|
||
"Requirement already satisfied: pillow>=9.1 in /Users/andrew/anaconda3/envs/pm21-dragon/lib/python3.11/site-packages (from scikit-image) (11.0.0)\n",
|
||
"Requirement already satisfied: imageio>=2.33 in /Users/andrew/anaconda3/envs/pm21-dragon/lib/python3.11/site-packages (from scikit-image) (2.36.1)\n",
|
||
"Requirement already satisfied: tifffile>=2022.8.12 in /Users/andrew/anaconda3/envs/pm21-dragon/lib/python3.11/site-packages (from scikit-image) (2024.9.20)\n",
|
||
"Requirement already satisfied: packaging>=21 in /Users/andrew/anaconda3/envs/pm21-dragon/lib/python3.11/site-packages (from scikit-image) (24.1)\n",
|
||
"Requirement already satisfied: lazy-loader>=0.4 in /Users/andrew/anaconda3/envs/pm21-dragon/lib/python3.11/site-packages (from scikit-image) (0.4)\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"!pip install scikit-image"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 21,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"image/png": "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",
|
||
"text/plain": [
|
||
"<Figure size 640x480 with 1 Axes>"
|
||
]
|
||
},
|
||
"metadata": {},
|
||
"output_type": "display_data"
|
||
}
|
||
],
|
||
"source": [
|
||
"import skimage\n",
|
||
"plt.hist(skimage.data.camera().flat,bins=256);\n",
|
||
"plt.xlabel('luminance');\n",
|
||
"plt.ylabel('number of occurances');"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python 3 (ipykernel)",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.11.10"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 4
|
||
}
|