#python #opencv #image-processing #document
#python #opencv #обработка изображений #документ
Вопрос:
Мне нужно найти самую большую пустую область в документе и отобразить ее координаты, центральную точку и область, используя python для размещения там QR-кода. Я думаю, что OpenCV и Numpy должно быть достаточно для этой задачи.
- Какой ПОРОГ использовать? Потому что существует много типов сканирований: серое, BW, с цветом, и как правильно найти контур?
- Как это можно реализовать самым быстрым способом? Прилагается пример с использованием первого сканирования из Google, где вы можете видеть, что код должен найти самую большую пустую квадратную область.
@Mark Setchell Спасибо! Этот код отлично работает для всех документов с белым фоном, но когда я использую что-то с цветом на заднем плане, он находит совершенно другую область. Кроме того, чтобы сохранить тонкие линии в документах, я использовал Erode после порогового значения. Пытался изменить пороговое значение и параметры erode, все еще не работает должным образом. Отредактированный пост, добавлены цветные картинки.
Комментарии:
1. Квадраты нечетной формы в вашей части мира 😉
2. @MarkSetchell это просто пример 🙂
3. Это может раздражать людей, которые отвечают, когда вопрос неоднозначен или образцы изображений не являются репрезентативными, потому что вы тратите время на основе неверных предположений. В вашем заголовке предлагается найти самую большую область (форма не указана), в вашем тексте запрашивается квадрат, а на вашей диаграмме показан прямоугольник — как минимум 2 очень разных вопроса / ответа.
Ответ №1:
Вот возможный подход:
#!/usr/bin/env python3
import cv2
import numpy as np
def largestSquare(im):
# Make image square of 100x100 to simplify and speed up
s = 100
work = cv2.resize(im, (s,s), interpolation=cv2.INTER_NEAREST)
# Make output accumulator - uint16 is ok because...
# ... max value is 100x100, i.e. 10,000 which is less than 65,535
# ... and you can make a PNG of it too
p = np.zeros((s,s), np.uint16)
# Find largest square
for i in range(1, s):
for j in range(1, s):
if (work[i][j] > 0 ):
p[i][j] = min(p[i][j-1], p[i-1][j], p[i-1][j-1]) 1
else:
p[i][j] = 0
# Save result - just for illustration purposes
cv2.imwrite("result.png",p)
# Work out what the actual answer is
ind = np.unravel_index(np.argmax(p, axis=None), p.shape)
print(f'Location: {ind}')
print(f'Length of side: {p[ind]}')
# Load image and threshold
im = cv2.imread('page.png', cv2.IMREAD_GRAYSCALE)
_, thr = cv2.threshold(im,127,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)
# Get largest white square
largestSquare(thr)
Вывод
Location: (21, 77)
Length of side: 18
Примечания:
-
Я отредактировал вашу красную аннотацию, чтобы она не мешала моему алгоритму.
-
Я установил пороговое значение Otsu, чтобы получить чисто черно-белое — это может подходить или не подходить для вашего варианта использования. Это будет зависеть от ваших сканирований, фона бумаги и т. Д.
-
Я уменьшил изображение до 100×100, чтобы его запуск не занял весь день. Вам нужно будет масштабировать результаты обратно до размера вашего исходного изображения, но я предполагаю, что вы можете сделать это достаточно легко.
Ключевые слова: Обработка изображений, изображение, Python, OpenCV, самый большой белый квадрат, самое большое пустое пространство.
Комментарии:
1. Привет, Марк, ты опубликовал это несколько лет назад, и я только что наткнулся на это. Это было действительно полезно для меня и, кажется, работает очень хорошо. Одна из проблем, с которой я столкнулся, заключается в том, что при запуске вашей программы с исходным изображением OP, result.png — это просто черный квадрат. Это совсем не похоже на изображение результата выходного аккумулятора, которое вы опубликовали. У вас есть какие-либо идеи, почему это может быть? Спасибо 🙂