How can I draw a red circle around blobs detected in image?

find circles in image python
opencv detect circles in video
red circle detection opencv python
opencv blob detection
color blob detection opencv python
opencv ellipse detection
detect circles in image
find center of circle in image python

I have the following image:

I want to achieve 3 outcomes in the output:

  1. Highlight the black dots/patches in the image, with a red circular outline around them.
  2. Count the number of dots/patches
  3. Print the number of dots/patches overlaid on the image.

Right now, I can only count the number of dots/patches in the image and print it:

import cv2

## convert to grayscale
gray = cv2.imread("blue.jpg", 0)

## threshold
th, threshed = cv2.threshold(gray, 100, 255,cv2.THRESH_BINARY_INV|cv2.THRESH_OTSU)

## findcontours
cnts = cv2.findContours(threshed, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[-2]

## filter by area
s1= 3
s2 = 20
xcnts = []
for cnt in cnts:
    if s1<cv2.contourArea(cnt) <s2:

print("Number of dots: {}".format(len(xcnts)))
>>> Number of dots: 66

But I am not able to figure out how to highlight the patches on the image.

EDIT: Expected results for the following image:

would be this:

Here are some approaches:

1. Color Thresholding

The idea is to convert the image to HSV format then define a lower and upper color threshold to isolate the desired color range. This results in a mask where we can find the contours on the mask with cv2.findContours() and draw the contours using cv2.drawContours()

import numpy as np
import cv2

# Color threshold
image = cv2.imread('1.jpg')
original = image.copy()
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 127])
upper = np.array([179, 255, 255])
mask = cv2.inRange(hsv, lower, upper)
result = cv2.bitwise_and(original,original,mask=mask)

# Find blob contours on mask
cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(original,[c], -1, (36,255,12), 2)

cv2.imshow('result', result)
cv2.imshow('original', original)

2. Simple Thresholding

The idea is to threshold and obtain a binary mask. Similarly, to highlight the patches in the image, we use cv2.drawContours(). To determine the number of colonies, we keep a counter while iterating through the contours. Finally, to print the number of patches onto the image, we use cv2.putText()

Colonies: 11

import numpy as np
import cv2

image = cv2.imread('2.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.medianBlur(gray, 5)
thresh = cv2.threshold(blur,100,255,cv2.THRESH_BINARY_INV)[1]

cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
colonies = 0
for c in cnts:
    cv2.drawContours(image, [c], -1, (36,255,12), 2)
    colonies += 1

print("Colonies:", colonies)
cv2.putText(image, 'Colonies: {}'.format(colonies), (0, image.shape[0] - 15), \
        cv2.FONT_HERSHEY_SIMPLEX, 0.8, (36,255,12), 2)

cv2.imshow('thresh', thresh)
cv2.imshow('image', image)

Color thresholding to detect the blue blobs would also work

lower = np.array([0, 0, 0])
upper = np.array([179, 255, 84])

You can use this script to determine the HSV lower and upper color ranges

import cv2
import sys
import numpy as np

def nothing(x):

# Load in image
image = cv2.imread('1.jpg')

# Create a window

# create trackbars for color change
cv2.createTrackbar('HMin','image',0,179,nothing) # Hue is from 0-179 for Opencv

# Set default value for MAX HSV trackbars.
cv2.setTrackbarPos('HMax', 'image', 179)
cv2.setTrackbarPos('SMax', 'image', 255)
cv2.setTrackbarPos('VMax', 'image', 255)

# Initialize to check if HSV min/max value changes
hMin = sMin = vMin = hMax = sMax = vMax = 0
phMin = psMin = pvMin = phMax = psMax = pvMax = 0

output = image
wait_time = 33


    # get current positions of all trackbars
    hMin = cv2.getTrackbarPos('HMin','image')
    sMin = cv2.getTrackbarPos('SMin','image')
    vMin = cv2.getTrackbarPos('VMin','image')

    hMax = cv2.getTrackbarPos('HMax','image')
    sMax = cv2.getTrackbarPos('SMax','image')
    vMax = cv2.getTrackbarPos('VMax','image')

    # Set minimum and max HSV values to display
    lower = np.array([hMin, sMin, vMin])
    upper = np.array([hMax, sMax, vMax])

    # Create HSV Image and threshold into a range.
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower, upper)
    output = cv2.bitwise_and(image,image, mask= mask)

    # Print if there is a change in HSV value
    if( (phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
        print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
        phMin = hMin
        psMin = sMin
        pvMin = vMin
        phMax = hMax
        psMax = sMax
        pvMax = vMax

    # Display output image

    # Wait longer to prevent freeze for videos.
    if cv2.waitKey(wait_time) & 0xFF == ord('q'):


Find Circles and Ellipses in an Image using OpenCV, The centers in the blob detection are found less accurately compared to those in the ground truth and some centers are not found (e.g. red circles in Figure 3). Ground truth and circles around detected fiber centers (a) Ground truth. (b) MRF. To identify circles, ellipses or in general any shape in which the pixels are connected we use the SimpleBlobDetector() function of OpenCV. In non-technical terms, a blob is understood as a thick liquid drop. Here, we are going to call all shapes as a blob. Our task is to detect and recognize whether the blob is a circle or not.

drawContours(), convexHull() or minEnclosingCircle() should work with what you want. Here is a tutorial from opencv that shows how to do what you want to do:

OpenCV has a lot of great tutorials so check them first when you want to learn something new :)

Image Analysis: 19th Scandinavian Conference, SCIA 2015, , HoughCircles function to effortlessly detect circles in images. A few days ago, I got an email from a PyImageSearch reader asking about circle detection. We draw the actual detected circle on Line 28 using the Our Python script has detected the red circle, outlined it in green, and then  From the many possible approaches to the problem of red circles detection, two seem straightforward: Detect all circles from the input image and keep only the ones that are filled with red. Threshold the input image in order to keep only the red pixels, search for circles in the result.

As Mr. @alkasm said, you can use cv2.drawContours(). So, you can add the following at the end of your code:

image = cv2.imread("blue.jpg")
cv2.drawContours(image, cnts,
        contourIdx = -1, 
        color = (0, 255, 0), #green
        thickness = 5)
cv2.imshow('Contours', image) 

Now, the image will look like this:

Detecting Circles in Images using OpenCV and Hough Circles , The detected blobs are displayed as red circles. The blob's size is Blob detection based on circular image region for a scene with a large viewpoint change. centers contains the locations of circle centers and radii contains the estimated radii of those circles. Step 5: Draw the Circles on the Image. The function viscircles can be used to draw circles on the image. Output variables centers and radii from imfindcircles can be passed directly to viscircles.

Towards a Common Software/Hardware Methodology for Future Advanced , In order to detect the circles, or any other geometric shape, we first need to For instance, the edge of a red ball on a white background is a circle. Draw in black and white the magnitude Either add a float around v or switch to python 3. $ python --image images/simple.png We’ll start with something simple, detecting a red circle on a black background: Figure 1: Detecting a simple circle in an image using OpenCV. Not bad! Our Python script has detected the red circle, outlined it in green, and then placed an orange square at the center of it.

How to Detect Circles in Images, A Blob is a group of connected pixels in an image that share some common property ( E.g grayscale 14, # Draw detected blobs as red circles. This tutorial explains simple blob detection using OpenCV. What is a Blob ? A Blob is a group of connected pixels in an image that share some common property ( E.g grayscale value ). In the image above, the dark connected regions are blobs, and the goal of blob detection is to identify and mark […]

Blob Detection Using OpenCV ( Python, C++ ), It's much more useful to say draw a box around the found face. Fornately SimpleCV To demostrate let's make a new circle, this time red on the simplecv logo. We found everything we need, all we have to do is to draw. Create new Mat of unsigned 8-bit chars, filled with zeros. It will contain all the drawings we are going to make (rects and circles).

  • use drawContours()
  • Please add a second, marked-up image showing the expected results. Thank you.
  • @MarkSetchell Edited to include an example output.
  • @Kristada673, the provided image will in gray-scale of course
  • How do I highlight smaller patches instead of bigger patches? Like this for example:…
  • Use cv2.contourArea() with a minimum/maximum threshold area. If the contour passes this filter then highlight it else ignore it. Something like maximum = 500, if cv2.contourArea(c) < maximum: then highlight
  • This opens 2 windows, one with the original image and a tracker for the threshold, and another for the highlighted circle. I wanted it in the same window - i.e., the original image with the patches highlighted.
  • Just draw the circles on the original image instead of using a drawing.
  • cv.drawContours(drawing, contours_poly, i, color), (int(centers[i][0]), int(centers[i][1])), int(radius[i]), color, 2) change drawing here to the name of your original image
  • This way, I get the highlights on the original image, but the tracker window is still separately appearing. How to get cv.createTrackbar() to create the trackbar in the same original window?
  • Do you want the trackbar? Or did you just copy all the code in the example? To add it to your original image you use source_window = 'Source' cv.namedWindow(source_window) cv.imshow(source_window, src) and then cv.createTrackbar('Canny thresh:', source_window, thresh, max_thresh, thresh_callback) and point them to the window you want the trackbar in. To avoid the other window to appear you just avoid creating or showing it.
  • Is there any way to adjust the threshold such that even the fainter dots are highlighted?
  • Check this link... hope this is what you want :)