Сейчас я ломаю голову над всеми возможными способами облегчить EasyOCR или pytesseract точное чтение моей сетки ввода. Это было жестоко, и я потратил на это добрых два месяца время от времени, работая над уточнением и определением порогов, а также оптимизируя свое изображение для обработки. Мне еще предстоит переобучить свою собственную модель EasyOCR специально для Segoe-UI Sans (рассматриваемый шрифт), но теперь я пытаюсь просто замаскировать цифры на каждой плитке, что доставляет много проблем с распознаванием текста. Я также хочу в конечном итоге замаскировать весь фон (пространство между плитками) и в итоге получить сетку из белых букв 4х4 на черном фоне. Вот моя отправная точка, игнорируйте нарисованный на нем прямоугольник, и вот результат моей маски:
(РЕДАКТИРОВАТЬ только что понял, что этот кадр обрезки шаблона не является совпадающим с теми же цифрами, но Я считаю, что идея в любом случае одна и та же. Дайте мне знать, если вам нужен фактический шаблон соответствующей сетки 4x4)

[img]https:// i.sstatic.net/YufyWTx7.png[/img]
А вот моя функция, которая будет работать вне класса, если вы уберете самовызовы ООП, но она очень примитивна и понятна. прочитать:
Код: Выделить всё
def template_matching_crop(self):
if not self.scrot_path or not os.path.isfile(self.scrot_path):
raise ValueError("Invalid screenshot path")
# Read the screenshot image
img = cv.imread(self.scrot_path)
if img is None:
raise ValueError("Failed to read screenshot")
# Convert the image to grayscale for matching, etc. etc.
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
template = cv.imread(self.template_path, 0)
if template is None:
raise ValueError("Failed to read template")
res = cv.matchTemplate(img_gray, template, cv.TM_CCOEFF_NORMED)
_, max_val, _, max_loc = cv.minMaxLoc(res)
top_left = max_loc
h, w = template.shape
bottom_right = (top_left[0] + w, top_left[1] + h)
# ROI
cropped_region = img[top_left[1]:bottom_right[1], top_left[0]:bottom_right[0]]
# Convert the cropped region to grayscale, blur it, thresh
cropped_gray = cv.cvtColor(cropped_region, cv.COLOR_BGR2GRAY)
median_blur = cv.medianBlur(cropped_gray, 5)
_, thresh = cv.threshold(median_blur, 201, 255, cv.THRESH_BINARY)
# Find contours in the thresh
contours, _ = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
# Create a mask to blank out small contours, initialized to white (255)
mask = np.ones_like(cropped_gray) * 255
for contour in contours:
# Get the bounding box and area of conts
x, y, w, h = cv.boundingRect(contour)
area = cv.contourArea(contour)
# If the area is less than arbitrary N, mask it
if area < 180:
cv.drawContours(mask, [contour], 0, 0, -1)
plt.imshow(mask)
# This might be stupid
masked_cropped_region = cv.bitwise_or(cropped_gray, mask)
# Binarize the final image so the background (and mask) is white (255) and foreground is black (0)
_, cropped_region = cv.threshold(masked_cropped_region, 201, 255, cv.THRESH_BINARY)
final_image = cv.bitwise_not(cropped_region)
plt.imshow(final_image)
# Save the binarized cropped region, make my function whole within class, headbutt
processed_path = os.path.join(ASSETS + os.sep + "ocr" + os.sep + "cropped_region.png")
cv.imwrite(processed_path, final_image)
plt.show() #DEBUG
return cropped_region, processed_path
Подробнее здесь: https://stackoverflow.com/questions/790 ... wise-opera