Removing small contours and noises from a thresholded image in Python

Question:

Are there any methods or functions to remove small contours given an already thresholded image through OpenCV in Python? My aim is only letting the rectangles and soon separate these overlapped ones:

enter image description here

enter image description here

Asked By: korzuswolf

||

Answers:

If the blobs you are trying to remove are small compared to the blobs you want to keep, one way is to draw bounding boxes around the blobs and discard unwanted blobs using the area of the bounding box.

    cnts = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)
    cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
    rect_areas = []
    for c in cnts:
        (x, y, w, h) = cv2.boundingRect(c)
        rect_areas.append(w * h)
    avg_area = mean(rect_areas)
    for c in cnts:
        (x, y, w, h) = cv2.boundingRect(c)
        cnt_area = w * h
        if cnt_area < 0.5 * avg_area:
            img[y:y + h, x:x + w] = 0

Here I am removing blobs with area less than half of the average areas. You can set this value experimentally for the value you want.

Answered By: chamith mawela

One another approach that I have reached this morning complementing your one for the same problem and to contribute as well, evaluating by the condition of the contour area of the rectangle:

_,contours, hierarchy = cv2.findContours(closing, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
image_copy = image.copy()
for c in contours:
#Defining a condition to draw the contours, a number larger than/smaller than or between ranges
x = 5000.0
    if cv2.contourArea(c) > x:
        x, y, w, h = cv2.boundingRect(c)
        cv2.drawContours(image_copy, [c], 0, (0,255,0), 17)

I believe that must have other ones and better than this one that I have done to avoid to print determined contours also that I am looking for, and some short ones that I am trying to solve

Answered By: korzuswolf