Я должен построить алгоритм, который берет изображение RBG и возвращает изображение, превращенное в древовидную мозаику. Для этого мне дали образцы древесных таблеток, как показано на рисунке ниже:
Я хотел бы знать, как я могу нормализовать цвета каждого планшета, что приводит к одному цвету, поэтому я могу построить карту эталонных цветов для преобразования цветов входных изображений.
Я искал, как это сделать, но я нашел статью в Википедии, но я не мог понять ее.
Заранее спасибо за любую помощь, которую вы могли бы мне предоставить.
PS: Я рассматриваю возможность использования Python для его разработки. Поэтому, если вы придумаете что-то, сделанное с использованием этого языка, я бы очень признателен.
Способ получения среднего цвета - просто взять среднее значение RGB.
Чтобы получить более точное среднее значение, вы должны сделать это с линейными значениями цвета. Обычно RGB использует гамма-скорректированное значение, но вы можете легко отменить его, а затем повторить его, как только у вас будет среднее значение. Вот как вы это сделаете с Python PIL, используя гамма 2.2:
def average_color(sample):
pix = sample.load()
totals = [0.0, 0.0, 0.0]
for y in range(sample.size[1]):
for x in range(sample.size[0]):
color = pix[x,y]
for c in range(3):
totals[c] += color[c] ** 2.2
count = sample.size[0] * sample.size[1]
color = tuple(int(round((totals[c] / count) ** (1/2.2))) for c in range(3))
return color
Для образца в левом верхнем углу ваших примеров результат (144, 82, 66). Вот визуальное из них:
Один тривиальный способ нормализовать цвета - просто заставить среднее и стандартное отклонение значений RGB во всех изображениях одинаковыми.
Ниже приведен пример с двумя панелями в верхней части левого столбца в примере изображения. Я использую MATLAB с DIPimage 3.0, потому что это то, что я знаю, но это достаточно тривиально для реализации на Python с помощью NumPy или любого другого желаемого языка/библиотеки:
img = readim('https://i.stack.imgur.com/HK6VY.png')
tab1 = dipcrop; % Interactive cropping of a tile from the displayed image
tab2 = dipcrop;
m1 = mean(tab1);
s1 = std(tab1);
m2 = mean(tab2);
s2 = std(tab2);
tab2b = (tab2 - m2) ./ s2 .* s1 + m1;
То, что код делает на tab2
изображения2, по каждому каналу, вычитает среднее значение и делит на стандартное отклонение. Затем он умножает каждый канал на стандартное отклонение соответствующего канала изображения шаблона и добавляет среднее значение этого канала.
Чтобы сделать один цвет изображением плитки, простым вариантом было бы найти средний цвет случайной выборки пикселей в определенном фрагменте. Вы можете выбрать подходящий размер выборки как компромисс между скоростью и точностью.
Для вашего конкретного случая использования я бы рекомендовал дальнейшее разделение плиток, скажем, на 3 столбца (из-за конструкции сверху вниз большинства деревянных панелей). Найдите средний цвет каждого столбца и устраните все, что выходит за рамки определенной дисперсии. Это делается для того, чтобы гарантировать, что плитки, такие как самые правые в четвертой строке, не отображаются на более темный оттенок.
Альтернативный подход состоял бы в том, чтобы преобразовать как ваше входное изображение, так и эти деревянные плитки в и выполнить вашу обработку в оттенках серого. Библиотека opencv
имеет различные простые функции для конверсий RGB2GRAY
.