【问题标题】:Tensorflow: Crop largest central square region of imageTensorflow:裁剪图像的最大中心正方形区域
【发布时间】:2020-08-02 20:34:58
【问题描述】:

我的网络拍摄大小为100 x 100 像素的图像。因此,我必须调整我的数据集大小不同的图像的大小。我希望能够从给定图像中提取最大的中心正方形区域,然后将其调整为100 x 100。

更准确地说,假设图像的宽度为200 像素,高度为50 像素。然后我想提取最大的中心正方形区域,在这个例子中是50 x 50,然后将图像调整为100 x 100像素。

使用 Tensorflow 的正确方法是什么?现在我正在使用 tf.image.resize_images() 扭曲图像,我想摆脱它。

【问题讨论】:

  • 张量的形状是什么?也就是说,是(batch_size, height, width, channels)还是别的什么?
  • @jdehesa 每个图像的形状都是(width, height, channels)。我无法将我的数据集显示为(batch_size, height, width, channels),因为每个图像的height 和width 可能会有所不同。

标签: python tensorflow image-processing


【解决方案1】:

听起来crop_to_bounding_box 正在做你需要的事情:

import tensorflow as tf

def crop_center(image):
    h, w = image.shape[-3], image.shape[-2]
    if h > w:
        cropped_image = tf.image.crop_to_bounding_box(image, (h - w) // 2, 0, w, w)
    else:
        cropped_image = tf.image.crop_to_bounding_box(image, 0, (w - h) // 2, h, h)
    return tf.image.resize_images(cropped_image, (100, 100))

【讨论】:

  • 有没有一种解决方案,我不需要提供除图像之外的任何其他信息?您的解决方案仅适用于 200 x 50 大小的图像,对吗?
  • @Samuel 好吧,当然,如果您的尺寸不同,您必须插入 200 和 50 以外的其他数字;) 我更新了我的答案。我不知道有任何功能可以一步完成您想要的。
  • 我无法获得正确的形状,image.shape 返回(无,无,3)。我将此函数映射到tf.data.Dataset。我该怎么做?
【解决方案2】:

我认为这是你想要的:

import tensorflow as tf

def crop_center_and_resize(img, size):
    s = tf.shape(img)
    w, h = s[0], s[1]
    c = tf.minimum(w, h)
    w_start = (w - c) // 2
    h_start = (h - c) // 2
    center = img[w_start:w_start + c, h_start:h_start + c]
    return tf.image.resize_images(img, [size, size])

print(crop_center_and_resize(tf.zeros((80, 50, 3)), 100))
# Tensor("resize_images/Squeeze:0", shape=(100, 100, 3), dtype=float32)

还有tf.image.crop_and_resize,它可以同时做这两件事,但你必须使用标准化的图像坐标:

import tensorflow as tf

def crop_center_and_resize(img, size):
    s = tf.shape(img)
    w, h = s[0], s[1]
    c = tf.minimum(w, h)
    wn, hn = h / c, w / c
    result = tf.image.crop_and_resize(tf.expand_dims(img, 0),
                                      [[(1 - wn) / 2, (1 - hn) / 2, wn, hn]],
                                      [0], [size, size])
    return tf.squeeze(result, 0)

【讨论】:

    【解决方案3】:
    import tensorflow as tf
    
    
    def central_square_crop(image):                                                                                                                                                                                                                                       
        h, w = image.get_shape()[0].value, image.get_shape()[1].value                                                                                                                                                                                                     
        side = tf.minimum(h, w)                                                                                                                                                                                                                                           
        begin_h = tf.maximum(0, h - side) // 2                                                                                                                                                                                                                            
        begin_w = tf.maximum(0, w - side) // 2                                                                                                                                                                                                                            
        return tf.slice(image, [begin_h, begin_w, 0], [side, side, -1])                                                                                                                                                                                                   
    
    
    def main():                                                                                                                                                                                                                                                           
        image_t = tf.reshape(tf.range(5 * 7), [5, 7])                                                                                                                                                                                                                     
        image_t = tf.transpose(tf.stack([image_t, image_t, image_t]), [1, 2, 0])                                                                                                                                                                                          
        cropped_image_t = central_square_crop(image_t)                                                                                                                                                                                                                    
        with tf.Session() as sess:                                                                                                                                                                                                                                        
            image, cropped_image = sess.run([image_t, cropped_image_t])                                                                                                                                                                                                   
            print(image[:, :, 0])                                                                                                                                                                                                                                         
            print(cropped_image[:, :, 0])                                                                                                                                                                                                                                 
    
    
    if __name__ == '__main__':                                                                                                                                                                                                                                            
        main() 
    

    裁剪前的输出:

    [[ 0  1  2  3  4  5  6]
     [ 7  8  9 10 11 12 13]
     [14 15 16 17 18 19 20]
     [21 22 23 24 25 26 27]
     [28 29 30 31 32 33 34]]
    

    裁剪后:

    [[ 1  2  3  4  5]
     [ 8  9 10 11 12]
     [15 16 17 18 19]
     [22 23 24 25 26]
     [29 30 31 32 33]]
    

    然后,照常应用调整大小。

    【讨论】:

      【解决方案4】:

      这个怎么样?

      import tensorflow as tf
      import pathlib
      
      data_root_orig = tf.keras.utils.get_file(
          origin="https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz",
          fname="flower_photos",
          untar=True,
      )
      data_root = pathlib.Path(data_root_orig)
      print(data_root)
      for item in data_root.iterdir():
          print(item)
      
      import random
      
      all_image_paths = list(data_root.glob("*/*"))
      all_image_paths = [str(path) for path in all_image_paths]
      image_count = len(all_image_paths)
      print(image_count)
      
      def preprocess_image(img: tf.Tensor):
          img = tf.image.decode_jpeg(img, channels=3)
          shapes = tf.shape(img)
          h, w = shapes[-3], shapes[-2]
          small = tf.minimum(h, w)
          img = tf.image.resize_with_crop_or_pad(img, small, small)
          img = tf.image.resize(img, [192, 192])
          img /= 255.0
          return img
      
      @tf.function
      def load_and_preprocess_image(path: str):
          image = tf.io.read_file(path)
          return preprocess_image(image)
      
      import matplotlib.pyplot as plt
      
      image_path = all_image_paths[0]
      plt.imshow(load_and_preprocess_image(image_path))
      plt.grid(False)
      plt.show()
      

      原创 调整大小 [

      【讨论】:

      • @tf.function 代表什么?你在哪里使用random 模块?输入图像是什么样的?
      • 随机用于增强。你可以删除它。 @tf.function 用于将函数编译成 tensorflow 的字节码。
      猜你喜欢
      • 2016-08-13
      • 2020-08-27
      • 2019-05-08
      • 2015-02-05
      • 1970-01-01
      • 2013-04-04
      • 1970-01-01
      • 2012-12-21
      相关资源
      最近更新 更多