Quantcast
Channel: CodeSection,代码区,Python开发技术文章_教程 - CodeSec
Viewing all articles
Browse latest Browse all 9596

Detecting multiple bright spots in an image with Python and OpenCV

$
0
0

Detecting multiple bright spots in an image with Python and OpenCV

Today’s blog post is a followup to a tutorial I did a couple of years ago on finding the brightest spot in an image .

My previous tutorial assumed there was only one bright spot in the image that you wanted to detect…

…but what if there were multiple bright spots?

If you want to detect more than one bright spot in an image the code gets slightly more complicated, but not by much.No worries though: I’ll explain each of the steps in detail.

To learn how to detect multiple bright spots in an image, keep reading.

Looking for the source code to this post?

Jump right to the downloads section. Detecting multiple bright spots in an image with python and OpenCV

Normally when I do code-based tutorials on the PyImageSearch blog I follow a pretty standard template of:

Explaining what the problem is and how we are going to solve it. Providing code to solve the project. Demonstrating the results of executing the code.

This template tends to work well for 95% of the PyImageSearch blog posts, but for this one, I’m going to squashthe template together into a single step.

I feel that the problem of detecting the brightestregions of an image is pretty self-explanatory so I don’t need to dedicate an entire section to detailing the problem.

I also think that explaining each block of code followed by immediately showing the output of executing that respective block of code will help you better understand what’s going on.

So, with that said, take a look at the following image:


Detecting multiple bright spots in an image with Python and OpenCV

Figure 1:The example image that we are detecting multiple bright objects in using computer vision and image processing techniques ( source image ).

In this image we have five lightbulbs.

Our goal is to detect these five lightbulbs in the image and uniquely label them.

To get started, open up a new file and name it detect_bright_spots . py . From there, insert the following code:

# import the necessary packages from imutilsimport contours from skimageimport measure import numpyas np import argparse import imutils import cv2 # construct the argument parse and parse the arguments ap = argparse.ArgumentParser() ap.add_argument("-i", "--image", required=True, help="path to the image file") args = vars(ap.parse_args())

Lines 2-7import our required Python packages. We’ll be using scikit-image in this tutorial, so if you don’t already have it installed on your system be sure to follow these install instructions .

We’ll also be using imutils , my set of convenience functions used to make applying image processing operations easier.

If you don’t already have imutils installed on your system, you can use pip to install it for you:

$ pipinstallimutils

From there, Lines 10-13 parse our command line arguments. We only need a single switch here, -- image , which is the path to our input image.

To start detecting the brightest regions in an image, we first need to load our image from disk followed by converting it to grayscale and smoothing (i.e., blurring) it to reduce high frequency noise:

# load the image, convert it to grayscale, and blur it image = cv2.imread(args["image"]) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (11, 11), 0)

The output of these operations can be seen below:


Detecting multiple bright spots in an image with Python and OpenCV

Figure 2:Converting our image to grayscale and blurring it.

Notice how our image is now (1) grayscale and (2) blurred.

To reveal the brightest regions in the blurred image we need to apply thresholding:

# threshold the image to reveal light regions in the # blurred image thresh = cv2.threshold(blurred, 200, 255, cv2.THRESH_BINARY)[1]

This operation takes any pixel value p >= 200 and sets it to 255 (white). Pixel values < 200 are set to 0 (black).

After thresholding we are left with the following image:


Detecting multiple bright spots in an image with Python and OpenCV

Figure 3:Applying thresholding to reveal the brighter regions of the image.

Note how the bright areas of the image are now all white while the rest of the image is set to black.

However, there is a bit of noise in this image (i.e., small blobs), so let’s clean it up by performing a series of erosions and dilations:

# perform a series of erosions and dilations to remove # any small blobs of noise from the thresholded image thresh = cv2.erode(thresh, None, iterations=2) thresh = cv2.dilate(thresh, None, iterations=4)

After applying these operations you can see that our thresh image is much “cleaner”, although we do still have a few left over blobs that we’d like to exclude (we’ll handle that in our next step):


Detecting multiple bright spots in an image with Python and OpenCV

Figure 4:Utilizing a series of erosions and dilations to help “clean up” the thresholded image by removing small blobs and then regrowing the remaining regions.

The critical step in this project is to label each of the regions in the above figure; however, even after applying our erosions and dilations we’d still like to filter out any leftover “noisy” regions.

An excellent way to do this is to perform a connected-component analysis :

# perform a connected component analysis on the thresholded # image, then initialize a mask to store only the "large" # components labels = measure.label(thresh, neighbors=8, background=0) mask = np.zeros(thresh.shape, dtype="uint8") # loop over the unique components for labelin np.unique(labels): # if this is the background label, ignore it if label == 0: continue # otherwise, construct the label mask and count the # number of pixels labelMask = np.zeros(thresh.shape, dtype="uint8") labelMask[labels == label] = 255 numPixels = cv2.countNonZero(labelMask) # if the number of pixels in the component is sufficiently # large, then add it to our mask of "large blobs" if numPixels > 300: mask = cv2.add(mask, labelMask) Line 32performs the actual connected-component analysis using the scikit-image library. The labels variable returned from measure . label has the exact same dimensions as our thresh

Viewing all articles
Browse latest Browse all 9596

Trending Articles