4
votes

Tensorflow: recadrer la plus grande région carrée centrale de l'image

Mon réseau prend des images de taille 100 x 100 pixels. Par conséquent, je dois redimensionner les images de mon ensemble de données qui sont de taille différente. Je veux pouvoir extraire la plus grande région carrée centrale d'une image donnée, puis la redimensionner à 100 x 100 .

Pour être plus précis, disons qu'une image a une largeur de 200 pixels et une hauteur de 50 pixels. Ensuite, je veux extraire la plus grande région carrée centrale qui est dans cet exemple 50 x 50 suivi d'un redimensionnement de l'image à 100 x 100 pixels.

Quelle est la bonne façon de faire cela en utilisant Tensorflow? En ce moment, j'utilise tf.image.resize_images () qui déforme l'image et je veux m'en débarrasser.


2 commentaires

Quelle est la forme de vos tenseurs? Autrement dit, est-ce (batch_size, hauteur, largeur, canaux) ou autre chose?


@jdehesa Chaque image est de forme (largeur, hauteur, canaux) . Je ne peux pas présenter mon ensemble de données sous la forme (batch_size, hauteur, largeur, canaux) car la hauteur et la largeur de chaque image peuvent varier.


4 Réponses :


4
votes

On dirait que crop_to_bounding_box est faire ce dont vous avez besoin:

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))


3 commentaires

Existe-t-il une solution où je n'ai pas à fournir d'autres informations que l'image? Votre solution ne fonctionne que pour les images de taille 200 x 50 , non?


@Samuel Eh bien, bien sûr, vous devez brancher d'autres nombres que 200 et 50 si vos dimensions sont différentes;) J'ai mis à jour ma réponse. Je ne connais aucune fonction faisant exactement ce que vous voulez en une seule étape.


Je ne peux pas obtenir la forme correcte, image.shape renvoie (Aucun, Aucun, 3). Je mappe cette fonction dans un tf.data.Dataset . Comment puis je faire ça?



1
votes

Je pense que cela fait ce que vous voulez:

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)

Il y a aussi tf.image.crop_and_resize , qui peut faire les deux choses en une seule fois, mais vous devez utiliser des coordonnées d'image normalisées avec cela:

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)


0 commentaires

1
votes
[[ 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]]

0 commentaires

1
votes

Et ça?

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()

orignal original redimensionné [image de sortie2


2 commentaires

Que signifie @ tf.function ? Où utilisez-vous le module random ? À quoi ressemblait l'image d'entrée?


aléatoire est pour l'augmentation. vous pouvez le supprimer. @ tf.function sert à compiler la fonction dans le bytecode de tensorflow.