0

With Keras version 2.1.5 and tensorflow 1.6.0, yolov3 in Keras, I'm on a small project that detecting few cracks from the wall. In this step, i'm trying to extract frames out from my sample video, but I got some errors for some reasons that I can't solve.

Here the whole code below::

import os
from timeit import default_timer as timer
import yolo_video
import yolo
from yolo3.model import yolo_head, box_iou
from yolo3.model import yolo_eval, yolo_body, tiny_yolo_body, yolo_loss
from yolo3.utils import letterbox_image

from keras import backend as K
from keras.layers import input
from keras.models import load_model
from keras.preprocessing import image
from keras.optimizers import Adam
from keras.utils import multi_gpu_model

from PIL import Image, ImageFont, ImageDraw
from imageio import imread
import numpy as np
import tensorflow as tf
from matplotlib import pyplot as plt
import cv2

%matplotlib inline

Here for loading weight file

img_height = 416
img_width = 416

anchros_path = 'model_data/tiny_yolo_anchors.txt'
classes_path = 'classes.txt'
image_input = Input(shape=(None, None, 3))
weights_path = 'tiny_yolo_crack.h5'
model = load_model(weights_path, {'yolo_head':yolo_head, 'tf':tf, 'box_iou':box_iou}, False)
adam = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)

Here for extracting images from Video

vidcap = cv2.VideoCapture('sample.mp4')
success, imagefile = vidcap.read()
count = 0

while success:
    if(count%6==0):
       cv2.imwrite("Frames/frame%d.jpg" % count, imagefile)
    success, imagefile = vidcap.read()
    count+=1

orig_images = []
input_images = []

frames_count = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT))
print(frames_count)
for i in range(0, frames_count):
    if(i%6==0):
        img_path = 'Frames/frame%d.jpg'%i
        orig_images.append(imread(img_path))
        img = image.load_img(img_path, target_size=(img_height, img_width))
        img = image.img_to_array(img)
        img = np.array(img)
        input_images.append(img)

input_images = np.array(input_images)
orig_images = np.array(orig_images)

Here for input the number of frame images to be batch processed.

num_of_frames = 16
counting = 0
saving_bounding_boxes = []
isBreak = 0;

print("Predicted boxes: \n")
print('   class  conf  xmin  ymin  xmax  ymax')

for i in range(0, frames_count):
    y_pred = model.predict(input_images[i*num_of_frames: i*num_of_frames + num_of_frames])
confidence_threshold = 0.4

    y_pred_thresh = [y_pred[k][y_pred[k, :, 1] > confidence_threshold] for k in range(y_pred.shape[0])]
    np.set_printoptions(precision=2, suppress = True, linewidth = 90)

    for j in range(0, num_of_frames):
        print('frame :', counting)
        if(j > len(y_pred_thresh)): break;
        for box in y_pred_thresh[j]:
            xmin = box[2] * orig_images[0].shape[1] / img_width
            ymin = box[3] * orig_images[0].shape[0] / img_height
            xmax = box[4] * orig_images[0].shape[1] / img_width
            ymax = box[5] * orig_images[0].shape[0] / img_height
            print('xmin : ', xmin, ' ymin : ', ymin, ' xmax : ', xmax, ' ymax : ', ymax)
            saving_bounding_boxes.append([counting, xmin, ymin, xmax, ymax])
        counting += 6
        if(counting > frames_count):
            isBreak = 1;
            break;
    if(isBreak == 1): break;

Then I got this result::

Predicted boxes:
    class  conf xmin ymin xmax ymax
------------------------------------------------------

ValueError Traceback (most recent call last)
<ipython-input-14-78d4330555fe> in <module>()
    46
    47 for i in range(0, frames_count):
--->48     y_pred = model.predict(input_images[i*num_of_frames: i*num_of_frames + num_of_frames])
    49     confidence_threshold = 0.4
    50

------------------------------------------------------
/usr/local/lib/python3.6/dist-packages/keras/engine/training.py in _standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
    84             'Expected to see' + str(len(names)) + 'array(s), '
    85             'but instead got the following list of ' +
--->86             str(len(data)) + ' arrays: ' + str(data)[:200] + '...')
    87         elif len(names) > 1:
    88            raise ValueError(

ValueError: Error when checking model : the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 3 array(s), but instead got the following list of 1 arrays: [array([[[[41., 66., 71.], [32., 61., 56.], [26., 49., 81.], ..., [31., 36., 32.], [25., 30., 26.], [28., 33., 29.]], [...

It said I have array size problem, but I don't even know what is the problem exactly. I tried to put some elements in line 48,

y_pred = model.predict(input_images[i*num_of_frames: i*num_of_frames + num_of_frames])

for fitting numpy array size, but didn't sure what I should put it there.

I've been up all night for two days because of it. "How to fit numpy array size?"

Thank you.

Edit

I changed the code above.

# load the model
model = load_model('tiny_yolo.h5', {'yolo_head':yolo_head, 'tf':tf, 'box_iou':box_iou}, False)

input_height = 416
input_width = 416

orig_images = [] 
input_images = [] 

frames_count = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT))
print(frames_count)

def load_images(filename, shape):
    img = load_img(filename)
    height, width = img.size
    orig_images.append(imread(filename))
    img = load_img(filename, target_size = shape)
    img = img_to_array(img) # convert to numpy array
    img = np.array(img)
    return img, height, width
        
#for i in range(0, frames_count):
#    if(i%6==0):
#        img_filename = 'Frames/20200706_3/frame%d.jpg'%i
#        img, img_height, img_width = load_images(img_filename, (input_height, input_width))
#        input_images.append(img)

#test for single image
img, img_height, img_width = load_images(img_filename, (input_height, input_width))
#orig_images = np.array(orig_images)
#input_images = np.array(input_images)
#print(input_images)
#y_pred = model.predict([]) # Hmm
y_pred = model.predict(img)
Gorani
  • 1
  • 1
  • 2
  • Did you try to predict one image before stack them together in list named 'input_images'? – CuCaRot Jul 06 '20 at 07:58
  • I tried what u said like this, `img_path = 'Frames/frame6.jpg' img = image.load_img(img_path, target_size = (img_height, img_width)) img = image.img_to_array(img) img = np.array(img) y_pred = model.predict(img)` and it said, same error above. – Gorani Jul 06 '20 at 09:56
  • Did you clone the code from [this repo](https://github.com/qqwweee/keras-yolo3)? – CuCaRot Jul 06 '20 at 09:59
  • I don't know "what" should I put in "y_pred = model.predict(...)." I think it wants to get 3 arguments, Idk. – Gorani Jul 06 '20 at 10:03
  • Yes, and changed them little bit when I retrained them – Gorani Jul 06 '20 at 10:04
  • double check the shape of variable `img` if that is 416x416 or any shape that you use to train – CuCaRot Jul 06 '20 at 10:08
  • `img` has ndarray with shape(416, 416, 3). Something's wrong? **I added some text.** – Gorani Jul 06 '20 at 10:19
  • Just wanna check your code. I used to work with this repo before, but it is really hard to guess what is your problem, why you didn't use the inference way of that repo, using `sess.run` combined with `yolo_head` to get three output array. The inference code should be in file `yolo.py`, class `YOLO` in that repo. – CuCaRot Jul 06 '20 at 17:12
  • Sry, I don't understand what I should to use exactly. Do you mean `detect_image()` in `yolo.py`? – Gorani Jul 07 '20 at 02:05
  • yeah, that function, the author pre-process by a method named `letter_box` by him, so remove that part if you only used normal resize. I am not too familiar with `predict` function in keras, but I guess it because of the output form yolo. It is not a vector as normal classification problem, YOLO's output is three tensor with size (only true because you use 416x416 input) `13x13xM`, `26x26xM` and `52x52xM` with M depend on your classes number. So I think you should try that `detect_image()` function before try your own code – CuCaRot Jul 07 '20 at 16:54

0 Answers0