pythonopencvcontourimage-thresholding

Reg: Copy blob based on the area of the blob size


Objective: Copy the bigger blobs in another mask image

I have a threshold image with blobs as shown:

enter image description here

How could I copy the bigger blobs into a mask image and leave out the one-pixel blobs?

enter image description here

My code (but I am not getting the desired result):

import numpy as np
import cv2

ref_img = cv2.imread('threshold.jpg', 0)
thresh = np.copy(ref_img)
cnts,_ = cv2.findContours(ref_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
mask = np.zeros(ref_img.shape, dtype="uint8")
for c in cnts:
   (x,y),radius = cv2.minEnclosingCircle(c)
   area = cv2.contourArea(c)
   if int(area) < 1:
      cv2.circle(mask, (int(x), int(y)), int(radius), (255, 255, 255), -1)

cv2.imshow('img', mask)
cv2.waitKey(0)

Note: Using OpenCV 2.4.x


Solution

  • Here is one of the method you can use to achieve your goal. Explanations are provided in the comments of the code

    import numpy as np
    import cv2
    
    ref_img = cv2.imread('threshold.jpg', 0)
    
    
    img, cnts,_ = cv2.findContours(ref_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    mask = np.zeros(ref_img.shape, dtype="uint8")
    for c in cnts:
       # Get the bounding rect surrounding your blobs
       x,y,w,h = cv2.boundingRect(c) 
    
       # Calculating the area of the rect is similar to the area of the blob minus the complexity
       area = w*h
    
       # For box area bigger than one, copy the information from the source image to the mask. 
       # Since the bounding box contains all the relevant information, just copy the entire box to the mask.
       if int(area) > 1 :
        mask[y:y+h,x:x+w] = ref_img[y:y+h,x:x+w]
    
    
    
    
    cv2.imshow('img', mask)
    cv2.waitKey(0)