{"id":1361,"date":"2017-02-20T06:02:59","date_gmt":"2017-02-20T04:02:59","guid":{"rendered":"https:\/\/www.kurokesu.com\/main\/?p=1361"},"modified":"2017-02-16T16:17:43","modified_gmt":"2017-02-16T14:17:43","slug":"dumb-thermometer-gets-digital-output","status":"publish","type":"post","link":"https:\/\/www.kurokesu.com\/main\/2017\/02\/20\/dumb-thermometer-gets-digital-output\/","title":{"rendered":"Dumb thermometer gets digital output"},"content":{"rendered":"<p><a href=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/setup_2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft wp-image-1388\" src=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/setup_2.jpg\" width=\"200\" height=\"122\" srcset=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/setup_2.jpg 539w, https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/setup_2-300x184.jpg 300w\" sizes=\"auto, (max-width: 200px) 100vw, 200px\" \/><\/a>Some time ago I purchased 4 channel thermometer. Soon after tried few optical character recognition (OCR) techniques on 7 segment symbols including <a href=\"https:\/\/github.com\/madmaze\/pytesseract\">pytesseract<\/a>, they worked but I was not happy with results. Few days ago <a href=\"http:\/\/www.pyimagesearch.com\/2017\/02\/13\/recognizing-digits-with-opencv-and-python\/\">pyimagesearch<\/a> published article detailing his approach. So I pushed it a bit forward and made solution more robust. Also added possibility to analyze video instead of single frame.<\/p>\n<h3>Setup<\/h3>\n<p>Not much was needed &#8211; camera, thermometer and bracket to keep them mechanically connected.<\/p>\n<ul>\n<li>4-Channel K-Type Digital Thermometer from eBay<\/li>\n<li><a href=\"http:\/\/www.kurokesu.com\/shop\/cameras\/CAMUSB1\">Kurokesu C1 USB camera<\/a> with <a href=\"http:\/\/www.kurokesu.com\/shop\/lenses\/CSLZFA2812\">2.8-12mm CS lens<\/a><\/li>\n<li>Stainless steel <a href=\"http:\/\/www.kurokesu.com\/shop\/accessories\/MAGICARM11\">articulating arm<\/a> with <a href=\"http:\/\/www.kurokesu.com\/shop\/CRAB_CLAMP\">C clamp<\/a><\/li>\n<\/ul>\n<p><a href=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/setup_.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1386\" src=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/setup_.jpg\" width=\"500\" height=\"599\" srcset=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/setup_.jpg 800w, https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/setup_-251x300.jpg 251w, https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/setup_-768x920.jpg 768w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/a><\/p>\n<p>Attaching C-clamp directly to instrument is kind of cruel, but this is quick and dirty setup. Additional light was not needed, camera and algorithm worked fine with regular room lights.<\/p>\n<h3>Digitizing process<\/h3>\n<p>First we need to find where useful information is located. Algorithm searches for approximated polygon with 4 edges. If your device has rectangular high contrast frame there is a chance that LCD boundaries will be detected automatically, otherwise mask remaining frame except LCD itself with white trapezoid.<\/p>\n<p>Then we need to find out where our digits are located. Take frame where where most of the segments are on (initial frame from power-up when all segments are turned on would be perfect) and process it with another script.<\/p>\n<p>Two configuration files will be saved to disk. These files will be used during normal OCR operation.<\/p>\n<p>Below is an animation how each segment is being located and recognized. Red highlighted clip is debug output to confirm correct segment location, threshold and identification. Green boundaries with recognized numbers is debug output of video stream.<\/p>\n<p><a href=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/segments.gif\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1377 alignleft\" src=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/segments.gif\" alt=\"\" width=\"265\" height=\"335\" \/><\/a><\/p>\n<p><a href=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/recognize.gif\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-1378 alignleft\" src=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/recognize.gif\" alt=\"\" width=\"265\" height=\"335\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<h3>Results<\/h3>\n<p>Results are saved to CSV file and ready to be imported into LibreOffice. Graph below visualizes two cycles of reflow oven. Sensors were placed on:<\/p>\n<ol>\n<li>Top of PCB<\/li>\n<li>Below PCB on drawer bed<\/li>\n<li>Bottom oven wall<\/li>\n<li>Drawer handle<\/li>\n<\/ol>\n<p><a href=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/results.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1380\" src=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/results-1024x524.png\" width=\"600\" height=\"307\" srcset=\"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/results-1024x524.png 1024w, https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/results-300x154.png 300w, https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/results-768x393.png 768w, https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/results.png 1697w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/a>If you zoom-in graphic, some artifacts will be seen. This is an issue with cheap thermometer, seems like it has calculation problems when temperature ramp is too steep.<\/p>\n<h3>Code<\/h3>\n<p>Code is really sketchy, but as usual I uploaded it to Github, feel free to explore.<br \/>\n<script src=\"https:\/\/gist.github.com\/Lukse\/ac5475ea574924fb7a7822dbfe483a03.js\"><\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Some time ago I purchased 4 channel thermometer. Soon after tried few optical character recognition (OCR) techniques on 7 segment symbols including pytesseract, they worked but I was not happy with results. Few days ago pyimagesearch published article detailing his approach. So I pushed it a bit forward and made solution more robust. Also added [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1388,"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":false,"_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":[157],"tags":[24,238,129,237,64,49,209,14],"class_list":["post-1361","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to","tag-computer-vision","tag-instrumentation","tag-kurokesu-c1","tag-ocr","tag-opencv","tag-python","tag-thermometer","tag-usb-camera"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/www.kurokesu.com\/main\/wp-content\/uploads\/2017\/02\/setup_2.jpg","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p6VSmB-lX","_links":{"self":[{"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/posts\/1361","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=1361"}],"version-history":[{"count":29,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/posts\/1361\/revisions"}],"predecessor-version":[{"id":2481,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/posts\/1361\/revisions\/2481"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/media\/1388"}],"wp:attachment":[{"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/media?parent=1361"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/categories?post=1361"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kurokesu.com\/main\/wp-json\/wp\/v2\/tags?post=1361"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}