I have the picture below.
I want to find the the black colored rectangles on the left using opencv. Thanks for help=)
Asked
Active
Viewed 5,400 times
1 Answers
7
Here's a simple approach using thresholding + morphological operations.
Obtain binary image. Load image, convert to grayscale, then adaptive threshold
Fill rectangular contours. Find contours and fill the contours to create filled rectangular blocks.
Perform morph open. We create a rectangular structuring element and morph open to remove the lines
Draw rectangles around largest rectangles Find contours and draw bounding rectangles around rectangles with an area above a certain treshold.
Here's each step visualized:
Obtain binary image
Adaptive treshold
Filled rectangular contours
Perform morph open
Draw rectangles around largest rectangles
In code:
import numpy as np
import cv2
#load the image
image = cv2.imread("mtF6y.jpg")
# grayscale
result = image.copy()
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
# adaptive threshold
thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,51,9)
# Fill rectangular contours
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:
cv2.drawContours(thresh, [c], -1, (255,255,255), -1)
# Morph open
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=4)
# Draw rectangles, the 'area_treshold' value was determined empirically
cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
area_treshold = 4000
for c in cnts:
if cv2.contourArea(c) > area_treshold :
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 3)
cv2.imshow('thresh', thresh)
cv2.imshow('opening', opening)
cv2.imshow('image', image)
cv2.waitKey()

BioGeek
- 21,897
- 23
- 83
- 145