{"id":264,"date":"2016-06-17T13:51:10","date_gmt":"2016-06-17T11:51:10","guid":{"rendered":"http:\/\/zaven.co\/blog\/?p=264"},"modified":"2025-04-08T19:55:20","modified_gmt":"2025-04-08T17:55:20","slug":"opencv-advanced-android-development-light-source-detection","status":"publish","type":"post","link":"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/","title":{"rendered":"OpenCV in advanced Android development: light source detection"},"content":{"rendered":"<p>In the last Android development tutorial we\u2019ve covered <a href=\"http:\/\/zaven.co\/blog\/opencv-advanced-android-development-drawing-histogram\/\" target=\"_blank\" rel=\"noopener noreferrer\">drawing a histogram using OpenCV<\/a>. This time we\u2019ll show you <strong>how to detect light sources in an image<\/strong>. This feature comes in very handy when building an Android app that has to perform quality checks on user-generated photographs (e.g. sending documents for proof).<!--more--><\/p>\n<p><strong>Our goal is to find the light source point and draw there a circle in an Android app<\/strong>. The easiest way to get it done is to detect the localization where the greatest white pixel value is. We can do it by using the <strong><code>Core.minMaxLoc<\/code> method<\/strong>, which takes only one parameter &#8211; the array.<\/p>\n<p>In order to <em>detect light source with OpenCV in our Android application<\/em> we need to perform 4 steps:<\/p>\n<ol>\n<li>Read the bitmap<\/li>\n<li>Transform it to grayscale<\/li>\n<li>Apply Gaussian blur<\/li>\n<li>Calculate <code>maxLoc<\/code> by using the <code>minMaxLoc<\/code> method<\/li>\n<\/ol>\n<pre><code class=\"language-java\">\n    private void detectLight(Bitmap bitmap, double gaussianBlurValue) {\n        Mat rgba = new Mat();\n        Utils.bitmapToMat(bitmap, rgba);\n\n        Mat grayScaleGaussianBlur = new Mat();\n        Imgproc.cvtColor(rgba, grayScaleGaussianBlur, Imgproc.COLOR_BGR2GRAY);\n        Imgproc.GaussianBlur(grayScaleGaussianBlur, grayScaleGaussianBlur, new Size(gaussianBlurValue, gaussianBlurValue), 0);\n\n        Core.MinMaxLocResult minMaxLocResultBlur = Core.minMaxLoc(grayScaleGaussianBlur);\n        Imgproc.circle(rgba, minMaxLocResultBlur.maxLoc, 30, new Scalar(255), 3);\n\n        \/\/ Don't do that at home or work it's for visualization purpose.\n        Bitmap resultBitmap = Bitmap.createBitmap(rgba.cols(), rgba.rows(), Bitmap.Config.ARGB_8888);\n        Utils.matToBitmap(rgba, resultBitmap);\n        BitmapHelper.showBitmap(this, resultBitmap, detectLightImageView);\n\n        Bitmap blurryBitmap = Bitmap.createBitmap(grayScaleGaussianBlur.cols(), grayScaleGaussianBlur.rows(), Bitmap.Config.ARGB_8888);\n        Utils.matToBitmap(grayScaleGaussianBlur, blurryBitmap);\n        BitmapHelper.showBitmap(this, blurryBitmap, gaussianBlurImageView);\n\n    }\n<\/code><\/pre>\n<h2>Extract data and apply transformations<\/h2>\n<pre><code class=\"language-java\">\/\/ Covert our bitmap into an array\nMat rgba = new Mat();\nUtils.bitmapToMat(bitmap, rgba);\n\n\/\/ Convert our rgba array to greyscale by using Imgproc.cvtColor ()\n\/\/ Apply Gaussian blur (for the last one we recommend Imgproc.GaussianBlur()).\nMat grayScaleGaussianBlur = new Mat();\nImgproc.cvtColor(rgba, grayScaleGaussianBlur, Imgproc.COLOR_BGR2GRAY);\nImgproc.GaussianBlur(grayScaleGaussianBlur, grayScaleGaussianBlur, new Size(gaussianBlurValue, gaussianBlurValue), 0);\n<\/code><\/pre>\n<p><code>Imgproc.cvtColor<\/code> parameters:<\/p>\n<ul>\n<li><code>Mat scr<\/code> \u2013 the source array (in our case <code>rgba<\/code>)<\/li>\n<li><code>Mat dst<\/code> \u2013 the array in which we will save the result of the conversion (in our case <code>grayScaleGaussianBlur<\/code>)<\/li>\n<li><code>int code<\/code> \u2013 code identifying the type of conversion<\/li>\n<\/ul>\n<p><code>Imgproc.GaussianBlur <\/code>parameters:<\/p>\n<ul>\n<li><code>Mat scr<\/code> \u2013 source array<\/li>\n<li><code>Mat dst<\/code>\u2013 output array (the blurring result will be saved to it)<\/li>\n<li><code>Size ksize<\/code> \u2013 Gaussian kernel size. <code>ksize.width<\/code> and <code>ksize.height<\/code> can differ but they both must be positive and odd. Or, they can be zero&#8217;s and then they are computed from sigma<\/li>\n<li><code>double sigmaX<\/code> \u2013 Gaussian kernel standard deviation in X direction<\/li>\n<\/ul>\n<h2>Analyze the image and display the output<\/h2>\n<p><strong>By using the <code>Core.minLoc()<\/code> method we can calculate the brightest spot in our photo and draw a circle around it using <code>Imgproc.circle()<\/code>.<\/strong><\/p>\n<pre><code class=\"language-java\">\nCore.MinMaxLocResult minMaxLocResultBlur = Core.minMaxLoc(grayScaleGaussianBlur);\nImgproc.circle(rgba, minMaxLocResultBlur.maxLoc, 30, new Scalar(255), 3);\n\n<\/code><\/pre>\n<p>Finally, we display two pictures, one with the circle and the other one with the transformations applied (greyscale + blur).<\/p>\n<pre><code class=\"language-java\">\n\/\/ Don't do that at home or work it's for visualization purpose.\nBitmap resultBitmap = Bitmap.createBitmap(rgba.cols(), rgba.rows(), Bitmap.Config.ARGB_8888);\nUtils.matToBitmap(rgba, resultBitmap);\nBitmapHelper.showBitmap(this, resultBitmap, detectLightImageView);\n\nBitmap blurryBitmap = Bitmap.createBitmap(grayScaleGaussianBlur.cols(), grayScaleGaussianBlur.rows(), Bitmap.Config.ARGB_8888);\nUtils.matToBitmap(grayScaleGaussianBlur, blurryBitmap);\nBitmapHelper.showBitmap(this, blurryBitmap, gaussianBlurImageView);\n<\/code><\/pre>\n<p>This method may not be perfect, but the effects are really good and the built <em>Android application can detect the light<\/em> now.<\/p>\n<div id=\"attachment_272\" style=\"width: 410px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-272\" class=\"wp-image-272\" src=\"http:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/06\/opencv_light_detection-730x1298.png\" alt=\"opencv light source detection\"   srcset=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/06\/opencv_light_detection-730x1298.png 730w, https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/06\/opencv_light_detection.png 1080w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><p id=\"caption-attachment-272\" class=\"wp-caption-text\">OpenCV: light source detection<\/p><\/div>\n<hr>\n<p>A code sample that we\u2019ve used in a commercial Android application can be found on our <a href=\"https:\/\/github.com\/zavenco\/DigitalImageProcessing\/blob\/master\/app\/src\/main\/java\/co\/zaven\/digitalimageprocessing\/activities\/DetectLightActivity.java\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">GitHub page<\/a>.<\/p>\n<hr>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the last Android development tutorial we\u2019ve covered drawing a histogram using OpenCV. This time we\u2019ll show you how to detect light sources in an image. This feature comes in very handy when building an Android app that has to perform quality checks on user-generated photographs (e.g. sending documents for proof).<\/p>\n","protected":false},"author":11,"featured_media":275,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[56,5],"tags":[24,30,23,12,31,7,25],"class_list":["post-264","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-android-development","category-tutorials","tag-advanced-android-development","tag-android-app-builidnig","tag-android-application","tag-app-development","tag-light-source","tag-opencv","tag-opencv-in-android-studio-project"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.8.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>OpenCV Android Tutorial: light source detection | Zaven Blog<\/title>\n<meta name=\"description\" content=\"Detecting light sources in an image is useful when building an application, which must perform quality checks on user-generated photographs. Check it out!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"OpenCV Android Tutorial: light source detection | Zaven Blog\" \/>\n<meta property=\"og:description\" content=\"Detecting light sources in an image is useful when building an application, which must perform quality checks on user-generated photographs. Check it out!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/\" \/>\n<meta property=\"og:site_name\" content=\"Zaven Blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-06-17T11:51:10+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-04-08T17:55:20+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/06\/Roy_Thomson_Hall_glare-1.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1800\" \/>\n\t<meta property=\"og:image:height\" content=\"1200\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Slawomir Onyszko\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Slawomir Onyszko\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/\",\"url\":\"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/\",\"name\":\"OpenCV Android Tutorial: light source detection | Zaven Blog\",\"isPartOf\":{\"@id\":\"https:\/\/zaven.co\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/06\/Roy_Thomson_Hall_glare-1.jpg\",\"datePublished\":\"2016-06-17T11:51:10+00:00\",\"dateModified\":\"2025-04-08T17:55:20+00:00\",\"author\":{\"@id\":\"https:\/\/zaven.co\/blog\/#\/schema\/person\/54027190fa6219030f9c4705fa7e0168\"},\"description\":\"Detecting light sources in an image is useful when building an application, which must perform quality checks on user-generated photographs. Check it out!\",\"breadcrumb\":{\"@id\":\"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/#primaryimage\",\"url\":\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/06\/Roy_Thomson_Hall_glare-1.jpg\",\"contentUrl\":\"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/06\/Roy_Thomson_Hall_glare-1.jpg\",\"width\":1800,\"height\":1200,\"caption\":\"OpenCV in advanced Android development: light source detection\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/zaven.co\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"OpenCV in advanced Android development: light source detection\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/zaven.co\/blog\/#website\",\"url\":\"https:\/\/zaven.co\/blog\/\",\"name\":\"Zaven Blog\",\"description\":\"Software development blog. Generative AI, web &amp; mobile applications.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/zaven.co\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/zaven.co\/blog\/#\/schema\/person\/54027190fa6219030f9c4705fa7e0168\",\"name\":\"Slawomir Onyszko\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/zaven.co\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/4dc8884e2167c9cc97596c4b71c7c250?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/4dc8884e2167c9cc97596c4b71c7c250?s=96&d=mm&r=g\",\"caption\":\"Slawomir Onyszko\"},\"description\":\"S\u0142awek is our mobile developer who mostly takes care of creating Android applications. He is constantly enhancing his skills of advanced Android app development and he wants to share this knowledge via Zaven\u2019s blog. In his spare time S\u0142awek enjoys watching a good movie at the cinema.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/mronyszko\"],\"url\":\"https:\/\/zaven.co\/blog\/author\/slawekzaven-pl\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"OpenCV Android Tutorial: light source detection | Zaven Blog","description":"Detecting light sources in an image is useful when building an application, which must perform quality checks on user-generated photographs. Check it out!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/","og_locale":"en_US","og_type":"article","og_title":"OpenCV Android Tutorial: light source detection | Zaven Blog","og_description":"Detecting light sources in an image is useful when building an application, which must perform quality checks on user-generated photographs. Check it out!","og_url":"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/","og_site_name":"Zaven Blog","article_published_time":"2016-06-17T11:51:10+00:00","article_modified_time":"2025-04-08T17:55:20+00:00","og_image":[{"width":1800,"height":1200,"url":"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/06\/Roy_Thomson_Hall_glare-1.jpg","type":"image\/jpeg"}],"author":"Slawomir Onyszko","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Slawomir Onyszko","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/","url":"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/","name":"OpenCV Android Tutorial: light source detection | Zaven Blog","isPartOf":{"@id":"https:\/\/zaven.co\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/#primaryimage"},"image":{"@id":"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/#primaryimage"},"thumbnailUrl":"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/06\/Roy_Thomson_Hall_glare-1.jpg","datePublished":"2016-06-17T11:51:10+00:00","dateModified":"2025-04-08T17:55:20+00:00","author":{"@id":"https:\/\/zaven.co\/blog\/#\/schema\/person\/54027190fa6219030f9c4705fa7e0168"},"description":"Detecting light sources in an image is useful when building an application, which must perform quality checks on user-generated photographs. Check it out!","breadcrumb":{"@id":"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/#primaryimage","url":"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/06\/Roy_Thomson_Hall_glare-1.jpg","contentUrl":"https:\/\/zaven.co\/blog\/wp-content\/uploads\/2016\/06\/Roy_Thomson_Hall_glare-1.jpg","width":1800,"height":1200,"caption":"OpenCV in advanced Android development: light source detection"},{"@type":"BreadcrumbList","@id":"https:\/\/zaven.co\/blog\/opencv-advanced-android-development-light-source-detection\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/zaven.co\/blog\/"},{"@type":"ListItem","position":2,"name":"OpenCV in advanced Android development: light source detection"}]},{"@type":"WebSite","@id":"https:\/\/zaven.co\/blog\/#website","url":"https:\/\/zaven.co\/blog\/","name":"Zaven Blog","description":"Software development blog. Generative AI, web &amp; mobile applications.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/zaven.co\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/zaven.co\/blog\/#\/schema\/person\/54027190fa6219030f9c4705fa7e0168","name":"Slawomir Onyszko","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/zaven.co\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/4dc8884e2167c9cc97596c4b71c7c250?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4dc8884e2167c9cc97596c4b71c7c250?s=96&d=mm&r=g","caption":"Slawomir Onyszko"},"description":"S\u0142awek is our mobile developer who mostly takes care of creating Android applications. He is constantly enhancing his skills of advanced Android app development and he wants to share this knowledge via Zaven\u2019s blog. In his spare time S\u0142awek enjoys watching a good movie at the cinema.","sameAs":["https:\/\/www.linkedin.com\/in\/mronyszko"],"url":"https:\/\/zaven.co\/blog\/author\/slawekzaven-pl\/"}]}},"_links":{"self":[{"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/posts\/264","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/users\/11"}],"replies":[{"embeddable":true,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/comments?post=264"}],"version-history":[{"count":15,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/posts\/264\/revisions"}],"predecessor-version":[{"id":69807,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/posts\/264\/revisions\/69807"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/media\/275"}],"wp:attachment":[{"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/media?parent=264"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/categories?post=264"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zaven.co\/blog\/wp-json\/wp\/v2\/tags?post=264"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}