Как я могу использовать VIPS для нормализации изображения? - PullRequest
2 голосов
/ 01 ноября 2019

Я хочу нормализовать экспозицию и цветовые палитры набора изображений. Для контекста, это для обучения нейронной сети в классификации изображений на медицинских изображениях. Я также делаю это для сотен тысяч изображений, поэтому эффективность очень важна.

До сих пор я использовал VIPS, в частности PyVIPS, и предпочел бы решение с использованием этой библиотеки. После нахождения этого ответа и просмотра документации я попытался

x = pyvips.Image.new_from_file('test.ndpi')
x = x.hist_norm()
x.write_to_file('test_normalized.tiff')

, но, похоже, всегда получается чисто белое изображение.

1 Ответ

2 голосов
/ 03 ноября 2019

Вам необходимо hist_equal для выравнивания гистограммы.

Основные документы здесь:

https://libvips.github.io/libvips/API/current/libvips-histogram.html

Однако это будет очень медленно для больших изображений слайдов,Для построения гистограммы потребуется один раз отсканировать весь слайд, а затем отсканировать еще раз, чтобы выровнять его. Было бы намного быстрее найти гистограмму слоя с низким разрешением, а затем использовать ее для выравнивания слоя с высоким разрешением.

Например:

#!/usr/bin/env python3

import sys
import pyvips

# open the slide image and get the number of layers ... we are not fetching 
# pixels, so this is quick
x = pyvips.Image.new_from_file(sys.argv[1])
levels = int(x.get("openslide.level-count"))

# find the histogram of the highest level ... again, this should be quick
x = pyvips.Image.new_from_file(sys.argv[1], 
                               level=levels - 1)
hist = x.hist_find()

# from that, compute the transform for histogram equalisation
equalise = hist.hist_cum().hist_norm()

# and use that on the full-res image
x = pyvips.Image.new_from_file(sys.argv[1])

x = x.maplut(equalise)

x.write_to_file(sys.argv[2])

Еще один фактор заключается в том, что гистограммаВыравнивание нелинейно, поэтому оно искажает отношения легкости. Это также может исказить цветовые отношения и заставить шумы и артефакты сжатия выглядеть сумасшедшими. Я попробовал эту программу на изображении, которое у меня здесь:

$ ~/try/equal.py bild.ndpi[level=7] y.jpg

enter image description here

Полосы взяты из слайд-сканера и ужасные полосы от сжатия.

Я думаю, что вместо этого я найду максимальное и минимальное изображения на уровне низкого разрешения, а затем использую их для простого линейного растягивания значений пикселей.

Что-то вроде:

x = pyvips.Image.new_from_file(sys.argv[1])
levels = int(x.get("openslide.level-count"))
x = pyvips.Image.new_from_file(sys.argv[1],
                               level=levels - 1)
mn = x.min()
mx = x.max()
x = pyvips.Image.new_from_file(sys.argv[1])
x = (x - mn) * (256 / (mx - mn))
x.write_to_file(sys.argv[2])

Нашли ли вы новую функцию Region в pyvips? Это делает генерацию патчей для обучения НАМНОГО быстрее, в некоторых случаях до 100 раз быстрее:

https://github.com/libvips/pyvips/issues/100#issuecomment-493960943

...