Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使图像的对象彼此最接近_Python_Image Processing_Computer Vision_Python Imaging Library - Fatal编程技术网

Python 使图像的对象彼此最接近

Python 使图像的对象彼此最接近,python,image-processing,computer-vision,python-imaging-library,Python,Image Processing,Computer Vision,Python Imaging Library,我对PIL没有太多经验,我从一堆显微镜图像细胞中编辑了这些图像,每个细胞都在一个30x30大小的掩模中。我一直在努力把这些细胞放在一个黑色的背景中,尽可能地相互靠近而不重叠 我的代码如下: def spread_circles(circles, rad, iterations,step): radsqr = rad**2 for i in range(iterations): for ix,c in enumerate(circles):

我对PIL没有太多经验,我从一堆显微镜图像细胞中编辑了这些图像,每个细胞都在一个30x30大小的掩模中。我一直在努力把这些细胞放在一个黑色的背景中,尽可能地相互靠近而不重叠

我的代码如下:

def spread_circles(circles, rad, iterations,step):
    radsqr = rad**2
    for i in range(iterations):
        for ix,c in enumerate(circles):
            vecs = c-circles
            dists = np.sum((vecs)**2,axis=1)
            if len(dists)>0:
                push = (vecs[dists<radsqr,:].T*dists[dists<radsqr]).T
                push = np.sum(push,axis=0)
                pushmag = np.sum(push*push)**0.5
                if pushmag>0:
                    push = push/pushmag*step
                    circles[ix]+=push
    return circles



def gen_image(sample,n_iter, height=850, width = 850, max_shape=30, num_circles=150):
    circles = np.random.uniform(low=max_shape,high=height-max_shape,size=(num_circles,2))   
    circles = spread_circles(circles, max_shape, n_iter, 1).astype(int)
    img = Image.new(mode='F',size=(height,width),color=0).convert('RGBA')
    final1 = Image.new("RGBA", size=(height,width))
    final1.paste(img, (0,0), img)
    for n,c in enumerate(circles):
        foreground = sample[n]       
        final1.paste(foreground, (c[0],c[1]), foreground)     
    return final1 
def spread_圆(圆、rad、迭代、步长):
radsqr=rad**2
对于范围内的i(迭代):
对于ix,枚举中的c(圆圈):
vecs=c-圆
距离=np.和((向量)**2,轴=1)
如果len(dists)>0:

push=(vecs[dists我已经开始考虑这一点,并且已经实施了一些策略。任何其他想找点乐趣的人都欢迎借用、窃取、盗用或破解我的代码中任何他们可以使用的部分!明天我可能还会玩一些

#!/usr/bin/env python3

from PIL import Image, ImageOps
import numpy as np
from glob import glob
import math

def checkCoverage(im):
   """Determines percentage of image that is cells rather than background"""
   N = np.count_nonzero(im)
   return N * 100 / im.size


def loadImages():
   """Load all cell images in current directory into list of trimmed Numpy arrays"""
   images = []
   for filename in glob('*.png'):
      # Open and convert to greyscale
      im = Image.open(filename).convert('L')
      # Trim to bounding box
      im = im.crop(im.getbbox())
      images.append(np.array(im))
   return images

def Strategy1():
   """Get largest image and pad all images to that size - at least it will tesselate perfectly"""
   images = loadImages()
   N = len(images)
   # Find height of tallest image and width of widest image
   maxh = max(im.shape[0] for im in images)
   maxw = max(im.shape[1] for im in images)
   # Determine how many images we will pack across and down the output image - could be improved
   Nx = int(math.sqrt(N))+1
   Ny = int(N/Nx)+1
   print(f'Padding {N} images each to height:{maxh} x width:{maxw}')
   # Create output image
   res = Image.new('L', (Nx*maxw,Ny*maxh), color=0)
   # Pack all images from list onto regular grid
   x, y = 0, 0
   for im in images:
      this = Image.fromarray(im)
      h, w = im.shape
      # Pack this image into top-left of its grid-cell, unless
      # a) in first row, in which case pack to bottom
      # b) in first col, in which case pack to right
      thisx = x*maxw
      thisy = y*maxh
      if y==0:
         thisy += maxh - h
      if x==0:
         thisx += maxw - w
      res.paste(this, (thisx,thisy))
      x += 1
      if x==Nx:
         x  = 0
         y += 1

   # Trim extraneous black edges
   res = res.crop(res.getbbox())
   # Save as JPEG so we don't find it as a PNG in next strategy
   res.save('strategy1.jpg')
   cov = checkCoverage(np.array(res))
   print(f'Strategy1 coverage: {cov}')


def Strategy2():
   """Rotate all images to portrait (tall rather than wide) and order by height so we tend to stack equal height images side-by-side"""
   tmp = loadImages()
   # Recreate list with all images in portrait format, i.e. tall
   portrait = []
   for im in tmp:
      if im.shape[0] >= im.shape[1]:
         # Already portrait, add as-is
         portrait.append(im)
      else:
         # Landscape, so rotate
         portrait.append(np.rot90(im))
   images = sorted(portrait, key=lambda x: x.shape[0], reverse=True)
   N = len(images)
   maxh, maxw = 31, 31
   # Determine how many images we will pack across and down the output image
   Nx = int(math.sqrt(N))+1
   Ny = int(N/Nx)+1
   print(f'Packing images by height')
   # Create output image
   resw, resh = Nx*maxw, Ny*maxh
   res = Image.new('L', (resw,resh), color=0)
   # Pack all from list 
   xpos, ypos = 0, 0
   # Pack first row L->R, second row R->L and alternate
   packToRight = True
   for im in images:
      thisw, thish = im.shape
      this = Image.fromarray(im)
      if packToRight:
         if xpos+thisw < resw:
            # If it fits to the right, pack it there
            res.paste(this,(xpos,ypos))
            xpos += thisw
         else:
            # Else start a new row, pack at right end and continue packing to left
            packToRight = False
            res.paste(this,(resw-thisw,ypos))
            ypos = res.getbbox()[3]
      else:
         if xpos>thisw:
            # If it fits to the left, pack it there
            res.paste(this,(xpos-thisw,ypos))
            xpos -= thisw
         else:
            # Else start a new row, pack at left end and continue packing to right
            ypos = res.getbbox()[3]
            packToRight = True
            res.paste(this,(0,ypos))

   # Trim any black edges
   res = res.crop(res.getbbox())
   # Save as JPEG so we don't find it as a PNG in next strategy
   res.save('strategy2.jpg')
   cov = checkCoverage(np.array(res))
   print(f'Strategy2 coverage: {cov}')

Strategy1()
Strategy2()
!/usr/bin/env python3
从PIL导入图像,图像操作
将numpy作为np导入
从全局导入全局
输入数学
def检查覆盖率(im):
“”“确定作为单元格而不是背景的图像的百分比”“”
N=np.计数非零(im)
返回N*100/im尺寸
def loadImages():
“”“将当前目录中的所有单元格图像加载到修剪过的Numpy数组列表中”“”
图像=[]
对于glob('*.png')中的文件名:
#打开并转换为灰度
im=Image.open(filename.convert('L'))
#修剪到边界框
im=im.crop(im.getbbox())
images.append(np.array(im))
返回图像
def Strategy1():
“”“获取最大的图像并将所有图像填充到该大小-至少它会完美地镶嵌”“”
images=loadImages()
N=透镜(图像)
#查找最高图像的高度和最宽图像的宽度
maxh=max(图像中im的im.shape[0])
maxw=max(图像中im的im.shape[1])
#确定我们将在输出图像上下打包多少图像-可以改进
Nx=int(数学sqrt(N))+1
Ny=int(N/Nx)+1
打印(f'填充{N}个图像,每个图像的高度:{maxh}x宽度:{maxw}')
#创建输出图像
res=Image.new('L',(Nx*maxw,Ny*maxh),color=0)
#将列表中的所有图像打包到常规网格中
x、 y=0,0
对于图像中的即时消息:
this=Image.fromarray(im)
h、 w=im.shape
#将此图像打包到其网格单元格的左上角,除非
#a)在第一排,在这种情况下,包装到底部
#b)在第一列中,在这种情况下,向右包装
thisx=x*maxw
thisy=y*maxh
如果y==0:
thisy+=maxh-h
如果x==0:
thisx+=maxw-w
res.paste(this,(thisx,thisy))
x+=1
如果x==Nx:
x=0
y+=1
#修剪无关的黑色边缘
res=res.crop(res.getbbox())
#另存为JPEG,这样我们在下一个策略中不会发现它是PNG
res.save('strategy1.jpg')
cov=检查覆盖率(np.数组(res))
打印(f'Strategy1覆盖范围:{cov}')
def Strategy2():
“”“将所有图像旋转为纵向(高而不是宽)并按高度排序,以便我们倾向于将等高图像并排堆叠”“”
tmp=loadImages()
#以纵向格式重新创建包含所有图像的列表,即
肖像=[]
对于tmp中的im:
如果im.shape[0]>=im.shape[1]:
#已绘制肖像,按原样添加
肖像。附加(im)
其他:
#风景,所以旋转
纵向附加(np.rot90(im))
图像=已排序(纵向,关键点=λx:x.shape[0],反向=真)
N=透镜(图像)
maxh,maxw=31,31
#确定我们将在输出图像上下打包多少图像
Nx=int(数学sqrt(N))+1
Ny=int(N/Nx)+1
打印(f‘按高度包装图像’)
#创建输出图像
resw,resh=Nx*maxw,Ny*maxh
res=Image.new('L',(resw,resh),color=0)
#从列表中打包所有内容
xpos,ypos=0,0
#打包第一行L->R,第二行R->L和备用
packToRight=True
对于图像中的即时消息:
thisw,thish=im.shape
this=Image.fromarray(im)
如果包装正确:
如果xpos+thiswthisw:
#如果放在左边,就放在那里
res.paste(此(xpos thisw,ypos))
xpos-=thisw
其他:
#否则,开始新的一行,在左端打包,然后继续向右打包
ypos=res.getbbox()[3]
packToRight=True
res.paste(此(0,ypos))
#修剪任何黑色边缘
res=res.crop(res.getbbox())
#另存为JPEG,这样我们在下一个策略中不会发现它是PNG
res.save('strategy2.jpg'))
cov=检查覆盖率(np.数组(res))
打印(f'Strategy2覆盖范围:{cov}')
战略1()
战略2()

战略1的覆盖率为42%:

战略2的覆盖率为64%:


问题很酷!我不清楚他们最初是如何陷入如此混乱的?你们有没有单独的图像(每个图像小于30x30)不知何故,你可以像那样分享它们..例如,Dropbox、Google drive中单独图像的Zip存档?或者我应该从你的两张图像中的第一张中剪切它们吗?另外,我最初的想法是OpenCV或skimage可能是一个更好的工具选择。请问有什么限制?我并不拒绝skimage或OpenCV的一个好方法,事实上我是从h openCv然后我努力获得图像的透明度,然后我找到了一种使用PIL的更简单的方法。下面的链接中有图像。没有主要限制,只是希望对象彼此靠近,并在黑色图像背景中,正如我用红色圆圈显示的那样。那么开始沿着这些线排列的东西怎么样?是细胞吗允许在最终图像中触摸?允许旋转它们吗?您看过吗