В мире 2D-изображений PIL может быть полезен как этот ответ .
Рассмотрим объем 3d:
import numpy as np
from PIL import Image, ImageChops
im = np.zeros((10, 10))
im[4:6, 4:6] = np.ones((2, 2))
im = Image.fromarray(im).convert("L")
vlm = np.zeros((10, 10, 10))
vlm[4:6, 4:6, 4:6] = np.ones((2, 2, 2))
Он включает три этапа:
1) Определение пограничных пикселей (вокселей в 3D-объеме).
2D: bg = Image.new(im.mode, im.size, im.getpixel((0, 0)))
3D: vbg = vlm[0, 0, 0]
2) Определение координаты, ширины, высоты (и глубины)для 3D) внутренней "коробки"
2D: bbox = ImageChops.difference(im, bg).getbbox()
3D: bbox3d = MAGIC(vlm, vbg) # return (4, 4, 4, 6, 6, 6)
← ПРОБЛЕМА
3) Обрезать "коробку" из
2D: im = im.crop(bbox) # same as im[bbox[0]:bbox[2], bbox[1]:bbox[3]]
3D: vlm = vlm[bbox3d[0]:bbox3d[3], bbox3d[1]:bbox3d[4], bbox3d[2]:bbox3d[5]]
Итак, проблема ясна.Как реализовать 3D-версию ImageChops.difference(im, bg).getbbox()
?
Есть ли какая-либо имеющаяся библиотека?
Я реализовал наивный подход MAGIC()
:
def bbox3d(volume):
slices = np.moveaxis(volume, 2, 0)
bboxes = []
for s in slices:
img = Image.fromarray(s)
bg = Image.new(img.mode, img.size)
diff = ImageChops.difference(img, bg)
bbox = ImageChops.add(diff, diff, 2.0, -100).getbbox()
bboxes.append(bbox)
z, zd = 0, len(bboxes)
for i in range(len(bboxes)):
if bboxes[i] and z == 0:
z = i
break
for i in reversed(range(len(bboxes))):
if bboxes[i] and zd == len(bboxes):
zd = i + 1
break
assert z <= zd
x = min([b[0] for b in bboxes if b])
y = min([b[1] for b in bboxes if b])
xd = max([b[2] for b in bboxes if b])
yd = max([b[3] for b in bboxes if b])
return (x, y, z, xd, yd, zd)