Title: Finding the Brightest Spot in an Image using OpenCV

URL Source: https://pyimagesearch.com/2014/09/29/finding-brightest-spot-image-using-python-opencv/

Published Time: 2014-09-29T14:00:33+00:00

Markdown Content:
[![Image 1](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20241'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2014/08/bright-area-retina-noise.jpg)

Originally I had intended on doing a followup post on my [Getting Started with Deep Learning Guide](https://pyimagesearch.com/2014/09/22/getting-started-deep-learning-python/), but due to some unfortunate personal events, I wasn’t able to complete the blog post. But don’t worry…I still have a really great tutorial for you today!

* * *

Bad tutorials are worse than warm beer.

You want to know why?

Because you can always chug a warm beer down in a few seconds…

But you can spend **_hours_** going down the wrong path when reading a misguiding tutorial.

And that’s my inspiration for this post — I really hate all the blog posts I’ve seen that detail how to find the brightest spot of an image using OpenCV.

You see, they are leaving out a _single line of code_ that is absolutely crucial to being more robust to noise.

Now, if you’re like me, that doesn’t sit well.

So sit back. Relax. And know that you’re about to read a good tutorial. You won’t spend hours wasting your time here.

In this blog post I’ll show you how to find the brightest spot in an image using Python and OpenCV…and I’ll show you the single line of pre-processing code you’ll need to improve your results.

![Image 2](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20128%20128'%3E%3C/svg%3E)

#### Looking for the source code to this post?

[Jump Right To The Downloads Section](#download-the-code)

**OpenCV and Python versions:**  
This example will run on **Python 2.7/Python 3.4+** and **OpenCV 2.4.X/OpenCV 3.0+**.

You Need More than `cv2.minMaxLoc`
----------------------------------

A few weeks ago a PyImageSearch reader wrote in and asked about the best way to find the brightest spot in the image.

You see, they were working with retinal images (see the top of this post for an example). These images are normally orange or yellowish in color, circular, and contain important physical structures of the eye, including the optic nerve and the macula.

This reader wanted to know the best way to find the optic nerve center, which is normally the brightest spot of the retinal image.

To find the brightest spot of the image using Python and OpenCV, you would utilize the `cv2.minMaxLoc` function.

However, the term “spot” here is a little misleading.

The “brightest spot” of the image according to `cv2.minMaxLoc` actually isn’t a region — _it’s simply the brightest single pixel in the **entire** image._

This means that the `cv2.minMaxLoc` function is extremely susceptible to noise if you don’t take the necessary pre-cautionary steps. A single bright pixel in an area where there wouldn’t normally be a bright pixel (in this case, an area other than the optic nerve center) can dramatically throw off your results.

Instead, you are better off examining _regions_ of the image, rather than a single pixel. When you examine regions you let the average balance everything out — and you’re less susceptible to noise.

So how do you mimic this “region” effect without explicitly examining each and every region of the image?

I’ll show you.

The rest of this blog post is dedicated to showing you how to find the brightest spot of an image using Python and OpenCV

Let’s go ahead and get started.

Open up your favorite editor, create a new file named `bright.py` , and let’s get started.

\# import the necessary packages
import numpy as np
import argparse
import cv2

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add\_argument("-i", "--image", help = "path to the image file")
ap.add\_argument("-r", "--radius", type = int,
	help = "radius of Gaussian blur; must be odd")
args = vars(ap.parse\_args())

# load the image and convert it to grayscale
image = cv2.imread(args\["image"\])
orig = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR\_BGR2GRAY)

On **Lines 2-4** we’ll import the packages we’ll need. If you’re a regular PyImageSearch reader, these packages should feel like old hat to you now. We’ll use NumPy for numerical processing, `argparse` to parse command line arguments, and `cv2` for our OpenCV bindings.

From there, we’ll parse our command line arguments on **Lines 7-11**. Nothing too special here.  
The first switch, `--image` , is the path to the image we are going to find the brightest spot in. The second switch `--radius` , is an integer indicating the radius of the Gaussian blur we are going to apply to the image.

It’s important to note that this radius value must be _odd_ and **not** _even._

Next up, lets go ahead and load the image on **Line 14**, make a clone of it on **Line 15**, and convert it to grayscale on **Line 15**.

The Susceptible Method:
-----------------------

Now, let’s go ahead and apply the suspectible method method to detecting the brightest spot in the image:

\# perform a naive attempt to find the (x, y) coordinates of
# the area of the image with the largest intensity value
(minVal, maxVal, minLoc, maxLoc) = cv2.minMaxLoc(gray)
cv2.circle(image, maxLoc, 5, (255, 0, 0), 2)

# display the results of the naive attempt
cv2.imshow("Naive", image)

The susceptible method to finding the brightest spot in an image is to use the `cv2.minMaxLoc` function **_without any pre-processing_**. This function requires a single argument, which is our grayscale image. Then, this function takes our grayscale image and finds the value and _(x, y)_ location of the pixel with the smallest and largest intensity values, respectively.

To break it down: `minVal` contains the smallest pixel intensity value, `maxVal` contains the largest pixel intensity value, `minLoc` specifies the _(x, y)_ coordinates of minVal, and `maxLoc` specifies the _(x, y)_ coordinates of `maxLoc` .

In this application, we’re only concerned with the pixel with the largest value, so we’ll grab that and draw a circle around the region on **Line 20** and display it on **Line 24**.

The biggest problem with this method, and why I call it the susceptible method to find the brightest spot in an image, is that it’s **_extremely_** susceptible to noise.

A single pixel could dramatically throw off your results…

So how do we fix this?

Simple.

We’ll apply a Gaussian blurring through a pre-processing step.

The Slightly More Robust Method:
--------------------------------

Let’s go ahead and check out how to do this:

\# import the necessary packages
import numpy as np
import argparse
import cv2

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add\_argument("-i", "--image", help = "path to the image file")
ap.add\_argument("-r", "--radius", type = int,
	help = "radius of Gaussian blur; must be odd")
args = vars(ap.parse\_args())

# load the image and convert it to grayscale
image = cv2.imread(args\["image"\])
orig = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR\_BGR2GRAY)

# perform a naive attempt to find the (x, y) coordinates of
# the area of the image with the largest intensity value
(minVal, maxVal, minLoc, maxLoc) = cv2.minMaxLoc(gray)
cv2.circle(image, maxLoc, 5, (255, 0, 0), 2)

# display the results of the naive attempt
cv2.imshow("Naive", image)

# apply a Gaussian blur to the image then find the brightest
# region
gray = cv2.GaussianBlur(gray, (args\["radius"\], args\["radius"\]), 0)
(minVal, maxVal, minLoc, maxLoc) = cv2.minMaxLoc(gray)
image = orig.copy()
cv2.circle(image, maxLoc, args\["radius"\], (255, 0, 0), 2)

# display the results of our newly improved method
cv2.imshow("Robust", image)
cv2.waitKey(0)

Like I mentioned above, using `cv2.minMaxLoc` without any pre-processing can leave you extremely susceptible to noise.

Instead, it’s better to first apply a Gaussian blur to the image to remove high frequency noise. This way, even pixels that have very large values (again, due to noise) will be averaged out by their neighbors.

On **Line 28** we apply our Gaussian blur with the supplied radius from our command line argument.

Then we once again make a call to `cv2.minMaxLoc` to find the brightest pixel in the image.

However, since we have applied a blurring pre-processing step, we’ve averaged all pixels together with the supplied `radius` of each other. Doing this allows us to remove high frequency noise and leaves `cv2.minMaxLoc` substantially less susceptible.

By using a _larger_ radius we’ll be averaging over a larger neighborhood of pixels — thus mimicking larger regions of the image.

And by using a _smaller_ radius we can average over smaller regions.

Determining the correct radius will heavily dependent on the application you are developing and the task you are trying to solve.

Results
-------

Fire up a terminal and execute the following command:

$ python bright.py --image retina.png --radius 41

If all goes well, you should see the following image:

[![Image 3: Figure 1: Detecting the brightest area of a retinal image using our naive and robust methods. The results are good and look quite similar.](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20243'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2014/08/bright-area-retina.jpg)

**Figure 1:** Detecting the brightest area of a retinal image using our naive and robust methods. The results are good and look quite similar.

On the _left_ we have the susceptible method using `cv2.minMaxLoc` **_without_** any pre-processing and on the _right_ we have the robust method.

But you’re probably looking at these images and saying, _“Hey Adrian, they both detected the same region of the image!”_

You’re right. They did.

But watch what happens when I add a single bright pixel to the top-center part of this image when you issue this command:

$ python bright.py --image images/retina-noise.png --radius 41

Your results should look something like:

[![Image 4: Figure 2: Adding a single white pixel to the image has thrown off the results of cv2.minMaxLoc (left), but the robust method is still able to easily find the optic center.](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20241'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2014/08/bright-area-retina-noise.jpg)

**Figure 2:** Adding a single bright pixel to the image has thrown off the results of cv2.minMaxLoc without any pre-processing (_left_), but the robust method is still able to easily find the optic center (_right_).

Now, the naive `cv2.minMaxLoc`  method finds this white pixel. Let’s be clear. The function is working correctly. It is indeed finding the single brightest pixel in the entire image.

However, this really isn’t what we want.

We are interested in the brightest **_region_** of the image, which is the optic nerve center.

Luckily, by utilizing a Gaussian blur, we are able to average a neighborhood of pixels within a given radius, and thus discard the single bright pixel and narrow in on the optic center region without an issue.

Obviously, a big aspect of getting the robust method to work correctly is properly setting your `radius`   size. If your `radius`  size is too small, you won’t be able to find larger, brighter regions of the image.

But if you set the `radius`   size too large, then you’ll be detecting too large of regions, missing out on the smaller ones, leading to sub-par results.

Definitely spend some time playing with the `radius`  size and viewing the results.

### What's next? We recommend [PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/?utm_source=blogPost&utm_medium=bottomBanner&utm_campaign=What%27s%20next%3F%20I%20recommend).

**Course information:**  
84 total classes • 114+ hours of on-demand code walkthrough videos • Last updated: February 2024  
★★★★★ 4.84 (128 Ratings) • 16,000+ Students Enrolled

**I strongly believe that if you had the right teacher you could _master_ computer vision and deep learning.**

Do you think learning computer vision and deep learning has to be time-consuming, overwhelming, and complicated? Or has to involve complex mathematics and equations? Or requires a degree in computer science?

That’s _not_ the case.

All you need to master computer vision and deep learning is for someone to explain things to you in _simple, intuitive_ terms. _And that’s exactly what I do_. My mission is to change education and how complex Artificial Intelligence topics are taught.

If you're serious about learning computer vision, your next stop should be PyImageSearch University, the most comprehensive computer vision, deep learning, and OpenCV course online today. Here you’ll learn how to _successfully_ and _confidently_ apply computer vision to your work, research, and projects. Join me in computer vision mastery.

**Inside PyImageSearch University you'll find:**

*   ✓ **84 courses** on essential computer vision, deep learning, and OpenCV topics
*   ✓ **84 Certificates** of Completion
*   ✓ **114+ hours** of on-demand video
*   ✓ **Brand new courses released _regularly_**, ensuring you can keep up with state-of-the-art techniques
*   ✓ **Pre-configured Jupyter Notebooks in Google Colab**
*   ✓ Run all code examples in your web browser — works on Windows, macOS, and Linux (no dev environment configuration required!)
*   ✓ Access to **centralized code repos for _all_ 536+ tutorials** on PyImageSearch
*   ✓ **Easy one-click downloads** for code, datasets, pre-trained models, etc.
*   ✓ **Access** on mobile, laptop, desktop, etc.

[Click here to join PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/?utm_source=blogPost&utm_medium=bottomBanner&utm_campaign=What%27s%20next%3F%20I%20recommend)

Summary
-------

In this blog post I showed you why it is critical to apply Gaussian blurring prior to finding the brightest spot in an image.

By applying a Gaussian blur, you are averaging the pixels within a given radius of each other together. Taking the average allows you to remove high frequency noise that would have otherwise thrown off the results of the `cv2.minMaxLoc`  function.

Be sure to explore appropriate values for the radius of Gaussian blur. If you take too small of a value, you’ll mitigate the effects of the average and miss out on the larger, brighter regions. But if your radius is too large, you won’t detect the small bright regions.

![Image 5](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20410%20567'%3E%3C/svg%3E)

#### Download the Source Code and FREE 17-page Resource Guide

Enter your email address below to get a .zip of the code and a **FREE 17-page Resource Guide on Computer Vision, OpenCV, and Deep Learning.** Inside you'll find my hand-picked tutorials, books, courses, and libraries to help you master CV and DL!