Reputation: 129
I am trying to figure out the marked answer from a OMR Sheet. I have been able to spot the dark circle on the image(Please see the green square around it) but I am stuck now. How to find the exact numbers from the image. Here is the image :
I am expecting output in the following format : 2,3,0,4,0,5,0,0,1,0,1,0,0.
I don't want to compare it with any answer key. I only want the output in the above format.
This is what I have done so far :
for contour in questionCnts:
# Calculate the area of the contour
area = cv2.contourArea(contour)
# If the area is above a certain threshold, consider it as a marked bubble
if area > 100: # Adjust the threshold based on your specific bubble size
# Calculate the centroid of the contour
moments = cv2.moments(contour)
centroid_x = int(moments['m10'] / moments['m00'])
centroid_y = int(moments['m01'] / moments['m00'])
# Add the centroid coordinates to the list of marked bubbles
marked_bubbles.append((centroid_x, centroid_y))
# Print the coordinates of the marked bubbles
for bubble in marked_bubbles:
print(f"Marked bubble at coordinates: {bubble}")
# Draw circles at the coordinates of the marked bubbles on the image
draw = ImageDraw.Draw(image)
for bubble in marked_bubbles:
if(bubble == (1, 1)):
continue
draw.rectangle([(bubble[0] - 10, bubble[1] - 10), (bubble[0] + 10, bubble[1] + 10)], outline='green')
# Save the modified image
image.save('/content/output_image.png')
Marked bubble at coordinates: (279, 11)
Marked bubble at coordinates: (346, 11)
Marked bubble at coordinates: (13, 28)
Marked bubble at coordinates: (46, 45)
Marked bubble at coordinates: (113, 61)
Marked bubble at coordinates: (179, 78)
Marked bubble at coordinates: (413, 161)
Marked bubble at coordinates: (379, 161)
Marked bubble at coordinates: (312, 161)
Marked bubble at coordinates: (246, 161)
Marked bubble at coordinates: (213, 161)
Marked bubble at coordinates: (146, 161)
Marked bubble at coordinates: (80, 161)
Any help will be grateful. Thanks a lot.
Edit : I have added the co-ordinates.
Edit 2 :
As suggested in the comments, I have updated the code. I am getting the values, but all of them are incorrect. Here is what I have done :
box_size = 38
# Iterating over the coordinates
for x, y in marked_bubbles:
# Determining the column based on the X value
column = int(x / box_size) + 1 # Addding 1 because index starts from 0
# Determine the score based on the quantized Y value of the box
score = int(y / box_size) # Rounding off to nearest integer
# Print the result
print(f"Centroid: ({x}, {y}), Column: {column}, Score: {score}")
I have tried playing around with box_size
value but its not giving correct. Here is the Output :
Centroid: (13, 28), Column: 1, Score: 0
Centroid: (46, 45), Column: 2, Score: 1
Centroid: (80, 161), Column: 3, Score: 4
Centroid: (113, 61), Column: 3, Score: 1
Centroid: (146, 161), Column: 4, Score: 4
Centroid: (179, 78), Column: 5, Score: 2
Centroid: (213, 161), Column: 6, Score: 4
Centroid: (246, 161), Column: 7, Score: 4
Centroid: (279, 11), Column: 8, Score: 0
Centroid: (312, 161), Column: 9, Score: 4
Centroid: (346, 11), Column: 10, Score: 0
Centroid: (379, 161), Column: 10, Score: 4
Centroid: (413, 161), Column: 11, Score: 4
Is my implementation correct ? Or Am I missing something ? Thanks.
Upvotes: -1
Views: 582
Reputation: 15573
Here you go. It's not even geometry, just moving numbers around. Feed the center of a mark in this function, not its left edge.
num_columns = 13
def column_from_x(x):
return int(x/image_width * num_columns + 1.0)
You can easily apply the same idea to identifying the position of a bubble in its column.
Upvotes: 0