#python #python-imaging-library
Вопрос:
У меня есть куча отсканированных страниц из книг, и мне нужен автоматический способ определить, должна ли страница быть битональной tiff или цветной jp2. Если страница состоит только из текста и черно-белых диаграмм, она будет преобразована в битовый формат tiff. Если на странице есть цветное изображение, или подсветка, или что-то еще, то это будет цветной jp2. У меня есть несколько примеров:
Комментарии:
1. Пожалуйста, отредактируйте вопрос, чтобы ограничить его конкретной проблемой с достаточной детализацией для определения адекватного ответа.
Ответ №1:
Я протестировал следующий наивный подход, основанный на правилах (код находится внизу). Что он делает, так это считывает изображение с помощью PIL
пакета , получает значения пикселей RGB
, и если абсолютная разница между R
и G
, R
и B
и G
и B
ниже 35 (которую я только что определил в качестве примера), она считается черно-белым пикселем в оттенках серого. В противном случае это был бы цветной пиксель. В моем подходе, основанном на правилах, если более 5% изображения состоит из цветных пикселей , то я считаю, что изображение является a color jp2
, иначе это a bitonal tiff
.
Я попробовал для ваших образцов изображений, и он неправильно классифицировал 5-битное изображение tiff (возможно, потому, что изображение немного желтое, поэтому вам нужно будет создать правило для них) и 2-цветное изображение jp2 (которое имеет действительно темные цвета, что может обмануть мое правило оттенков серого).:
Следование подходу, основанному на правилах, приведет вас к достаточно хорошим результатам, но может быть громоздким для учета всех случаев. С другой стороны, вы могли бы использовать модель машинного обучения под наблюдением, в которой вы загружаете ее с помощью меток (будь то изображение в формате tiff или цветное jp2) и RGB
вектора изображения, обучаете его и смотрите, дает ли оно хорошие результаты. Это, вероятно, не будет иметь 100% точности, но будет лучше, чем пытаться определить наилучший подход, основанный на правилах, вручную, хотя это будет больше работы. Теперь вам решать, насколько точным вы хотите быть.
from PIL import Image
def process_image(filename):
image = Image.open(filename)
width, height = image.size
pixel_grid = image.load()
colored_rgbs_count = 0
for i in range(width):
for j in range(height):
r, g, b = pixel_grid[i,j]
if abs(r - g) > 35 or abs(r - b) > 35 or abs(b - g) > 35:
colored_rgbs_count = 1
return 'color jp2' if colored_rgbs_count > width * height * 0.05 else 'bitonal tiff'
print(f'bitonal_1: {process_image("bitonal_1.jpg")}')
print(f'bitonal_2: {process_image("bitonal_2.jpg")}')
print(f'bitonal_3: {process_image("bitonal_3.jpg")}')
print(f'bitonal_4: {process_image("bitonal_4.jpg")}')
print(f'bitonal_5: {process_image("bitonal_5.jpg")}')
print(f'color_1: {process_image("color_1.jpg")}')
print(f'color_2: {process_image("color_2.jpg")}')
print(f'color_3: {process_image("color_3.jpg")}')
Комментарии:
1. Эй, спасибо за помощь и советы по машинному обучению. У меня нет никакого опыта в этом, так что мне может потребоваться немного времени, чтобы войти в курс дела. Я попробую этот код и, надеюсь, смогу настроить его достаточно для своих нужд.
2. Просто подумайте, сможет ли PIL перейти на 8-цветовую палитру с колебаниями «Байера»? Я использую XnConvert, и у него есть опция, которая может работать для этой тонированной страницы. Затем, основываясь на этих значениях, я задаюсь вопросом, может ли это быть более точным?