{"id":1074,"date":"2016-10-24T06:01:14","date_gmt":"2016-10-24T04:01:14","guid":{"rendered":"https:\/\/www.kurokesu.com\/main\/?p=1074"},"modified":"2016-10-25T16:38:52","modified_gmt":"2016-10-25T14:38:52","slug":"heatmap-motion-analysis-of-autonomous-robot","status":"publish","type":"post","link":"https:\/\/www.kurokesu.com\/main\/2016\/10\/24\/heatmap-motion-analysis-of-autonomous-robot\/","title":{"rendered":"Heatmap motion analysis of autonomous robot"},"content":{"rendered":"<p style=\"text-align: justify;\">I have always wanted to ease my daily life and obtain vacuum robot. Many things were stopping for a while, but finally found a local company which provides demo units so could not resist taking one for a spin. What a good chance to run some computer vision processing algorithms to analyze it!<\/p>\n<p style=\"text-align: justify;\">Seen few pictures where robot owners installed LED on top of their robot and took long exposure pictures capturing motion path in a single shot. I wanted to be more scientific and replicate this effect only without a LED and long exposure photography.<\/p>\n<h3 style=\"text-align: justify;\">Preparation<\/h3>\n<p style=\"text-align: justify;\">As cleaning properties were reviewed by multiple owners I will skip this part. Let&#8217;s just say robot does what it was designed to do. I wanted to visualize motion path and coverage area. So placed couple of simple obstacles and added some dirt imitation in blue masking tape marked region (I thought robot will stay longer in this place but my guess was wrong).<\/p>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1090\" src=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2016\/10\/IMG_8444_r-1024x683.jpg\" alt=\"img_8444_r\" width=\"600\" height=\"400\" srcset=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2016\/10\/IMG_8444_r-1024x683.jpg 1024w, https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2016\/10\/IMG_8444_r-300x200.jpg 300w, https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2016\/10\/IMG_8444_r-768x512.jpg 768w, https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2016\/10\/IMG_8444_r.jpg 1500w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/>Could not resist and mounted GoPro action camera to take awesome first person (FPV) video. <strong>Note: speed is increased 4 times.<\/strong><\/p>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1095\" src=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2016\/10\/robot1.gif\" alt=\"robot1\" width=\"600\" height=\"337\" \/>Installed <a href=\"http:\/\/www.kurokesu.com\/shop\/cameras\/CAMUSB1\">Kurokesu C1<\/a> camera with <a href=\"http:\/\/www.kurokesu.com\/shop\/lenses\/CSL155\">1.55m CS fisheye lens<\/a> mounted above the room recorded all the action. Later this footage was used to run motion analysis.<\/p>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1077\" src=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2016\/10\/IMG_8478_r-1024x683.jpg\" alt=\"img_8478_r\" width=\"600\" height=\"400\" srcset=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2016\/10\/IMG_8478_r-1024x683.jpg 1024w, https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2016\/10\/IMG_8478_r-300x200.jpg 300w, https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2016\/10\/IMG_8478_r-768x512.jpg 768w, https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2016\/10\/IMG_8478_r.jpg 1500w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/>\n<h3>Results<\/h3>\n<p style=\"text-align: justify;\">Sketchy code I wrote over half an our uses Python and background subtraction functions from OpenCV, probably not even worth publishing as a functional program. You can clearly see persistent motion as a heat-map and and cleaned area. What a hypnotic view! (Full resolution <a href=\"https:\/\/www.youtube.com\/watch?v=wmvgq9rOU0w\">youtube video<\/a> will open if you click this animated gif)<\/p>\n<p style=\"text-align: justify;\"><a href=\"https:\/\/www.youtube.com\/watch?v=wmvgq9rOU0w\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1099\" src=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2016\/10\/blue1.gif\" alt=\"blue1\" width=\"600\" height=\"337\" \/><\/a><\/p>\n<h3 style=\"text-align: justify;\">Code highlights<\/h3>\n<p style=\"text-align: justify;\">Open video file and prepare for reading it.<\/p>\n<pre>cap = cv2.VideoCapture(\"robot_video.avi\")<\/pre>\n<p style=\"text-align: justify;\">Initialize background subtraction function. Parameters might vary depending on your situation.<\/p>\n<pre style=\"text-align: justify;\">backsub = cv2.createBackgroundSubtractorMOG2(history=200, varThreshold=128, detectShadows=True)\r\n<\/pre>\n<p style=\"text-align: justify;\">Read and subtract background from each frame. Result image is all black. Motion areas are white.<\/p>\n<pre>ret, im = cap.read()\u00a0\u00a0 \r\nfgmask = backsub.apply(im, None, 0.01)<\/pre>\n<p style=\"text-align: justify;\">Integrate all motion images into one frame. Kind of long exposure imitation.<\/p>\n<pre>arr = arr + imarr<\/pre>\n<p style=\"text-align: justify;\">After all frames are processed normalize result picture and run grayscale to heatmap gradient function. Some tricks were used to convert image into float type and normalize pixel values correctly before this step.<\/p>\n<pre>heat = cv2.applyColorMap(arr, cv2.COLORMAP_JET)<\/pre>\n<p style=\"text-align: justify;\">Save and display calculated heatmap picture<\/p>\n<pre>cv2.imwrite(\"heatmap.jpg\", heat)\r\ncv2.imshow(\"heatmap\", heat)<\/pre>\n<p>Also added feature to save each n&#8217;th heatmap frame to decimate output clip and speed up processing time. After separate frames were produced video and <a href=\"https:\/\/www.kurokesu.com\/main\/2016\/07\/14\/making-animated-gifs\/\">animated gif&#8217;s were rendered<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have always wanted to ease my daily life and obtain vacuum robot. Many things were stopping for a while, but finally found a local company which provides demo units so could not resist taking one for a spin. What a good chance to run some computer vision processing algorithms to analyze it! Seen few [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1092,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[153],"tags":[183,101,62,189,188,184,65,64,187,49,185,186,151],"class_list":["post-1074","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-projects","tag-analysis","tag-animated-gif","tag-camera","tag-fpv","tag-gopro","tag-heatmap","tag-motion","tag-opencv","tag-persistent","tag-python","tag-robot","tag-vision","tag-youtube"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2016\/10\/motion2.jpg","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p6VSmB-hk","_links":{"self":[{"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/posts\/1074","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/comments?post=1074"}],"version-history":[{"count":48,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/posts\/1074\/revisions"}],"predecessor-version":[{"id":1152,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/posts\/1074\/revisions\/1152"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/media\/1092"}],"wp:attachment":[{"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/media?parent=1074"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/categories?post=1074"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/tags?post=1074"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}