I am working on a problem that extracts rectangular boxes from image and sort those rectangular boxes sequentially. Code that I tried is:
import cv2
import matplotlib.pyplot as plt
# Load image, grayscale, adaptive threshold
image = cv2.imread('3.jpg')
result = image.copy()
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
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)
plt.imshow(thresh)
# Draw rectangles
cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnts = sorted(cnts, key=lambda x: [cv2.boundingRect(x)[1], cv2.boundingRect(x)[0]])
# cnts = sorted(cnts, key=lambda ctr: cv2.boundingRect(ctr)[0] + cv2.boundingRect(ctr)[1] * image.shape[1], reverse=True)
i = 0
for c in cnts:
area = cv2.contourArea(c)
# print("Area:", area)
x,y,w,h = cv2.boundingRect(c)
# cv2.rectangle(image, (x+8, y+8), (x + w-8, y + h-8), (36,255,12), 1)
roi = image[y:y+h, x:x+w]
cv2.imwrite('{}.jpg'.format(i), roi)
i += 1
cv2.imwrite('output_image.jpg', image)
cv2.imshow('thresh', thresh)
cv2.imshow('opening', opening)
cv2.imshow('image', image)
cv2.waitKey()
cv2.destroyAllWindows()
Image used to detect and extract contours: here. I want to extract the boxes containing numbers in order 1-2-3-4-5-6-7-----32. The above code extracts boxes in random order, sometimes from left-to-right and sometimes from right-to-left.
[Edited]
Images that yield contour in order 4-3-2-1 8-7-6-5...
1
2
Images that yield contour in order 1-2-3-4 5-6-7-8...
3
5