My work:
At this point, I thought I could find it by using Hierarchical and Contours: Below is my work
for i in range (len( contours_region)): #I already have X,Y,W,H of the checkbox through
#print(i) #cv2.connectedComponentsWithStats
x = contours_region[i][0][1] #when detecting checkbox
x_1 = contours_region[i][2][1]
y = contours_region[i][0][0]
y_1 = contours_region[i][2][0]
image_copy= image.copy()
X,Y,W,H = contours_info[i]
cv2.drawContours(image_copy, [numpy.array([[[X,Y]],[[X+W,Y]],[[X+W,Y+H]],[[X,Y+H]]])], 0, (0,0,255),2)
gray = cv2.cvtColor(image_copy, cv2.COLOR_BGR2GRAY)
ret,bw = cv2.threshold(gray,220,255,cv2.THRESH_BINARY_INV)
contours,hierarchy = cv2.findContours(bw[x:x_1, y:y_1], cv2.RETR_CCOMP,1)
print('-----Hierarchy-----')
print(hierarchy)
print('-----Number of Contours : '+ str(len(contours)))
cv2.imshow('a', image_copy)
cv2.waitKey(0)
I got this result (some high contours, some high hierarchy)
-----Hierarchy----- [[[-1 -1 1 -1] [ 2 -1 -1 0] [ 3 1 -1 0] [ 4 2 -1 0] [ 5 3 -1 0] [ 6 4 -1 0] [ 7 5 -1 0] [-1 6 -1 0]]] -----Number of Contours : 8
Another result:
Low Contours, Low Hierarchy
-----Hierarchy----- [[[-1 -1 1 -1] [ 2 -1 -1 0] [-1 1 -1 0]]] -----Number of Contours : 3
However, it's not perfect some case where it's not ticked but still got a really high result
[[[-1 -1 1 -1] [ 2 -1 -1 0] [ 3 1 -1 0] [ 4 2 -1 0] [ 5 3 -1 0] [-1 4 -1 0]]] -----Number of Contours : 6
In general, After review the whole data, the gap is not convincing between ticked and not ticked. Around 30% of boxes, giving the wrong result. Therefore, really wish to have a better method.
you want to use check box, if that is the case, then you should use c1. getState() and not isSelected() you need RadioBox instead of CheckBox and then you can use the isSelected() method.
You can use the . prop() method or the :checked selector to check the status of a checkbox.
I think erode function help you. Use erosion to make the ticks bigger then count the non zero pixels. Here You can find the basics:
import cv2
import numpy as np
from google.colab.patches import cv2_imshow
img = cv2.imread("image.png");
cv2_imshow(img)
kernel = np.ones((3, 3), np.uint8)
better_image = cv2.erode(img,kernel)
cv2_imshow(better_image)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With