Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/pt-br/hub/tutorials/tf2_object_detection.ipynb
25118 views
Kernel: Python 3

Licensed under the Apache License, Version 2.0 (the "License");

#@title Copyright 2020 The TensorFlow Hub Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ==============================================================================

Colab de detecção de objetos do TensorFlow Hub

Este é o Colab de detecção de objetos do TensorFlow Hub! Este notebook apresenta as etapas de execução de um modelo de detecção de objetos "out-of-the-box" em imagens.

Outros modelos

Esta coleção tem modelos de detecção de objetos do TF2 que foram treinados com o dataset COCO 2017. Aqui você encontra todos os modelos de detecção de objetos hospedados atualmente em tfhub.dev.

Importações e configuração

Vamos começar com as importações básicas.

# This Colab requires a recent numpy version. !pip install numpy==1.24.3 !pip install protobuf==3.20.3
import os import pathlib import matplotlib import matplotlib.pyplot as plt import io import scipy.misc import numpy as np from six import BytesIO from PIL import Image, ImageDraw, ImageFont from six.moves.urllib.request import urlopen import tensorflow as tf import tensorflow_hub as hub tf.get_logger().setLevel('ERROR')

Utilitários

Execute a célula abaixo para criar alguns utilitários que serão necessários posteriormente:

  • Método helper para carregar uma imagem

  • Mapeamento entre nome do modelo e identificador do TF Hub

  • Lista de tuplas com pontos-chave humanos para o dataset COCO 2017, necessária para modelos com pontos-chave.

# @title Run this!! def load_image_into_numpy_array(path): """Load an image from file into a numpy array. Puts image into numpy array to feed into tensorflow graph. Note that by convention we put it into a numpy array with shape (height, width, channels), where channels=3 for RGB. Args: path: the file path to the image Returns: uint8 numpy array with shape (img_height, img_width, 3) """ image = None if(path.startswith('http')): response = urlopen(path) image_data = response.read() image_data = BytesIO(image_data) image = Image.open(image_data) else: image_data = tf.io.gfile.GFile(path, 'rb').read() image = Image.open(BytesIO(image_data)) (im_width, im_height) = image.size return np.array(image.getdata()).reshape( (1, im_height, im_width, 3)).astype(np.uint8) ALL_MODELS = { 'CenterNet HourGlass104 512x512' : 'https://tfhub.dev/tensorflow/centernet/hourglass_512x512/1', 'CenterNet HourGlass104 Keypoints 512x512' : 'https://tfhub.dev/tensorflow/centernet/hourglass_512x512_kpts/1', 'CenterNet HourGlass104 1024x1024' : 'https://tfhub.dev/tensorflow/centernet/hourglass_1024x1024/1', 'CenterNet HourGlass104 Keypoints 1024x1024' : 'https://tfhub.dev/tensorflow/centernet/hourglass_1024x1024_kpts/1', 'CenterNet Resnet50 V1 FPN 512x512' : 'https://tfhub.dev/tensorflow/centernet/resnet50v1_fpn_512x512/1', 'CenterNet Resnet50 V1 FPN Keypoints 512x512' : 'https://tfhub.dev/tensorflow/centernet/resnet50v1_fpn_512x512_kpts/1', 'CenterNet Resnet101 V1 FPN 512x512' : 'https://tfhub.dev/tensorflow/centernet/resnet101v1_fpn_512x512/1', 'CenterNet Resnet50 V2 512x512' : 'https://tfhub.dev/tensorflow/centernet/resnet50v2_512x512/1', 'CenterNet Resnet50 V2 Keypoints 512x512' : 'https://tfhub.dev/tensorflow/centernet/resnet50v2_512x512_kpts/1', 'EfficientDet D0 512x512' : 'https://tfhub.dev/tensorflow/efficientdet/d0/1', 'EfficientDet D1 640x640' : 'https://tfhub.dev/tensorflow/efficientdet/d1/1', 'EfficientDet D2 768x768' : 'https://tfhub.dev/tensorflow/efficientdet/d2/1', 'EfficientDet D3 896x896' : 'https://tfhub.dev/tensorflow/efficientdet/d3/1', 'EfficientDet D4 1024x1024' : 'https://tfhub.dev/tensorflow/efficientdet/d4/1', 'EfficientDet D5 1280x1280' : 'https://tfhub.dev/tensorflow/efficientdet/d5/1', 'EfficientDet D6 1280x1280' : 'https://tfhub.dev/tensorflow/efficientdet/d6/1', 'EfficientDet D7 1536x1536' : 'https://tfhub.dev/tensorflow/efficientdet/d7/1', 'SSD MobileNet v2 320x320' : 'https://tfhub.dev/tensorflow/ssd_mobilenet_v2/2', 'SSD MobileNet V1 FPN 640x640' : 'https://tfhub.dev/tensorflow/ssd_mobilenet_v1/fpn_640x640/1', 'SSD MobileNet V2 FPNLite 320x320' : 'https://tfhub.dev/tensorflow/ssd_mobilenet_v2/fpnlite_320x320/1', 'SSD MobileNet V2 FPNLite 640x640' : 'https://tfhub.dev/tensorflow/ssd_mobilenet_v2/fpnlite_640x640/1', 'SSD ResNet50 V1 FPN 640x640 (RetinaNet50)' : 'https://tfhub.dev/tensorflow/retinanet/resnet50_v1_fpn_640x640/1', 'SSD ResNet50 V1 FPN 1024x1024 (RetinaNet50)' : 'https://tfhub.dev/tensorflow/retinanet/resnet50_v1_fpn_1024x1024/1', 'SSD ResNet101 V1 FPN 640x640 (RetinaNet101)' : 'https://tfhub.dev/tensorflow/retinanet/resnet101_v1_fpn_640x640/1', 'SSD ResNet101 V1 FPN 1024x1024 (RetinaNet101)' : 'https://tfhub.dev/tensorflow/retinanet/resnet101_v1_fpn_1024x1024/1', 'SSD ResNet152 V1 FPN 640x640 (RetinaNet152)' : 'https://tfhub.dev/tensorflow/retinanet/resnet152_v1_fpn_640x640/1', 'SSD ResNet152 V1 FPN 1024x1024 (RetinaNet152)' : 'https://tfhub.dev/tensorflow/retinanet/resnet152_v1_fpn_1024x1024/1', 'Faster R-CNN ResNet50 V1 640x640' : 'https://tfhub.dev/tensorflow/faster_rcnn/resnet50_v1_640x640/1', 'Faster R-CNN ResNet50 V1 1024x1024' : 'https://tfhub.dev/tensorflow/faster_rcnn/resnet50_v1_1024x1024/1', 'Faster R-CNN ResNet50 V1 800x1333' : 'https://tfhub.dev/tensorflow/faster_rcnn/resnet50_v1_800x1333/1', 'Faster R-CNN ResNet101 V1 640x640' : 'https://tfhub.dev/tensorflow/faster_rcnn/resnet101_v1_640x640/1', 'Faster R-CNN ResNet101 V1 1024x1024' : 'https://tfhub.dev/tensorflow/faster_rcnn/resnet101_v1_1024x1024/1', 'Faster R-CNN ResNet101 V1 800x1333' : 'https://tfhub.dev/tensorflow/faster_rcnn/resnet101_v1_800x1333/1', 'Faster R-CNN ResNet152 V1 640x640' : 'https://tfhub.dev/tensorflow/faster_rcnn/resnet152_v1_640x640/1', 'Faster R-CNN ResNet152 V1 1024x1024' : 'https://tfhub.dev/tensorflow/faster_rcnn/resnet152_v1_1024x1024/1', 'Faster R-CNN ResNet152 V1 800x1333' : 'https://tfhub.dev/tensorflow/faster_rcnn/resnet152_v1_800x1333/1', 'Faster R-CNN Inception ResNet V2 640x640' : 'https://tfhub.dev/tensorflow/faster_rcnn/inception_resnet_v2_640x640/1', 'Faster R-CNN Inception ResNet V2 1024x1024' : 'https://tfhub.dev/tensorflow/faster_rcnn/inception_resnet_v2_1024x1024/1', 'Mask R-CNN Inception ResNet V2 1024x1024' : 'https://tfhub.dev/tensorflow/mask_rcnn/inception_resnet_v2_1024x1024/1' } IMAGES_FOR_TEST = { 'Beach' : 'models/research/object_detection/test_images/image2.jpg', 'Dogs' : 'models/research/object_detection/test_images/image1.jpg', # By Heiko Gorski, Source: https://commons.wikimedia.org/wiki/File:Naxos_Taverna.jpg 'Naxos Taverna' : 'https://upload.wikimedia.org/wikipedia/commons/6/60/Naxos_Taverna.jpg', # Source: https://commons.wikimedia.org/wiki/File:The_Coleoptera_of_the_British_islands_(Plate_125)_(8592917784).jpg 'Beatles' : 'https://upload.wikimedia.org/wikipedia/commons/1/1b/The_Coleoptera_of_the_British_islands_%28Plate_125%29_%288592917784%29.jpg', # By Américo Toledano, Source: https://commons.wikimedia.org/wiki/File:Biblioteca_Maim%C3%B3nides,_Campus_Universitario_de_Rabanales_007.jpg 'Phones' : 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Biblioteca_Maim%C3%B3nides%2C_Campus_Universitario_de_Rabanales_007.jpg/1024px-Biblioteca_Maim%C3%B3nides%2C_Campus_Universitario_de_Rabanales_007.jpg', # Source: https://commons.wikimedia.org/wiki/File:The_smaller_British_birds_(8053836633).jpg 'Birds' : 'https://upload.wikimedia.org/wikipedia/commons/0/09/The_smaller_British_birds_%288053836633%29.jpg', } COCO17_HUMAN_POSE_KEYPOINTS = [(0, 1), (0, 2), (1, 3), (2, 4), (0, 5), (0, 6), (5, 7), (7, 9), (6, 8), (8, 10), (5, 6), (5, 11), (6, 12), (11, 12), (11, 13), (13, 15), (12, 14), (14, 16)]

Ferramentas de visualização

Para visualizar as imagens com as caixas detectadas, pontos-chave e segmentação adequados, vamos usar a API Object Detection do TensorFlow. Para instalá-la, vamos clonar o repositório.

# Clone the tensorflow models repository !git clone --depth 1 https://github.com/tensorflow/models

Instalação da API Object Detection.

%%bash sudo apt install -y protobuf-compiler cd models/research/ protoc object_detection/protos/*.proto --python_out=. cp object_detection/packages/tf2/setup.py . python -m pip install .

Agora, podemos importar as dependências que serão necessárias posteriormente.

from object_detection.utils import label_map_util from object_detection.utils import visualization_utils as viz_utils from object_detection.utils import ops as utils_ops %matplotlib inline

Carregue os dados de mapas de rótulos (para plotagem)

Os mapas de rótulos fazem a correspondência entre números do índice e nomes de categorias para que, quando a rede de convolução previr 5, saibamos que isso corresponde a airplane (avião). Aqui, usamos funções utilitárias internas, mas qualquer função que retorne um dicionário mapeando inteiros em rótulos de strings apropriados funcionará.

Por questões de simplicidade, vamos carregar a partir do repositório usado para carregar a API Object Detection.

PATH_TO_LABELS = './models/research/object_detection/data/mscoco_label_map.pbtxt' category_index = label_map_util.create_category_index_from_labelmap(PATH_TO_LABELS, use_display_name=True)

Crie um modelo de detecção e carregue os pesos do modelo pré-treinado

Aqui, vamos escolher qual modelo de detecção de objetos usaremos. Selecione a arquitetura, e ela será carregada automaticamente. Se você quiser alterar o modelo para testar outras arquiteturas posteriormente, basta mudar a próxima célula e executar as seguintes.

Dica: se você quiser ler mais detalhes sobre o modelo selecionado, pode acessar o link (identificador do modelo) e ler a documentação adicional no TF Hub. Após selecionar um modelo, você exibirá o identificador via print para facilitar.

#@title Model Selection { display-mode: "form", run: "auto" } model_display_name = 'CenterNet HourGlass104 Keypoints 512x512' # @param ['CenterNet HourGlass104 512x512','CenterNet HourGlass104 Keypoints 512x512','CenterNet HourGlass104 1024x1024','CenterNet HourGlass104 Keypoints 1024x1024','CenterNet Resnet50 V1 FPN 512x512','CenterNet Resnet50 V1 FPN Keypoints 512x512','CenterNet Resnet101 V1 FPN 512x512','CenterNet Resnet50 V2 512x512','CenterNet Resnet50 V2 Keypoints 512x512','EfficientDet D0 512x512','EfficientDet D1 640x640','EfficientDet D2 768x768','EfficientDet D3 896x896','EfficientDet D4 1024x1024','EfficientDet D5 1280x1280','EfficientDet D6 1280x1280','EfficientDet D7 1536x1536','SSD MobileNet v2 320x320','SSD MobileNet V1 FPN 640x640','SSD MobileNet V2 FPNLite 320x320','SSD MobileNet V2 FPNLite 640x640','SSD ResNet50 V1 FPN 640x640 (RetinaNet50)','SSD ResNet50 V1 FPN 1024x1024 (RetinaNet50)','SSD ResNet101 V1 FPN 640x640 (RetinaNet101)','SSD ResNet101 V1 FPN 1024x1024 (RetinaNet101)','SSD ResNet152 V1 FPN 640x640 (RetinaNet152)','SSD ResNet152 V1 FPN 1024x1024 (RetinaNet152)','Faster R-CNN ResNet50 V1 640x640','Faster R-CNN ResNet50 V1 1024x1024','Faster R-CNN ResNet50 V1 800x1333','Faster R-CNN ResNet101 V1 640x640','Faster R-CNN ResNet101 V1 1024x1024','Faster R-CNN ResNet101 V1 800x1333','Faster R-CNN ResNet152 V1 640x640','Faster R-CNN ResNet152 V1 1024x1024','Faster R-CNN ResNet152 V1 800x1333','Faster R-CNN Inception ResNet V2 640x640','Faster R-CNN Inception ResNet V2 1024x1024','Mask R-CNN Inception ResNet V2 1024x1024'] model_handle = ALL_MODELS[model_display_name] print('Selected model:'+ model_display_name) print('Model Handle at TensorFlow Hub: {}'.format(model_handle))

Carregando o modelo selecionado a partir do TensorFlow Hub

Aqui, só precisamos do identificador do modelo que foi selecionado e usamos a biblioteca do TensorFlow Hub para carregá-lo na memória.

print('loading model...') hub_model = hub.load(model_handle) print('model loaded!')

Carregando uma imagem

Vamos testar o modelo em uma imagem simples. Para ajudar, fornecemos uma lista de imagens de teste.

Veja abaixo alguns testes interessantes, se você tiver curiosidade.

  • Tente executar a inferência em suas próprias imagens. Basta fazer upload delas no Colab e carregar da mesma forma que na célula abaixo.

  • Modifique algumas imagens de entrada e verifique se a detecção ainda funciona. Veja alguns testes simples que você pode fazer: girar a imagem horizontalmente ou converter para escala de cinza (observe que ainda esperamos que a imagem de entrada tenha três canais).

Cuidado: ao usar imagens com um canal alfa, o modelo espera imagens com três canais, e o alfa será contabilizado como um quarto canal.

#@title Image Selection (don't forget to execute the cell!) { display-mode: "form"} selected_image = 'Beach' # @param ['Beach', 'Dogs', 'Naxos Taverna', 'Beatles', 'Phones', 'Birds'] flip_image_horizontally = False #@param {type:"boolean"} convert_image_to_grayscale = False #@param {type:"boolean"} image_path = IMAGES_FOR_TEST[selected_image] image_np = load_image_into_numpy_array(image_path) # Flip horizontally if(flip_image_horizontally): image_np[0] = np.fliplr(image_np[0]).copy() # Convert image to grayscale if(convert_image_to_grayscale): image_np[0] = np.tile( np.mean(image_np[0], 2, keepdims=True), (1, 1, 3)).astype(np.uint8) plt.figure(figsize=(24,32)) plt.imshow(image_np[0]) plt.show()

Faça a inferência

Para fazer a inferência, basta chamarmos o modelo do TF Hub carregado.

Veja o que você pode testar:

  • Exiba result['detection_boxes'] via print e tente fazer a correspondência entre os locais das caixas e as caixas na imagem. Observe que as coordenadas são fornecidas de forma normalizada (isto é, no intervalo [0, 1]).

  • Inspecione outras chaves de saída presentes no resultado. Confira a documentação completa na página de documentação dos modelos (basta acessar no navegador o identificador do modelo exibido via print anteriormente).

# running inference results = hub_model(image_np) # different object detection models have additional results # all of them are explained in the documentation result = {key:value.numpy() for key,value in results.items()} print(result.keys())

Visualização dos resultados

Aqui, vamos precisar da API Object Detection do TensorFlow para mostrar os quadrados do passo de inferência (e os pontos-chave, quando disponíveis).

Confira a documentação completa desse método aqui.

Aqui, você pode, por exemplo, definir min_score_thresh como outros valores (entre 0 e 1) para permitir mais detecções ou para eliminar mais detecções.

label_id_offset = 0 image_np_with_detections = image_np.copy() # Use keypoints if available in detections keypoints, keypoint_scores = None, None if 'detection_keypoints' in result: keypoints = result['detection_keypoints'][0] keypoint_scores = result['detection_keypoint_scores'][0] viz_utils.visualize_boxes_and_labels_on_image_array( image_np_with_detections[0], result['detection_boxes'][0], (result['detection_classes'][0] + label_id_offset).astype(int), result['detection_scores'][0], category_index, use_normalized_coordinates=True, max_boxes_to_draw=200, min_score_thresh=.30, agnostic_mode=False, keypoints=keypoints, keypoint_scores=keypoint_scores, keypoint_edges=COCO17_HUMAN_POSE_KEYPOINTS) plt.figure(figsize=(24,32)) plt.imshow(image_np_with_detections[0]) plt.show()

[Opcional]

Entre os modelos de detecção de objetos disponíveis, temos o Mask R-CNN, cuja saída permite a segmentação de instâncias.

Para visualizá-la, vamos usar o mesmo método de antes, mas acrescentando um parâmetro adicional:instance_masks=output_dict.get('detection_masks_reframed', None)

# Handle models with masks: image_np_with_mask = image_np.copy() if 'detection_masks' in result: # we need to convert np.arrays to tensors detection_masks = tf.convert_to_tensor(result['detection_masks'][0]) detection_boxes = tf.convert_to_tensor(result['detection_boxes'][0]) # Reframe the bbox mask to the image size. detection_masks_reframed = utils_ops.reframe_box_masks_to_image_masks( detection_masks, detection_boxes, image_np.shape[1], image_np.shape[2]) detection_masks_reframed = tf.cast(detection_masks_reframed > 0.5, tf.uint8) result['detection_masks_reframed'] = detection_masks_reframed.numpy() viz_utils.visualize_boxes_and_labels_on_image_array( image_np_with_mask[0], result['detection_boxes'][0], (result['detection_classes'][0] + label_id_offset).astype(int), result['detection_scores'][0], category_index, use_normalized_coordinates=True, max_boxes_to_draw=200, min_score_thresh=.30, agnostic_mode=False, instance_masks=result.get('detection_masks_reframed', None), line_thickness=8) plt.figure(figsize=(24,32)) plt.imshow(image_np_with_mask[0]) plt.show()