Извлечение ограничивающей рамки в формате .jpg

#python #opencv #tensorflow #object-detection-api

#python #opencv #тензорный поток #object-detection-api

Вопрос:

Извлеките обнаруженный объект вместе с ограничивающей рамкой и сохраните его как изображение на моем диске.

Я взял код Edge Electronics и успешно обучил и протестировал модель. Я получил ограничивающую рамку на своих изображениях.

 import os
import cv2
import numpy as np
import tensorflow as tf
import sys
from glob import glob
import glob
import csv
from PIL import Image
import json

sys.path.append("..")

# Import utilites
from utils import label_map_util
from utils import visualization_utils as vis_util

MODEL_NAME = 'inference_graph'

CWD_PATH = os.getcwd()

PATH_TO_CKPT = os.path.join(CWD_PATH,MODEL_NAME,'frozen_inference_graph.pb')

PATH_TO_LABELS = os.path.join(CWD_PATH,'training','labelmap.pbtxt')

PATH_TO_IMAGE = list(glob.glob("C:\new_multi_cat\models\research\object_detection\img_test\*jpeg"))

NUM_CLASSES = 3

label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
category_index = label_map_util.create_category_index(categories)

detection_graph = tf.Graph()

with detection_graph.as_default():
    od_graph_def = tf.GraphDef()
    with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
        serialized_graph = fid.read()
        od_graph_def.ParseFromString(serialized_graph)
        tf.import_graph_def(od_graph_def, name='')

    sess = tf.Session(graph=detection_graph)

image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')

detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')


detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')
detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')

num_detections = detection_graph.get_tensor_by_name('num_detections:0')


for paths in range(len(PATH_TO_IMAGE)):
    image = cv2.imread(PATH_TO_IMAGE[paths])
    image_expanded = np.expand_dims(image, axis=0)

    (boxes, scores, classes, num) = sess.run([detection_boxes, detection_scores, detection_classes, num_detections],feed_dict={image_tensor: image_expanded})


    vis_util.visualize_boxes_and_labels_on_image_array(
    image,
    np.squeeze(boxes),
    np.squeeze(classes).astype(np.int32),
    np.squeeze(scores),
    category_index,
    use_normalized_coordinates=True,
    line_thickness=4,
    min_score_thresh=0.80)


    white_bg_img = 255*np.ones(PATH_TO_IMAGE[paths].shape, np.uint8)
    vis_util.draw_bounding_boxes_on_image(
    white_bg_img ,
    np.squeeze(boxes),
    color='red',
    thickness=4)
    cv2.imwrite("bounding_boxes.jpg", white_bg_img)

    boxes = np.squeeze(boxes)
    for i in range(len(boxes)):
        box[0]=box[0]*height
        box[1]=box[1]*width
        box[2]=box[2]*height
        box[3]=box[3]*width
    roi = image[box[0]:box[2],box[1]:box[3]].copy()
    cv2.imwrite("box_{}.jpg".format(str(i)), roi)
  

Это ошибка, которую я получаю:

 Traceback (most recent call last):   File "objd_1.py", line
75, in <module>
     white_bg_img = 255*np.ones(PATH_TO_IMAGE[paths].shape, np.uint8) AttributeError: 'str' object has no attribute 'shape' 
  

Я много искал, но не смог определить, что не так в моем коде. Почему я не могу извлечь обнаруженную область в виде изображения?

Комментарии:

1. @halfer Я здесь новичок. Прошу прощения за мой пост. Будем учитывать предложенные вами моменты

Ответ №1:

Вы пытаетесь взять shape из имени файла вместо изображения. Заменить

 white_bg_img = 255*np.ones(PATH_TO_IMAGE[paths].shape, np.uint8)
  

Для

 white_bg_img = 255*np.ones(image.shape, np.uint8)
  

Редактировать: исправленный код

 import os
import cv2
import numpy as np
import tensorflow as tf
import sys
from glob import glob
import glob
import csv
from PIL import Image
import json

sys.path.append("..")

# Import utilites
from utils import label_map_util
from utils import visualization_utils as vis_util

MODEL_NAME = 'inference_graph'

CWD_PATH = os.getcwd()

PATH_TO_CKPT = os.path.join(CWD_PATH,MODEL_NAME,'frozen_inference_graph.pb')

PATH_TO_LABELS = os.path.join(CWD_PATH,'training','labelmap.pbtxt')

PATH_TO_IMAGE = list(glob.glob("C:\new_multi_cat\models\research\object_detection\img_test\*jpeg"))

NUM_CLASSES = 3

label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
category_index = label_map_util.create_category_index(categories)

detection_graph = tf.Graph()

with detection_graph.as_default():
    od_graph_def = tf.GraphDef()
    with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
        serialized_graph = fid.read()
        od_graph_def.ParseFromString(serialized_graph)
        tf.import_graph_def(od_graph_def, name='')

    sess = tf.Session(graph=detection_graph)

image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')

detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')


detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')
detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')

num_detections = detection_graph.get_tensor_by_name('num_detections:0')


for paths in range(len(PATH_TO_IMAGE)):
    image = cv2.imread(PATH_TO_IMAGE[paths])
    image_expanded = np.expand_dims(image, axis=0)

    (boxes, scores, classes, num) = sess.run([detection_boxes, detection_scores, detection_classes, num_detections],feed_dict={image_tensor: image_expanded})


    vis_util.visualize_boxes_and_labels_on_image_array(
    image,
    np.squeeze(boxes),
    np.squeeze(classes).astype(np.int32),
    np.squeeze(scores),
    category_index,
    use_normalized_coordinates=True,
    line_thickness=4,
    min_score_thresh=0.80)


    white_bg_img = 255*np.ones(image.shape, np.uint8)
    vis_util.draw_bounding_boxes_on_image_array(
    white_bg_img ,
    np.squeeze(boxes),
    color='red',
    thickness=4)
    cv2.imwrite("bounding_boxes.jpg", white_bg_img)

    boxes = np.squeeze(boxes)
    for i in range(len(boxes)):
        box[0]=box[0]*height
        box[1]=box[1]*width
        box[2]=box[2]*height
        box[3]=box[3]*width
    roi = image[box[0]:box[2],box[1]:box[3]].copy()
    cv2.imwrite("box_{}.jpg".format(str(i)), roi)
  

Комментарии:

1. Я сделал, как вы предложили, но это выдает другую ошибку. Ошибка атрибута: объект ‘numpy.ndarray’ не имеет атрибута ‘load’, поскольку значение в переменной image является numpy ndarray. Я просматриваю каталог изображений и считываю его в переменной изображения следующим образом для путей в диапазоне (len(PATH_TO_IMAGE)): image = cv2.imread(PATH_TO_IMAGE[пути])

2. @Ankit pilImage = Image.fromarray(image) для получения PIL-изображения из массива numpy. Затем передайте это pilImage функциям PIL вместо (или другим функциям, которые ожидают изображения PIL) передачи массивов numpy. visualize_boxes_and_labels_on_image_array ожидает, например, PIL-изображение.

3. Ваша проблема была четко указана в виде конкретного сообщения об ошибке. Если предлагаемое решение решает эту проблему, пожалуйста, рассмотрите возможность принятия ответа. Если у вас есть какие-либо другие проблемы, пожалуйста, задайте другой вопрос

4. @Oliort: изменено для путей в диапазоне (len(PATH_TO_IMAGE)): image = cv2.imread(PATH_TO_IMAGE[пути]) pilImage = Image.fromarray(изображение) и передано pilImage в visualize_boxes_and_labels_on_image_array. Получена ошибка np.copyto(изображение, np.array(image_pil)) Ошибка типа: аргумент copyto() 1 должен быть numpy.ndarray, а не Image

5. @Sharky Если какое-либо решение решит мою проблему, я обязательно приму его в качестве ответа