{"id":1347,"date":"2021-12-13T16:45:02","date_gmt":"2021-12-13T16:45:02","guid":{"rendered":"https:\/\/salarydistribution.com\/machine-learning\/2021\/12\/13\/image-processing-the-simple-and-the-complex\/"},"modified":"2021-12-13T16:45:02","modified_gmt":"2021-12-13T16:45:02","slug":"image-processing-the-simple-and-the-complex","status":"publish","type":"post","link":"https:\/\/salarydistribution.com\/machine-learning\/2021\/12\/13\/image-processing-the-simple-and-the-complex\/","title":{"rendered":"Image Processing: The Simple and The Complex"},"content":{"rendered":"<div>\n<p>We\u2019ve seen in the past several blog posts on how you\u00a0can learn simple image classifiers with BigML, via the <a href=\"https:\/\/blog.bigml.com\/2021\/12\/01\/building-a-simple-image-classifier-on-the-bigml-dashboard\/\">interface<\/a>, the <a href=\"https:\/\/blog.bigml.com\/2021\/12\/07\/programming-image-processing\/\">API<\/a>, and with the <a href=\"https:\/\/blog.bigml.com\/2021\/12\/09\/automating-machine-learning-with-images\/\">BigML Python Bindings<\/a>, and we\u2019ve also seen that you can <a href=\"https:\/\/blog.bigml.com\/2021\/12\/03\/ml-in-manufacturing-detecting-defects-with-unsupervised-learning-and-image-feature-extraction\/\">train unsupervised models<\/a> on the same images. But let\u2019s dig a little deeper and explore different approaches to an image processing problem.<\/p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" data-attachment-id=\"30300\" data-permalink=\"https:\/\/blog.bigml.com\/bigml_image_complex_rrss\/\" data-orig-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/bigml_image_complex_rrss.jpg\" data-orig-size=\"1200,630\" data-comments-opened=\"1\" data-image-meta='{\"aperture\":\"0\",\"credit\":\"\",\"camera\":\"\",\"caption\":\"\",\"created_timestamp\":\"0\",\"copyright\":\"\",\"focal_length\":\"0\",\"iso\":\"0\",\"shutter_speed\":\"0\",\"title\":\"\",\"orientation\":\"0\"}' data-image-title=\"bigml_image_complex_rrss\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/bigml_image_complex_rrss.jpg?w=300\" data-large-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/bigml_image_complex_rrss.jpg?w=810\" src=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/bigml_image_complex_rrss.jpg?w=1024\" alt=\"\" class=\"wp-image-30300\"><\/figure>\n<p>One of the things we try hard to do at BigML is, to paraphrase Alan Kay, <strong>make simple things simple and complex things possible<\/strong>.\u00a0It\u2019s a relatively simple thing to train an image classifier:\u00a0You have a bunch of images, those images have classes, and you want to train a model that will classify any new image into one of those classes.<\/p>\n<p>One great application of this is the area of security and monitoring:\u00a0You have a system constantly looking at something and you want to be alerted when that thing changes.\u00a0For example, you have a security camera looking at a room, and you\u2019d like to be alerted when a person enters.<\/p>\n<p>This problem has a lot of variations.\u00a0One of these, used by a client of BigML, is to monitor a surface for changes of a specific type.\u00a0For example, if a person is shooting at a target, we\u2019d like to flag changes in the image of the target that corresponds to new holes in the surface and reject any other changes.<\/p>\n<h2 id=\"the-only-constant-is-change\">The Only Constant is Change<\/h2>\n<p>To sense a change in the image, a simple approach is to use a form of image differencing, where (again, in its simplest form) you subtract the gray-level values of each pixel in the current frame of video from a \u201creference image\u201d (say, an image where you know there\u2019s nothing in it) and take the absolute value.\u00a0Differences between the two images will show up as white pixels, and everything that\u2019s the same will be black.\u00a0Try it, and you\u2019ll see that this is very effective at the classic children\u2019s activity, \u201cFind the differences between these pictures\u201d:<\/p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" data-attachment-id=\"30264\" data-permalink=\"https:\/\/blog.bigml.com\/screen-shot-2021-12-10-at-10-45-36-am-1\/\" data-orig-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/screen-shot-2021-12-10-at-10.45.36-am-1.png\" data-orig-size=\"1748,648\" data-comments-opened=\"1\" data-image-meta='{\"aperture\":\"0\",\"credit\":\"\",\"camera\":\"\",\"caption\":\"\",\"created_timestamp\":\"0\",\"copyright\":\"\",\"focal_length\":\"0\",\"iso\":\"0\",\"shutter_speed\":\"0\",\"title\":\"\",\"orientation\":\"0\"}' data-image-title=\"screen-shot-2021-12-10-at-10.45.36-am-1\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/screen-shot-2021-12-10-at-10.45.36-am-1.png?w=300\" data-large-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/screen-shot-2021-12-10-at-10.45.36-am-1.png?w=810\" src=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/screen-shot-2021-12-10-at-10.45.36-am-1.png?w=1024\" alt=\"\" class=\"wp-image-30264\"><figcaption>I missed the grandmother\u2019s collar!<\/figcaption><\/figure>\n<p>While it\u2019s easy and effective to use image differencing to find unfamiliar things in images, it\u2019s also easy to imagine cases where changes in the image correspond to something other than the thing you\u2019re looking for:\u00a0The camera may move slightly, things may blow in the wind, lighting may change, things like debris or small animals may dance through the field of view, and so on.\u00a0So we get a classic image classification problem.\u00a0In summary, we have images that show a difference between the current scene and the reference, and those images have two classes:\u00a0differences we care about and differences we don\u2019t.<\/p>\n<p>In the case of this target surface monitoring problem, as a first filter, we convolve the difference image with a hole-shaped filter and only flag areas of the image that \u201ccould be\u201d a hole. For each of these, we capture a 32\u00d732 close-up image of the difference of the current surface image with the \u201creference surface image\u201d in the video.\u00a0<\/p>\n<p>Most of these correspond to small movements of either the camera or the surface itself, which causes the image to align slightly differently with the reference, and thereby show differences around high-contrast areas of the reference image:<\/p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" data-attachment-id=\"30269\" data-permalink=\"https:\/\/blog.bigml.com\/screen-shot-2021-12-10-at-10-58-50-am-3\/\" data-orig-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/screen-shot-2021-12-10-at-10.58.50-am-3.png\" data-orig-size=\"1778,520\" data-comments-opened=\"1\" data-image-meta='{\"aperture\":\"0\",\"credit\":\"\",\"camera\":\"\",\"caption\":\"\",\"created_timestamp\":\"0\",\"copyright\":\"\",\"focal_length\":\"0\",\"iso\":\"0\",\"shutter_speed\":\"0\",\"title\":\"\",\"orientation\":\"0\"}' data-image-title=\"screen-shot-2021-12-10-at-10.58.50-am-3\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/screen-shot-2021-12-10-at-10.58.50-am-3.png?w=300\" data-large-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/screen-shot-2021-12-10-at-10.58.50-am-3.png?w=810\" src=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/screen-shot-2021-12-10-at-10.58.50-am-3.png?w=1024\" alt=\"\" class=\"wp-image-30269\"><figcaption>Differences due to camera shake or slight movements in the scene<\/figcaption><\/figure>\n<p>But some of the differences are clearly holes:<\/p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" data-attachment-id=\"30271\" data-permalink=\"https:\/\/blog.bigml.com\/screen-shot-2021-12-10-at-10-58-39-am-1\/\" data-orig-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/screen-shot-2021-12-10-at-10.58.39-am-1.png\" data-orig-size=\"1802,550\" data-comments-opened=\"1\" data-image-meta='{\"aperture\":\"0\",\"credit\":\"\",\"camera\":\"\",\"caption\":\"\",\"created_timestamp\":\"0\",\"copyright\":\"\",\"focal_length\":\"0\",\"iso\":\"0\",\"shutter_speed\":\"0\",\"title\":\"\",\"orientation\":\"0\"}' data-image-title=\"screen-shot-2021-12-10-at-10.58.39-am-1\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/screen-shot-2021-12-10-at-10.58.39-am-1.png?w=300\" data-large-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/screen-shot-2021-12-10-at-10.58.39-am-1.png?w=810\" src=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/screen-shot-2021-12-10-at-10.58.39-am-1.png?w=1024\" alt=\"\" class=\"wp-image-30271\"><figcaption>Differences due to an actual change in the surface of the target<\/figcaption><\/figure>\n<p>And there are some that are a bit ambiguous:<\/p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" data-attachment-id=\"30273\" data-permalink=\"https:\/\/blog.bigml.com\/screen-shot-2021-12-10-at-10-58-31-am-1\/\" data-orig-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/screen-shot-2021-12-10-at-10.58.31-am-1.png\" data-orig-size=\"1800,570\" data-comments-opened=\"1\" data-image-meta='{\"aperture\":\"0\",\"credit\":\"\",\"camera\":\"\",\"caption\":\"\",\"created_timestamp\":\"0\",\"copyright\":\"\",\"focal_length\":\"0\",\"iso\":\"0\",\"shutter_speed\":\"0\",\"title\":\"\",\"orientation\":\"0\"}' data-image-title=\"screen-shot-2021-12-10-at-10.58.31-am-1\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/screen-shot-2021-12-10-at-10.58.31-am-1.png?w=300\" data-large-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/screen-shot-2021-12-10-at-10.58.31-am-1.png?w=810\" src=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/screen-shot-2021-12-10-at-10.58.31-am-1.png?w=1024\" alt=\"\" class=\"wp-image-30273\"><figcaption>A bit of both<\/figcaption><\/figure>\n<h2 id=\"the-simple\">The Simple<\/h2>\n<p>So, Machine Learning!\u00a0Labeling all of these gives you a pretty straightforward dataset.\u00a0The validation predictions on the trained classifier, while not a substitute for a proper evaluation, suggest that deep learning can more than handle this job.<\/p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" data-attachment-id=\"30275\" data-permalink=\"https:\/\/blog.bigml.com\/image-28\/\" data-orig-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/image.png\" data-orig-size=\"1930,1430\" data-comments-opened=\"1\" data-image-meta='{\"aperture\":\"0\",\"credit\":\"\",\"camera\":\"\",\"caption\":\"\",\"created_timestamp\":\"0\",\"copyright\":\"\",\"focal_length\":\"0\",\"iso\":\"0\",\"shutter_speed\":\"0\",\"title\":\"\",\"orientation\":\"0\"}' data-image-title=\"image\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/image.png?w=300\" data-large-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/image.png?w=810\" src=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/image.png?w=1024\" alt=\"\" class=\"wp-image-30275\"><\/figure>\n<p>So we\u2019re all done, right? Dust off our hands and go get a beer? Maybe.\u00a0But also, maybe you have 10 cameras running, and this all has to run in real-time.\u00a0Now what?\u00a0Go out and grab 10 GPUs?\u00a0If you\u2019ve got that kind of money, that\u2019s great, but I sure don\u2019t. Moreover, by doing this you\u2019re volunteering to deal with the nightmare maintenance problems that come with having 10 different machines to keep running, network together, and so on.<\/p>\n<p>Wouldn\u2019t it be nice if we could make this happen all on one machine? All we need is for things to run ten times faster! How hard could that be?<\/p>\n<h2 id=\"and-the-complex\">. . . and the Complex<\/h2>\n<p>Deep learning works very nicely for these sorts of image processing problems. But there are a few other things that work <strong>pretty nicely<\/strong> and are <strong>way faster<\/strong>. For example, by default, BigML extracts \u201chistogram of gradients\u201d features for both the whole image and several sub-windows. If you train any model besides a Deepnet on this data, it will use these extracted features as inputs. When you\u2019re configuring your composite image source, you can change the type of features that are extracted:<\/p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" data-attachment-id=\"30288\" data-permalink=\"https:\/\/blog.bigml.com\/image-6-3\/\" data-orig-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/image-6.png\" data-orig-size=\"1962,1240\" data-comments-opened=\"1\" data-image-meta='{\"aperture\":\"0\",\"credit\":\"\",\"camera\":\"\",\"caption\":\"\",\"created_timestamp\":\"0\",\"copyright\":\"\",\"focal_length\":\"0\",\"iso\":\"0\",\"shutter_speed\":\"0\",\"title\":\"\",\"orientation\":\"0\"}' data-image-title=\"image-6\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/image-6.png?w=300\" data-large-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/image-6.png?w=810\" src=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/image-6.png?w=1024\" alt=\"\" class=\"wp-image-30288\"><figcaption>The image feature extraction options <\/figcaption><\/figure>\n<p>If you check the documentation, you\u2019ll see that some of those features encode the color information from the image, some encode the texture information, but the histogram of gradients encodes primarily edge and shape information. That seems pretty relevant for this problem, so we\u2019ll train a Logistic Regression using those features and do an evaluation:<\/p>\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" data-attachment-id=\"30281\" data-permalink=\"https:\/\/blog.bigml.com\/image-3-4\/\" data-orig-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/image-3.png\" data-orig-size=\"2056,1364\" data-comments-opened=\"1\" data-image-meta='{\"aperture\":\"0\",\"credit\":\"\",\"camera\":\"\",\"caption\":\"\",\"created_timestamp\":\"0\",\"copyright\":\"\",\"focal_length\":\"0\",\"iso\":\"0\",\"shutter_speed\":\"0\",\"title\":\"\",\"orientation\":\"0\"}' data-image-title=\"image-3\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/image-3.png?w=300\" data-large-file=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/image-3.png?w=810\" src=\"https:\/\/littleml.files.wordpress.com\/2021\/12\/image-3.png?w=1024\" alt=\"\" class=\"wp-image-30281\"><\/figure>\n<p>It\u2019s very good, but not <em>quite<\/em> as good as the Deepnet. Overall, it\u2019s about 98% accurate, which isn\u2019t enough for this application. More importantly though, as we can see, at 100% recall for the positive class, we\u2019re at 73.3% precision, while only predicting 10% of the total instances to be positive. This means that using this classifier, we\u2019re able to reject 9\/10 images with near-100% confidence, leaving only the \u201cpotentially positive\u201d 1\/10 images to be passed to the other classifier.<\/p>\n<p>This is important because the logistic model with the histogram of gradients features is way, way faster than a full Deepnet. <\/p>\n<pre class=\"wp-block-code\"><code>$ gradle test --tests *timeTest*\n\n&gt; Task :test\n\ncom.bigml.deepnet.ResourceTest &gt; timeTest STANDARD_OUT\n\n    Deepnet time per image: 120.58 msec.\n    Logistic time per image: 0.69 msec.\nResults: SUCCESS (1 tests, 1 successes, 0 failures, 0 skipped)<\/code><\/pre>\n<p>We see that on a (commodity) laptop, the logistic model runs 120.58 \/ 0.69 = about 175x faster than the deepnet.  Since 9\/10 images never have to see the full Deepnet, and only see this much faster model, we get near 10x speedup without sacrificing any accuracy.<\/p>\n<p>This example highlights one of the best things about BigML, not just for image processing, but on the platform in general. While other Machine Learning solutions focus on letting you optimize and monitor individual models, BigML allows you to combine the Lego pieces of the platform to solve complex problems that can\u2019t be solved by single models alone. With the ultimate goal of building efficient solutions top of mind, when the simple is not enough, BigML always has the complex ready and waiting on the sidelines.<\/p>\n<h2 id=\"do-you-want-to-know-more-about-image-processing\">Do you want to know more about Image Processing?<\/h2>\n<p>Please\u00a0<a rel=\"noreferrer noopener\" href=\"https:\/\/bigml.com\/releases\/image-processing\" target=\"_blank\"><strong>visit the dedicated release page<\/strong><\/a>\u00a0and<strong>\u00a0join the FREE live webinar on Wednesday, December 15 at 8:30 AM PST \/ 10:30 AM CST \/ 5:30 PM CET.<\/strong>\u00a0<strong><a href=\"https:\/\/attendee.gotowebinar.com\/register\/3316692637331486991\" target=\"_blank\" rel=\"noreferrer noopener\">Register today,<\/a><\/strong>\u00a0<strong>space is limited!<\/strong><\/p>\n<div id=\"jp-post-flair\" class=\"sharedaddy sharedaddy-dark sd-like-enabled sd-sharing-enabled\">\n<div class=\"sharedaddy sd-block sd-like jetpack-likes-widget-wrapper jetpack-likes-widget-unloaded\" id=\"like-post-wrapper-30283844-30255-61b77870ede13\" data-src=\"\/\/widgets.wp.com\/likes\/index.html?ver=20211208#blog_id=30283844&amp;post_id=30255&amp;origin=littleml.wordpress.com&amp;obj_id=30283844-30255-61b77870ede13&amp;domain=blog.bigml.com\" data-name=\"like-post-frame-30283844-30255-61b77870ede13\" data-title=\"Like or Reblog\">\n<h3 class=\"sd-title\">Like this:<\/h3>\n<p><span class=\"button\"><span>Like<\/span><\/span> <span class=\"loading\">Loading&#8230;<\/span><\/p>\n<p><span class=\"sd-text-color\"><\/span><a class=\"sd-link-color\"><\/a><\/div>\n<h3 class=\"jp-relatedposts-headline\"><em>Relacionado<\/em><\/h3>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>https:\/\/blog.bigml.com\/2021\/12\/13\/image-processing-the-simple-and-the-complex\/<\/p>\n","protected":false},"author":0,"featured_media":1348,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts\/1347"}],"collection":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/comments?post=1347"}],"version-history":[{"count":0,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts\/1347\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/media\/1348"}],"wp:attachment":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/media?parent=1347"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/categories?post=1347"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/tags?post=1347"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}