In the last Android development tutorial we’ve covered drawing a histogram using OpenCV. This time we’ll 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).
Our goal is to find the light source point and draw there a circle in an Android app. 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 Core.minMaxLoc
method, which takes only one parameter – the array.
In order to detect light source with OpenCV in our Android application we need to perform 4 steps:
- Read the bitmap
- Transform it to grayscale
- Apply Gaussian blur
- Calculate
maxLoc
by using theminMaxLoc
method
private void detectLight(Bitmap bitmap, double gaussianBlurValue) {
Mat rgba = new Mat();
Utils.bitmapToMat(bitmap, rgba);
Mat grayScaleGaussianBlur = new Mat();
Imgproc.cvtColor(rgba, grayScaleGaussianBlur, Imgproc.COLOR_BGR2GRAY);
Imgproc.GaussianBlur(grayScaleGaussianBlur, grayScaleGaussianBlur, new Size(gaussianBlurValue, gaussianBlurValue), 0);
Core.MinMaxLocResult minMaxLocResultBlur = Core.minMaxLoc(grayScaleGaussianBlur);
Imgproc.circle(rgba, minMaxLocResultBlur.maxLoc, 30, new Scalar(255), 3);
// Don't do that at home or work it's for visualization purpose.
Bitmap resultBitmap = Bitmap.createBitmap(rgba.cols(), rgba.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(rgba, resultBitmap);
BitmapHelper.showBitmap(this, resultBitmap, detectLightImageView);
Bitmap blurryBitmap = Bitmap.createBitmap(grayScaleGaussianBlur.cols(), grayScaleGaussianBlur.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(grayScaleGaussianBlur, blurryBitmap);
BitmapHelper.showBitmap(this, blurryBitmap, gaussianBlurImageView);
}
Extract data and apply transformations
// Covert our bitmap into an array
Mat rgba = new Mat();
Utils.bitmapToMat(bitmap, rgba);
// Convert our rgba array to greyscale by using Imgproc.cvtColor ()
// Apply Gaussian blur (for the last one we recommend Imgproc.GaussianBlur()).
Mat grayScaleGaussianBlur = new Mat();
Imgproc.cvtColor(rgba, grayScaleGaussianBlur, Imgproc.COLOR_BGR2GRAY);
Imgproc.GaussianBlur(grayScaleGaussianBlur, grayScaleGaussianBlur, new Size(gaussianBlurValue, gaussianBlurValue), 0);
Imgproc.cvtColor
parameters:
Mat scr
– the source array (in our casergba
)Mat dst
– the array in which we will save the result of the conversion (in our casegrayScaleGaussianBlur
)int code
– code identifying the type of conversion
Imgproc.GaussianBlur
parameters:
Mat scr
– source arrayMat dst
– output array (the blurring result will be saved to it)Size ksize
– Gaussian kernel size.ksize.width
andksize.height
can differ but they both must be positive and odd. Or, they can be zero’s and then they are computed from sigmadouble sigmaX
– Gaussian kernel standard deviation in X direction
Analyze the image and display the output
By using the Core.minLoc()
method we can calculate the brightest spot in our photo and draw a circle around it using Imgproc.circle()
.
Core.MinMaxLocResult minMaxLocResultBlur = Core.minMaxLoc(grayScaleGaussianBlur);
Imgproc.circle(rgba, minMaxLocResultBlur.maxLoc, 30, new Scalar(255), 3);
Finally, we display two pictures, one with the circle and the other one with the transformations applied (greyscale + blur).
// Don't do that at home or work it's for visualization purpose.
Bitmap resultBitmap = Bitmap.createBitmap(rgba.cols(), rgba.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(rgba, resultBitmap);
BitmapHelper.showBitmap(this, resultBitmap, detectLightImageView);
Bitmap blurryBitmap = Bitmap.createBitmap(grayScaleGaussianBlur.cols(), grayScaleGaussianBlur.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(grayScaleGaussianBlur, blurryBitmap);
BitmapHelper.showBitmap(this, blurryBitmap, gaussianBlurImageView);
This method may not be perfect, but the effects are really good and the built Android application can detect the light now.
A code sample that we’ve used in a commercial Android application can be found on our GitHub page.
Popular posts
From Hype to Hard Hats: Practical Use Cases for AI chatbots in Construction and Proptech.
Remember the multimedia craze in the early 2000s? It was everywhere, but did it truly revolutionize our lives? Probably not. Today, it feels like every piece of software is labeled "AI-powered." It's easy to dismiss AI chatbots in construction as just another tech fad.
Read moreFears surrounding external support. How to address concerns about outsourcing software development?
Whether you’ve had bad experiences in the past or no experience at all, there will always be fears underlying your decision to outsource software development.
Read moreWhat do you actually seek from external support? Identify what’s preventing you from completing a project on time and within budget
Let’s make it clear: if the capabilities are there, a project is best delivered internally. Sometimes, however, we are missing certain capabilities that are required to deliver said project in a realistic timeline. These may be related to skills (e.g. technical expertise, domain experience), budget (hiring locally is too expensive) or just capacity (not enough manpower). What are good reasons for outsourcing software development?
Read more