Planeamos crear fotografías de partículas pequeñas usando un microscopio. Estos pequeños elementos tienden a ser convexos y se supone que no deben tocarse entre sí. El fondo puede ser un poco ruidoso, pero debe haber un gran contraste entre el fondo y los elementos (nuestro objetivo es crear imágenes como las del ejemplo). Me gustaría extraer todos los elementos individuales, recortarlos y guardarlos como imágenes individuales. Necesito una herramienta que pueda resolver este problema también en los casos en que el borde entre un elemento y el fondo está menos definido.
Después de extraer todas las fotografías, ejecuté un script de Matlab en cada imagen.
Sistema operativo: preferiblemente Linux, pero Windows también está bien.
Prefiero que la selección sea lo más automática posible (para poder ejecutar el algoritmo en cientos de imágenes).
Imagen de muestra:
Aquí hay un programa de Python 3 que distingue los píxeles de los objetos de los píxeles que no son objetos simplemente ajustando el umbral del canal rojo a 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.")
Así es como se ven los archivos resultantes (no se muestran a escalas iguales):
Nicolás Raúl
Mawg dice que reincorpore a Monica
Codiólogo