Нужно считать объекты на белом фоне в Python, тени вызывают проблемы

Этот вопрос является своего рода продолжением моих двух предыдущих вопросов: images-wit/28031400#28031400">Руководство по Python Image работает, другие изображения ведут себя по-другому (показ изображений с помощью Pylab) и Обнаружение объектов на белом фоне в Python .

Я пытаюсь добиться возможности программно подсчитать количество отдельных объектов на белом фоне. Как видно из двух других сообщений, мне удалось добиться этого в некоторой степени. В этот момент я могу подсчитать количество объектов, когда на изображении практически нет тени. Изображение, которое я пытаюсь проанализировать (внизу этого поста), имеет некоторые тени, из-за которых объекты сливаются и рассматриваются как один отдельный объект.

Мне нужен простой способ избавиться от теней, я уже пробовал адаптивную пороговую настройку с помощью scikit-image (http://scikit-image.org/docs/dev/auto_examples/plot_threshold_adaptive.html#example-plot-threshold-adaptive-py), но Я столкнулся с некоторыми проблемами (https://imgur.com/uYnj6af). Есть ли какой-нибудь не слишком сложный способ заставить это работать? В моих предыдущих сообщениях уже было много кода, но, пожалуйста, дайте мне знать, если вы хотите увидеть какой-либо дополнительный код!

Заранее спасибо.

введите здесь описание изображения


person E. V. d. B.    schedule 20.01.2015    source источник


Ответы (1)


Возможно, проще работать с бинарным изображением. В приведенном ниже коде я получаю такое изображение, вычисляя дисперсию по скользящему окну и определяя ее порогом.

Двоичная карта порога дисперсии

from skimage import io, exposure, color, util
import matplotlib.pyplot as plt

image = color.rgb2gray(io.imread('tools.jpg'))

exposure.equalize_adapthist(image)
Z = util.view_as_windows(image, (5, 5))
Z = Z.reshape(Z.shape[0], Z.shape[1], -1)
variance_map = Z.var(axis=2)

plt.imshow(variance_map > 0.005, cmap='gray')
plt.savefig('tools_thresh.png')

plt.show()

Обновление:

введите здесь описание изображения

Эта расширенная версия кода идентифицирует 8 инструментов.

from skimage import io, exposure, color, util, measure, morphology
from scipy import ndimage as ndi
import numpy as np
import matplotlib.pyplot as plt

image = color.rgb2gray(io.imread('tools.jpg'))

exposure.equalize_adapthist(image)
Z = util.view_as_windows(image, (5, 5))
Z = Z.reshape(Z.shape[0], Z.shape[1], -1)
variance_map = Z.var(axis=2)

tools_bw = variance_map > 0.005
tools_bw = morphology.binary_closing(tools_bw, np.ones((5, 5)))
tools_bw = ndi.binary_fill_holes(tools_bw)


labels = measure.label(tools_bw)
regions = measure.regionprops(labels)
regions = [r for r in regions if r.perimeter > 500 and r.major_axis_length > 200]

print(len(regions))

out = np.zeros_like(tools_bw, dtype=int)
for i, r in enumerate(regions):
    out[labels == r.label] = i + 1

plt.imshow(out, cmap='spectral')
plt.savefig('tools_identified.png', bbox_inches='tight')

plt.show()
person Stefan van der Walt    schedule 21.01.2015
comment
Выглядит хорошо, потому что sahdows практически исчезли, но я думаю, что все маленькие белые пятна будут рассматриваться как отдельные компоненты, и поэтому счет будет неверным, не так ли? сейчас попробую и отчитаюсь - person E. V. d. B.; 21.01.2015
comment
Как я и подозревал, все маленькие части воспринимаются как объекты, и я получаю счет 318. - person E. V. d. B.; 21.01.2015
comment
Ну, конечно, вам придется выполнить постобработку бинарного изображения, чтобы удалить их. - person Stefan van der Walt; 21.01.2015
comment
К сожалению, мои знания слишком ограничены, чтобы сделать это, я никогда раньше не работал с Python и никогда не занимался анализом изображений, поэтому все это для меня ново, но все равно спасибо за вашу помощь! - person E. V. d. B.; 21.01.2015