Предполагая, что ответы характеризуются в основном заполненными кружками, я бы просто суммировал все значения пикселей по строкам.Затем разделите вектор повторной выборки на пять частей, каждая из которых представляет суммированные значения для одного из параметров, и усредните значения интенсивности в этих окнах.Окно с наименьшей средней интенсивностью будет тогда выбранным ответом (темные цвета = значения низкой интенсивности).
Я приведу пример фрагмента кода для определения одного ответа:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Read image
img = cv2.imread('images/p4I1m.png', cv2.IMREAD_GRAYSCALE)
# Sum intensity values row-wise
sum = np.sum(img, axis=0)
plt.plot(sum)
plt.show()
# Set up answers
nAnswers = 5
answers = []
# Calculate mean intensity value for each answer option using a simple windowed, moving average with displacement
step = int(np.floor(sum.size / nAnswers))
for i in range(nAnswers):
answers.append(np.mean(sum[i*step:(i+1)*step-1]))
print(answers)
# Find minimum mean intensity
answer = np.argmin(answers)
print(answer)
# TODO: Mapping from indices (0, 1, ...) to ('A', 'B', ...)
Выводучастка:
Выход answers
:
[2225.0, 2227.5454545454545, 2252.909090909091, 2246.0, 1449.3636363636363]
Выход answer
:
4
Я пропустил отображение из результата np.argmin
во что-то вроде A, B и т. Д.
Теперь необходимы дальнейшие улучшения:
- Пустые ответы:Все средние значения будут одинаковыми.Вам понадобится какой-то порог для проверки «заполнено» или «не заполнено».
- Несколько ответов: более одного среднего значения будет значительно больше, чем другие.Опять же, пороги могут быть лучшим вариантом для различия между «заполненным» или «не заполненным».
Пошаговое суммирование должно быть устойчивым к повороту до определенной степени.
Надеюсь, это поможет!