Skip to content Skip to sidebar Skip to footer

Obtain Only External Contours In Image

I have this code, that draws contours in my image, but I need only the external contours: import cv2 import numpy as np camino= 'C:/Users/Usuario/Documents/Deteccion de Objetos/12

Solution 1:

Here's an approach using thresholding + morphological operations + contour filtering

First we convert to grayscale then Otsu's threshold for a binary image (left) then remove dotted lines using contour area filtering (right)

From here we perform morph close to remove the text then invert the image (left). We find contours and fill all contours smaller than a threshold to black (right)

Next we invert again and perform morph open with a large rectangle kernel to remove the small edges and spikes

Finally we find contours to get our result

import cv2

image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5,5), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Remove dotted lines
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    area = cv2.contourArea(c)
    if area < 5000:
        cv2.drawContours(thresh, [c], -1, (0,0,0), -1)

# Fill contours
close_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
close = 255 - cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, close_kernel, iterations=6)
cnts = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    area = cv2.contourArea(c)
    if area < 15000:
        cv2.drawContours(close, [c], -1, (0,0,0), -1)

# Smooth contours
close = 255 - close
open_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (20,20))
opening = cv2.morphologyEx(close, cv2.MORPH_OPEN, open_kernel, iterations=3)

# Find contours and draw result
cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(image, [c], -1, (36,255,12), 3)

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

Solution 2:

You can try flood fill combined with some morph operators.

Post a Comment for "Obtain Only External Contours In Image"