{"id":96,"date":"2016-04-16T10:51:34","date_gmt":"2016-04-16T16:51:34","guid":{"rendered":"http:\/\/jacobncalvert.com\/?p=96"},"modified":"2018-02-10T14:31:52","modified_gmt":"2018-02-10T20:31:52","slug":"reliably-identifying-discrete-colors","status":"publish","type":"post","link":"https:\/\/jacobncalvert.com\/blog-archive\/2016\/04\/16\/reliably-identifying-discrete-colors\/","title":{"rendered":"Reliably identifying discrete colors from an RGB color sensor"},"content":{"rendered":"<p>For my Capstone Design project, one of my many tasks was to identify discrete colors on painted blocks (red, green, blue, yellow) using a the\u00a0<a href=\"https:\/\/www.adafruit.com\/datasheets\/TCS34725.pdf\">TCS34725 color sensor<\/a>. I configured the color sensor to pass back four 16-bit integers representing the RGB and Clear color values of the reflected object that the sensor is &#8220;looking&#8221; at. Initially, I tried a simple linear matrix equation to map the input RGBC values to RGBy output numbers. I then took the highest output value as the &#8216;color&#8217; it represented. This is easily seen in the equations below.<\/p>\n<div id=\"attachment_97\" style=\"width: 310px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-97\" loading=\"lazy\" class=\"size-medium wp-image-97\" src=\"http:\/\/jacobncalvert.com\/wp-content\/uploads\/2018\/02\/first_matrix_approx-300x138.png\" alt=\"First Matrix Approx\" width=\"300\" height=\"138\" srcset=\"https:\/\/jacobncalvert.com\/blog-archive\/wp-content\/uploads\/2018\/02\/first_matrix_approx-300x138.png 300w, https:\/\/jacobncalvert.com\/blog-archive\/wp-content\/uploads\/2018\/02\/first_matrix_approx.png 527w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><p id=\"caption-attachment-97\" class=\"wp-caption-text\">First Matrix Approx.<\/p><\/div>\n<p>The idea was to use the coefficients in the matrix on the left to scale the incoming data (R<sub>S<\/sub>, G<sub>S<\/sub>, B<sub>S<\/sub>) and produce an output that could be used to identify that color. This works in theory because of color mixing. However, due to imperfect reflection, imperfect lighting, and other types of imperfection, this was not as reliable as I wanted.<br \/>\nThe next logical step was to &#8220;train&#8221; the coefficients by some manner. This was accomplished by taking a block of each color and wiggling it in front of the sensor at varying heights and angles and recording the RGB values from the sensor. I took 10,000 samples of each color and proceeded to do some post-processing in FreeMAT (a MATLAB clone). The post-processing proceeded in the following manner:<\/p>\n<ol>\n<li>For each set of 10,000 samples, separate the RGB components, and take the mean of each component.<\/li>\n<li>Assemble those generated means into a three-component array and divide by the 2-norm, thereby normalizing the array<\/li>\n<li>Repeat the first two steps for each of the the color samples<\/li>\n<\/ol>\n<p>The arrays that are generated are your coefficients for the previously shown matrix.<br \/>\nThis method turned out to be very effective. I also found that if the colors change, it is as simple as regenerating the coefficients to compensate. Then the system will be able to identify the colors again. I am quite confident that this method can be used to identify many other colors as well, however I have only tested on the four colors.<br \/>\nI have attached my .m script below for further exploration.\u00a0<b><br \/>\n<a href=\"http:\/\/jacobncalvert.com\/wp-content\/uploads\/2018\/02\/coeff_make.m.txt\">coeff_make.m<\/a><br \/>\n<\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>For my Capstone Design project, one of my many tasks was to identify discrete colors on painted blocks (red, green, blue, yellow) using a the\u00a0TCS34725 color sensor. I configured the color sensor to pass back four 16-bit integers representing the RGB and Clear color values of the reflected object that the sensor is &#8220;looking&#8221; at. Initially, I tried a simple linear matrix equation to map the input RGBC values to RGBy output numbers. I then took the highest output value&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[21],"tags":[22,24,23,25],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v16.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Reliably identifying discrete colors from an RGB color sensor - Jacob N Calvert<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/jacobncalvert.com\/blog-archive\/2016\/04\/16\/reliably-identifying-discrete-colors\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Reliably identifying discrete colors from an RGB color sensor - Jacob N Calvert\" \/>\n<meta property=\"og:description\" content=\"For my Capstone Design project, one of my many tasks was to identify discrete colors on painted blocks (red, green, blue, yellow) using a the\u00a0TCS34725 color sensor. I configured the color sensor to pass back four 16-bit integers representing the RGB and Clear color values of the reflected object that the sensor is &#8220;looking&#8221; at. Initially, I tried a simple linear matrix equation to map the input RGBC values to RGBy output numbers. I then took the highest output value&hellip;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jacobncalvert.com\/blog-archive\/2016\/04\/16\/reliably-identifying-discrete-colors\/\" \/>\n<meta property=\"og:site_name\" content=\"Jacob N Calvert\" \/>\n<meta property=\"article:published_time\" content=\"2016-04-16T16:51:34+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2018-02-10T20:31:52+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/jacobncalvert.com\/wp-content\/uploads\/2018\/02\/first_matrix_approx-300x138.png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/#website\",\"url\":\"https:\/\/jacobncalvert.com\/blog-archive\/\",\"name\":\"Jacob N Calvert\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/jacobncalvert.com\/blog-archive\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/2016\/04\/16\/reliably-identifying-discrete-colors\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"http:\/\/jacobncalvert.com\/wp-content\/uploads\/2018\/02\/first_matrix_approx-300x138.png\",\"contentUrl\":\"http:\/\/jacobncalvert.com\/wp-content\/uploads\/2018\/02\/first_matrix_approx-300x138.png\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/2016\/04\/16\/reliably-identifying-discrete-colors\/#webpage\",\"url\":\"https:\/\/jacobncalvert.com\/blog-archive\/2016\/04\/16\/reliably-identifying-discrete-colors\/\",\"name\":\"Reliably identifying discrete colors from an RGB color sensor - Jacob N Calvert\",\"isPartOf\":{\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/2016\/04\/16\/reliably-identifying-discrete-colors\/#primaryimage\"},\"datePublished\":\"2016-04-16T16:51:34+00:00\",\"dateModified\":\"2018-02-10T20:31:52+00:00\",\"author\":{\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/#\/schema\/person\/f4b22a996d41bf09ed2bbe22912a8c8a\"},\"breadcrumb\":{\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/2016\/04\/16\/reliably-identifying-discrete-colors\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/jacobncalvert.com\/blog-archive\/2016\/04\/16\/reliably-identifying-discrete-colors\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/2016\/04\/16\/reliably-identifying-discrete-colors\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"item\":{\"@type\":\"WebPage\",\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/\",\"url\":\"https:\/\/jacobncalvert.com\/blog-archive\/\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"position\":2,\"item\":{\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/2016\/04\/16\/reliably-identifying-discrete-colors\/#webpage\"}}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/#\/schema\/person\/f4b22a996d41bf09ed2bbe22912a8c8a\",\"name\":\"Jacob\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/jacobncalvert.com\/blog-archive\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/64a2dd1c00cb39dfc19bb1204c87efbc?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/64a2dd1c00cb39dfc19bb1204c87efbc?s=96&d=mm&r=g\",\"caption\":\"Jacob\"},\"sameAs\":[\"https:\/\/jacobncalvert.com\"],\"url\":\"https:\/\/jacobncalvert.com\/blog-archive\/author\/jcalvert\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/posts\/96"}],"collection":[{"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/comments?post=96"}],"version-history":[{"count":1,"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/posts\/96\/revisions"}],"predecessor-version":[{"id":99,"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/posts\/96\/revisions\/99"}],"wp:attachment":[{"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/media?parent=96"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/categories?post=96"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jacobncalvert.com\/blog-archive\/wp-json\/wp\/v2\/tags?post=96"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}