Created
June 10, 2020 13:44
-
-
Save eqs/ea3ac4f628236cafc1a7d524817653d2 to your computer and use it in GitHub Desktop.
Tracking Zebrafish by Tracktor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# ゼブラフィッシュのトラッキングをやる\n", | |
"---" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"モジュールの読み込み" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'modules/tracktor/examples\\\\tracktor.py'" | |
] | |
}, | |
"execution_count": 1, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# examplesの中のtracktor.pyへのパスを通しておく\n", | |
"import sys\n", | |
"sys.path.append('modules/tracktor/examples/')\n", | |
"\n", | |
"from tqdm import tqdm\n", | |
"\n", | |
"import numpy as np\n", | |
"import pandas as pd\n", | |
"import cv2\n", | |
"\n", | |
"import tracktor as tr\n", | |
"\n", | |
"tr.__file__" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"ツールの設定" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"video_path = 'modules/tracktor/videos/zebrafish_video.mp4'\n", | |
"\n", | |
"# トラッキングID\n", | |
"t_id = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']\n", | |
"colours = [(0, 0, 255), (0, 255, 255), (255, 0, 255), (255, 255, 255),\n", | |
" (255, 255, 0),(255, 0, 0), (0, 255, 0), (0, 0, 0)]\n", | |
"\n", | |
"# 個体数\n", | |
"n_individuals = 5\n", | |
"# 個体が複数いるかどうかのフラグ\n", | |
"multi_object = n_individuals > 1\n", | |
"\n", | |
"# Adaptive Thresholdingのパラメタ\n", | |
"block_size = 51\n", | |
"offset = 25\n", | |
"\n", | |
"# 個体検出用のパラメタ(小さすぎる/でかすぎる個体を除くためのもの)\n", | |
"min_area = 50\n", | |
"max_area = 1000" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"個体追跡の実行" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"True" | |
] | |
}, | |
"execution_count": 3, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# 動画を開く\n", | |
"video = cv2.VideoCapture(video_path)\n", | |
"video.isOpened()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"100%|███████████████████████████████████████████████████████████████████████████▉| 14994/15000 [09:55<00:00, 30.92it/s]" | |
] | |
} | |
], | |
"source": [ | |
"# 位置をいれておく変数\n", | |
"loc_prev = np.zeros((n_individuals, 2)).tolist()\n", | |
"loc_curr = np.zeros((n_individuals, 2)).tolist()\n", | |
"df = []\n", | |
"\n", | |
"nframes = int(video.get(cv2.CAP_PROP_FRAME_COUNT))\n", | |
"pbar = tqdm(total=nframes)\n", | |
"\n", | |
"while True:\n", | |
" \n", | |
" pbar.update(1)\n", | |
" ok, image = video.read()\n", | |
" \n", | |
" if not ok:\n", | |
" break\n", | |
" \n", | |
" frame_idx = video.get(cv2.CAP_PROP_POS_FRAMES)\n", | |
"\n", | |
" image_bin = tr.colour_to_thresh(image, block_size, offset)\n", | |
"\n", | |
" final, contours, loc_prev, loc_curr = tr.detect_and_draw_contours(image, image_bin,\n", | |
" loc_prev, loc_curr,\n", | |
" min_area, max_area)\n", | |
" \n", | |
" if len(loc_curr) != n_individuals:\n", | |
" contours, loc_curr = tr.apply_k_means(contours, n_individuals, loc_curr)\n", | |
"\n", | |
"\n", | |
" row_idx, col_idx = tr.hungarian_algorithm(loc_prev, loc_curr)\n", | |
"\n", | |
" final, loc_curr, df = tr.reorder_and_draw(final, colours, n_individuals, col_idx,\n", | |
" loc_curr, df, multi_object, frame_idx)\n", | |
"\n", | |
" # Create output dataframe\n", | |
" for i in range(n_individuals):\n", | |
" df.append([frame_idx, loc_curr[i][0], loc_curr[i][1], t_id[i]])\n", | |
"\n", | |
"# リストをpandasのDataFrameに変換する\n", | |
"df = pd.DataFrame(df, columns = ['frame','pos_x','pos_y', 'id'])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"video.release()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>frame</th>\n", | |
" <th>pos_x</th>\n", | |
" <th>pos_y</th>\n", | |
" <th>id</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <td>0</td>\n", | |
" <td>1.0</td>\n", | |
" <td>184.785185</td>\n", | |
" <td>59.246914</td>\n", | |
" <td>A</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>1</td>\n", | |
" <td>1.0</td>\n", | |
" <td>782.726437</td>\n", | |
" <td>70.147126</td>\n", | |
" <td>B</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>2</td>\n", | |
" <td>1.0</td>\n", | |
" <td>301.841339</td>\n", | |
" <td>121.573508</td>\n", | |
" <td>C</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>3</td>\n", | |
" <td>1.0</td>\n", | |
" <td>195.685083</td>\n", | |
" <td>289.246777</td>\n", | |
" <td>D</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>4</td>\n", | |
" <td>1.0</td>\n", | |
" <td>229.135250</td>\n", | |
" <td>328.037274</td>\n", | |
" <td>E</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>5</td>\n", | |
" <td>2.0</td>\n", | |
" <td>178.861979</td>\n", | |
" <td>60.221354</td>\n", | |
" <td>A</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>6</td>\n", | |
" <td>2.0</td>\n", | |
" <td>781.649930</td>\n", | |
" <td>66.481172</td>\n", | |
" <td>B</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>7</td>\n", | |
" <td>2.0</td>\n", | |
" <td>302.521262</td>\n", | |
" <td>120.418381</td>\n", | |
" <td>C</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>8</td>\n", | |
" <td>2.0</td>\n", | |
" <td>194.862847</td>\n", | |
" <td>290.975694</td>\n", | |
" <td>D</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>9</td>\n", | |
" <td>2.0</td>\n", | |
" <td>227.624044</td>\n", | |
" <td>330.831694</td>\n", | |
" <td>E</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>10</td>\n", | |
" <td>3.0</td>\n", | |
" <td>174.192848</td>\n", | |
" <td>60.541507</td>\n", | |
" <td>A</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>11</td>\n", | |
" <td>3.0</td>\n", | |
" <td>783.514170</td>\n", | |
" <td>62.967611</td>\n", | |
" <td>B</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>12</td>\n", | |
" <td>3.0</td>\n", | |
" <td>303.360000</td>\n", | |
" <td>119.509630</td>\n", | |
" <td>C</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>13</td>\n", | |
" <td>3.0</td>\n", | |
" <td>193.814035</td>\n", | |
" <td>293.143860</td>\n", | |
" <td>D</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>14</td>\n", | |
" <td>3.0</td>\n", | |
" <td>226.002179</td>\n", | |
" <td>333.840959</td>\n", | |
" <td>E</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>15</td>\n", | |
" <td>4.0</td>\n", | |
" <td>169.844125</td>\n", | |
" <td>60.898082</td>\n", | |
" <td>A</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>16</td>\n", | |
" <td>4.0</td>\n", | |
" <td>785.762082</td>\n", | |
" <td>61.651797</td>\n", | |
" <td>B</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>17</td>\n", | |
" <td>4.0</td>\n", | |
" <td>304.232493</td>\n", | |
" <td>118.819328</td>\n", | |
" <td>C</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>18</td>\n", | |
" <td>4.0</td>\n", | |
" <td>192.903955</td>\n", | |
" <td>294.902072</td>\n", | |
" <td>D</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>19</td>\n", | |
" <td>4.0</td>\n", | |
" <td>224.186754</td>\n", | |
" <td>337.018458</td>\n", | |
" <td>E</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" frame pos_x pos_y id\n", | |
"0 1.0 184.785185 59.246914 A\n", | |
"1 1.0 782.726437 70.147126 B\n", | |
"2 1.0 301.841339 121.573508 C\n", | |
"3 1.0 195.685083 289.246777 D\n", | |
"4 1.0 229.135250 328.037274 E\n", | |
"5 2.0 178.861979 60.221354 A\n", | |
"6 2.0 781.649930 66.481172 B\n", | |
"7 2.0 302.521262 120.418381 C\n", | |
"8 2.0 194.862847 290.975694 D\n", | |
"9 2.0 227.624044 330.831694 E\n", | |
"10 3.0 174.192848 60.541507 A\n", | |
"11 3.0 783.514170 62.967611 B\n", | |
"12 3.0 303.360000 119.509630 C\n", | |
"13 3.0 193.814035 293.143860 D\n", | |
"14 3.0 226.002179 333.840959 E\n", | |
"15 4.0 169.844125 60.898082 A\n", | |
"16 4.0 785.762082 61.651797 B\n", | |
"17 4.0 304.232493 118.819328 C\n", | |
"18 4.0 192.903955 294.902072 D\n", | |
"19 4.0 224.186754 337.018458 E" | |
] | |
}, | |
"execution_count": 5, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"df.head(20)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"df.to_csv('zebrafish.csv', index=False)" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"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.7.3" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 4 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://nbviewer.jupyter.org/gist/eqs/ea3ac4f628236cafc1a7d524817653d2