Цветовая фильтрация изображений Scikit и изменение частей изображения в массив

Я хочу сделать оптическое распознавание меток с помощью scikit-image. Ищу 2 функции

Допустим, у меня есть изображение, которое выглядит так: OMR

Я бы обнаружил это с помощью фильтров для очистки изображения: (т.е. двусторонняя и гауссова фильтрация для шумовых пятен в модуле filter)

Затем я бы использовал шкалу серого в color модуле. В-третьих, я бы использовал хитрый детектор краев в filter модуле.

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

Я предполагаю, что есть какая-то функция для оттенков, насыщенности и яркости или RGB, которую можно использовать для фильтрации определенных цветов или чего-то, что можно использовать с k-means из scikit learn для фильтрации данных

Во-вторых, как мне преобразовать это изображение в массив данных numpy / pandas, который будет следующим:

[[1,2,0,2,0]
[0,1,1,0,1]
[0,0,1,2,0]]

Где красный - 1, синий - 2, а белый - 0. Я видел, как некоторые люди ставили линию, идущую вниз, но не знали, как она называется и доступна ли она в sk-образе.


person user3084006    schedule 09.02.2014    source источник
comment
Вы заранее знаете положение кругов?   -  person Stefan van der Walt    schedule 09.02.2014
comment
@StefanvanderWalt Нет, ты бы не стал. Позиции, которые вы знаете, будут черными кружками   -  person user3084006    schedule 09.02.2014


Ответы (1)


Следующий код использует пиковый детектор scikit-image, примененный к карте расстояний, вычисленной между изображением и значениями чистого красного и синего:

from skimage import io, color, img_as_float
from skimage.feature import corner_peaks, plot_matches

import matplotlib.pyplot as plt
import numpy as np

image = img_as_float(io.imread('colordots.jpg'))

black_mask = color.rgb2gray(image) < 0.1
distance_red = color.rgb2gray(1 - np.abs(image - (1, 0, 0)))
distance_blue = color.rgb2gray(1 - np.abs(image - (0, 0, 1)))

distance_red[black_mask] = 0
distance_blue[black_mask] = 0

coords_red = corner_peaks(distance_red, threshold_rel=0.9, min_distance=50)
coords_blue = corner_peaks(distance_blue, threshold_rel=0.9, min_distance=50)

f, ((ax0, ax1), (ax2, ax3)) = plt.subplots(2, 2, figsize=(15, 10))
ax0.imshow(image)
ax0.set_title('Input image')
ax1.imshow(image)
ax1.set_title('Marker locations')
ax1.plot(coords_red[:, 1], coords_red[:, 0], 'ro')
ax1.plot(coords_blue[:, 1], coords_blue[:, 0], 'bo')
ax1.axis('image')
ax2.imshow(distance_red, interpolation='nearest', cmap='gray')
ax2.set_title('Distance to pure red')
ax3.imshow(distance_blue, interpolation='nearest', cmap='gray')
ax3.set_title('Distance to pure blue')
plt.show()

Обнаружение цветных точек

person Stefan van der Walt    schedule 09.02.2014
comment
Какая у вас версия Skimage У меня в skimage.feature нет функции plot_matches - person user3084006; 09.02.2014
comment
У меня последняя версия. Проверьте skimage.__version__, чтобы увидеть свое - что это? Кстати, я понял, что мой метод определения расстояния до синего был немного грубоват. Намного лучше было бы использовать color.deltaE_* функции. - person Stefan van der Walt; 09.02.2014
comment
Я использую 0.93. Итак, для вашего кода я предполагаю, что происходит: вы сначала применяете маску только для черного. Затем вы применяете фильтры для каждого цвета, вычитая все, что не входит в их значение RGB, из 1. После этого вы добавляли черную маску в качестве границы для каждого цвета и использовали детектор углов, чтобы указать координаты того, где находится каждый элемент. - person user3084006; 09.02.2014
comment
Почти: я получил маску для подавления черных кругов, затем измерил расстояние от цветов изображения до красного и синего (здесь могут пригодиться функции color.deltaE_*, см., Например, stackoverflow.com/questions/21618252 /). Затем я нахожу пики на этих двух картах расстояний по отдельности, и это говорит мне, где находятся синие и красные точки. - person Stefan van der Walt; 09.02.2014
comment
Привет, отличный ответ. Я не понимаю, что делает эта строка: color.rgb2gray(1 - np.abs(image - (1, 0, 0))) как мы определяем кортежи (1, 0, 0) и (0, 0, 1)? - person partizanos; 07.06.2018
comment
(1, 0, 0) - чистый красный цвет, (0, 0, 1) - чистый синий цвет (изображения имеют формат с плавающей запятой, поэтому значения находятся в диапазоне от 0 до 1). - person Stefan van der Walt; 13.06.2018