Python: Как изменить форму массива на основе ввода изображения? - PullRequest
0 голосов
/ 24 сентября 2018

У меня есть функция, которая применяет операцию маскирования к входным изображениям следующим образом:

file_names = glob(os.path.join(IMAGE_DIR, "*.jpg"))
masks_prediction = np.zeros((2000, 2000, len(file_names)))
for i in range(len(file_names)):
    print(i)
    image = skimage.io.imread(file_names[i])
    predictions = model.detect([image],  verbose=1)
    p = predictions[0]
    masks = p['masks']
    merged_mask = np.zeros((masks.shape[0], masks.shape[1]))
    for j in range(masks.shape[2]):
        merged_mask[masks[:,:,j]==True] = True
        masks_prediction[:,:,i] = merged_mask
print(masks_prediction.shape)

Таким образом, в основном она считывает все изображения из каталога, создает маску для каждого и запускает обнаружение.

Однако, поскольку изображения имеют разные размеры, это не работает:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-10-764e6229811a> in <module>()
     10     for j in range(masks.shape[2]):
     11         merged_mask[masks[:,:,j]==True] = True
---> 12         masks_prediction[:,:,i] = merged_mask
     13 print(masks_prediction.shape)

ValueError: could not broadcast input array from shape (1518,1077) into shape (2000,2000)

Я думал о том, как узнать размер каждого изображения до применения операции маски (перед строкой 12 в сообщении об ошибке), таким образом передав точный размер формы изображения правильно для операции маскирования.

Возможно ли это как-то в Python?

РЕДАКТИРОВАТЬ: Так что, очевидно, люди почему-то не получили того, чего я хотел достичь - хотя я искренне верю, что это было написано вочень простой способ.Тем не менее, вот весь код (скопированный из записной книжки ipython), где находится функция:

import os
import sys
import random
import math
import re
import time
import numpy as np
import tensorflow as tf
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import skimage.draw

# Root directory of the project
ROOT_DIR = os.path.abspath("../../")

# Import Mask RCNN
sys.path.append(ROOT_DIR)  # To find local version of the library
from mrcnn import utils
from mrcnn import visualize
from mrcnn.visualize import display_images
import mrcnn.model as modellib
from mrcnn.model import log
from glob import glob


import components

%matplotlib inline 

# Directories to be referred
MODEL_DIR = os.path.join(ROOT_DIR, "logs")
IMAGE_DIR = os.path.join(ROOT_DIR, "datasets/components/back/predict")
ANNOTATION_DIR = os.path.join(ROOT_DIR, "datasets/components/front/")
WEIGHTS_PATH = os.path.join(ROOT_DIR, "logs/back/mask_rcnn_components_0100.h5")

config = components.ComponentsConfig()
# Override the training configurations with a few
# changes for inferencing.
class InferenceConfig(config.__class__):
# Run detection on one image at a time
GPU_COUNT = 1
IMAGES_PER_GPU = 1

 config = InferenceConfig()
 config.display()
 # Create model in inference mode
with tf.device(DEVICE):
    model = modellib.MaskRCNN(mode="inference", model_dir=MODEL_DIR,
                              config=config)
# Load weights
print("Loading weights ", WEIGHTS_PATH)
model.load_weights(WEIGHTS_PATH, by_name=True)

file_names = glob(os.path.join(IMAGE_DIR, "*.jpg"))
masks_prediction = np.zeros((2000, 2000, len(file_names)))
for i in range(len(file_names)):
    print(i)
    image = skimage.io.imread(file_names[i])
    predictions = model.detect([image],  verbose=1)
    p = predictions[0]
    masks = p['masks']
    merged_mask = np.zeros((masks.shape[0], masks.shape[1]))
    for j in range(masks.shape[2]):
        merged_mask[masks[:,:,j]==True] = True
        masks_prediction[:,:,i] = merged_mask
print(masks_prediction.shape)

dataset = components.ComponentsDataset()
dataset.load_components(ANNOTATION_DIR, "predict")

accuracy = 0
precision = 0
for image_id in range(len(dataset.image_info)):
    name = dataset.image_info[image_id]['id']
    file_name = os.path.join(IMAGE_DIR, name)
    image_id_pred = file_names.index(file_name)
    merged_mask = masks_prediction[:, :, image_id_pred]

    annotated_mask = dataset.load_mask(image_id)[0]
    merged_annotated_mask = np.zeros((510, 510))
    for i in range(annotated_mask.shape[2]):
        merged_annotated_mask[annotated_mask[:,:,i]==True] = True
    accuracy  += np.sum(merged_mask==merged_annotated_mask) / (1200 * 1600)
    all_correct = np.sum(merged_annotated_mask[merged_mask == 1])
    precision += all_correct / (np.sum(merged_mask))
print('accuracy:{}'.format(accuracy / len(file_names)))
print('precision:{}'.format(precision / len(file_names)))

file_names = glob(os.path.join(IMAGE_DIR, "*.jpg"))
class_names = ['BG', 'screw', 'lid']
test_image = skimage.io.imread(file_names[random.randint(0,len(file_names)-1)])
predictions = model.detect([test_image], verbose=1) # We are replicating the same image to fill up the batch_size
p = predictions[0]
visualize.display_instances(test_image, p['rois'], p['masks'], p['class_ids'], 
                            class_names, p['scores'])

1 Ответ

0 голосов
/ 24 сентября 2018

Изображение представляет собой просто массив.Поэтому, чтобы ответить на ваш вопрос «возможно ли узнать размер каждого изображения»: Да, просто используйте shape изображения.

Если вы работаете со многими изображениями разных размеров, это может привести ксмысл изменять их размер до единого разрешения.skimage имеет для этого встроенную функциональность, метод skimage.transform.resize.Посмотрите документы здесь .

Если вы используете изменение размера, вы должны убедиться, что в ваших изображениях нет артефактов.Проверьте результат операции изменения размера, прежде чем использовать его.

Изменение размера skimage происходит довольно медленно.Если вам нужно больше производительности, вы можете использовать opencv.У них отличный Python API, и, поскольку существует пакет conda , установка стала действительно простой.

resized_images = []
file_names = glob(os.path.join(IMAGE_DIR, "*.jpg")) 
for i in range(len(file_names)):
    print("Resizing: " + str(i))
    image = skimage.io.imread(file_names[i])
    image_resized = resize(image, (1200, 800),anti_aliasing=True)
    resized_images.append(image_resized)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...