Мы планируем создавать фотографии мелких частиц с помощью микроскопа. Эти мелкие элементы имеют тенденцию быть выпуклыми и не должны соприкасаться друг с другом. Фон может быть немного зашумлен, но между фоном и элементами должен быть большой контраст (мы стремимся создавать изображения, как в примере). Я хотел бы извлечь все отдельные элементы, обрезать их и сохранить как отдельные изображения. Мне нужен инструмент, способный решить эту проблему и в тех случаях, когда граница между элементом и фоном менее определена.
После того, как я извлек все фотографии, я запускаю сценарий Matlab для каждого изображения.
Операционная система: желательно Linux, но можно и Windows.
Я предпочитаю, чтобы выбор был как можно более автоматическим (чтобы иметь возможность запускать алгоритм на сотнях изображений).
Образец изображения:
Вот программа Python 3, которая отличает пиксели объекта от пикселя, не являющегося объектом, просто устанавливая порог красного канала на 128.
import sys
from PIL import Image
orig = Image.open(sys.argv[1])
width = orig.width
height = orig.height
# The workspace will be a list of lists of bools, where True
# means an object pixel.
workspace = list(orig.getdata())
workspace = list(zip(*(workspace[i * width : (i + 1) * width] for i in range(height))))
workspace = [[r < 128 for r, _, _ in col] for col in workspace]
n_objects = 0
for x in range(width):
for y in range(height):
if workspace[x][y]:
n_objects += 1
# Start a bounding box at this pixel.
x1, x2, y1, y2 = x, x, y, y
# Try growing the bounding box in each direction,
# one pixel at a time, until none of the four
# directions will get us another object pixel.
while True:
if x1 > 0 and any(workspace[x1 - 1][yt ] for yt in range(y1, y2 + 1)): x1 -= 1
elif x2 < width - 1 and any(workspace[x2 + 1][yt ] for yt in range(y1, y2 + 1)): x2 += 1
elif y1 > 0 and any(workspace[xt ][y1 - 1] for xt in range(x1, x2 + 1)): y1 -= 1
elif y2 < height - 1 and any(workspace[xt ][y2 + 1] for xt in range(x1, x2 + 1)): y2 += 1
else: break
# Save everything in the bounding box as a new image.
orig.crop((x1, y1, x2, y2)).save("out/obj-{:04d}-{:04d}.png".format(x1, y1))
# Clear the workspace here so we don't re-process this object.
for xt in range(x1, x2 + 1):
for yt in range(y1, y2 + 1):
workspace[xt][yt] = False
print("Extracted", n_objects, "objects.")
Вот как выглядят полученные файлы (не показаны в одинаковом масштабе):
Николя Рауль
Мог говорит восстановить Монику
Кодиолог