【问题标题】:Resize rectangular image to square, keeping ratio and fill background with black将矩形图像调整为正方形,保持比例并用黑色填充背景
【发布时间】:2017-10-29 02:19:34
【问题描述】:

我正在尝试调整一批 256 x N 像素的灰度图像(N 变化,但始终≤256)。

我的目的是缩小图像。

调整大小必须输出正方形 (1:1) 图像,其中:

  • 调整大小的图像垂直居中
  • 保持纵横比
  • 剩余像素呈现黑色

从视觉上看,这将是理想的结果:

我尝试创建一个具有目标大小(例如 200 x 200)的 numpy zeroes 矩阵,但无法将调整大小的图像粘贴到其垂直中心。

欢迎使用 cv2、PIL 或 numpy 提出任何建议。

【问题讨论】:

    标签: python opencv numpy image-processing python-imaging-library


    【解决方案1】:

    您可以使用Pillow 来实现:

    代码:

    from PIL import Image
    
    def make_square(im, min_size=256, fill_color=(0, 0, 0, 0)):
        x, y = im.size
        size = max(min_size, x, y)
        new_im = Image.new('RGBA', (size, size), fill_color)
        new_im.paste(im, (int((size - x) / 2), int((size - y) / 2)))
        return new_im
    

    测试代码:

    test_image = Image.open('hLarp.png')
    new_image = make_square(test_image)
    new_image.show()
    

    对于白色背景,您可以这样做:

    new_image = make_square(test_image, fill_color=(255, 255, 255, 0))
    

    结果:

    【讨论】:

    • 这看起来很不错,谢谢——所以.paste 的原点将位于中心?
    • 居中,除非图像是奇数像素。
    • 当然 - 因为我刚刚使用它而抓住了它。
    • 此代码仅将背景调整为 min_size 并将原始图像居中放置。如何将原始图像调整为 min_size?谢谢。
    • 我尝试在带有 python 3 的 jupyter notebook 上使用它,我不得不转换 (size - x) / 2(size - y) / 2 i> 到 int 使用 int((size - x) / 2)int((size - x) / 2)。我还必须将 RGBA 更改为 RGB 才能获得黑色背景
    【解决方案2】:

    这是使用 OPENCV 模块解决您问题的代码(也使用 NUMPY 模块)

    #Importing modules opencv + numpy
    import cv2
    import numpy as np
    
    #Reading an image (you can use PNG or JPG)
    img = cv2.imread("image.png")
    
    #Getting the bigger side of the image
    s = max(img.shape[0:2])
    
    #Creating a dark square with NUMPY  
    f = np.zeros((s,s,3),np.uint8)
    
    #Getting the centering position
    ax,ay = (s - img.shape[1])//2,(s - img.shape[0])//2
    
    #Pasting the 'image' in a centering position
    f[ay:img.shape[0]+ay,ax:ax+img.shape[1]] = img
    
    #Showing results (just in case) 
    cv2.imshow("IMG",f)
    #A pause, waiting for any press in keyboard
    cv2.waitKey(0)
    
    #Saving the image
    cv2.imwrite("img2square.png",f)
    cv2.destroyAllWindows()
    

    【讨论】:

    • 是否可以通过.zeros方法创建一个透明背景的正方形?
    【解决方案3】:

    PIL 具有缩略图方法,可以在保持纵横比的情况下进行缩放。从那里您只需将其粘贴到黑色背景矩形的中心即可。

    from PIL import Image
    
    def black_background_thumbnail(path_to_image, thumbnail_size=(200,200)):
        background = Image.new('RGBA', thumbnail_size, "black")    
        source_image = Image.open(path_to_image).convert("RGBA")
        source_image.thumbnail(thumbnail_size)
        (w, h) = source_image.size
        background.paste(source_image, ((thumbnail_size[0] - w) / 2, (thumbnail_size[1] - h) / 2 ))
        return background
    
    if __name__ == '__main__':
        img = black_background_thumbnail('hLARP.png')
        img.save('tmp.jpg')
        img.show()
    

    【讨论】:

      【解决方案4】:
      from PIL import Image
      
      def reshape(image):
          '''
          Reshapes the non-square image by pasting
          it to the centre of a black canvas of size
          n*n where n is the biggest dimension of
          the non-square image. 
          '''
          old_size = image.size
          max_dimension, min_dimension = max(old_size), min(old_size)
          desired_size = (max_dimension, max_dimension)
          position = int(max_dimension/2) - int(min_dimension/2) 
          blank_image = Image.new("RGB", desired_size, color='black')
          if image.height<image.width:
              blank_image.paste(image, (0, position))
          else:
              blank_image.paste(image, (position, 0))
          return blank_image
      

      【讨论】:

        猜你喜欢
        • 2018-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-21
        • 1970-01-01
        • 2017-11-06
        • 1970-01-01
        相关资源
        最近更新 更多