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)