Я пытаюсь создать программу, которая классифицирует ASL поет. Я создал свой собственный набор данных с 6 знаками для тестирования.
Как я создал набор данных?
Я использовал алгоритм вычитания фона с использованием скользящих средних. Итак, после вычитания фона я получаю изображение в оттенках серого с фоном черного цвета (0) и моей руки белым (255). Я постоянно продолжаю двигать рукой для изменения изображения. Я включил камеру своей веб-камеры и сохранил каждый кадр из живого видео в папку.
Данные тренировки
Я использовал модель keras CNN для обучения набора данных. Ниже приведен код для обучения.
data_dir = "../input/dataset"
target_size = (64, 64)
target_dims = (64, 64, 3) # add channel for RGB
n_classes = 29
val_frac = 0.1
batch_size = 64
data_augmentor = ImageDataGenerator(samplewise_center=False,
samplewise_std_normalization=False,
validation_split=val_frac)
train_generator = data_augmentor.flow_from_directory(data_dir, target_size=target_size, batch_size=batch_size, shuffle=True, subset="training")
val_generator = data_augmentor.flow_from_directory(data_dir, target_size=target_size, batch_size=batch_size, subset="validation")
my_model = Sequential()
my_model.add(Conv2D(64, kernel_size=4, strides=1, activation='relu', input_shape=target_dims))
my_model.add(Conv2D(64, kernel_size=4, strides=2, activation='relu'))
my_model.add(Dropout(0.5))
my_model.add(Conv2D(128, kernel_size=4, strides=1, activation='relu'))
my_model.add(Conv2D(128, kernel_size=4, strides=2, activation='relu'))
my_model.add(Dropout(0.5))
my_model.add(Conv2D(256, kernel_size=4, strides=1, activation='relu'))
my_model.add(Conv2D(256, kernel_size=4, strides=2, activation='relu'))
my_model.add(Flatten())
my_model.add(Dropout(0.5))
my_model.add(Dense(512, activation='relu'))
my_model.add(Dense(n_classes, activation='softmax'))
my_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=["accuracy"])
my_model.fit_generator(train_generator, epochs=5, validation_data=val_generator)
my_model.save('new.h5')
Как я предсказал изображение?
Используя тот же код вычитания фона, я использую окончательное пороговое изображение (черно-белое изображение), чтобы отправить его в мою модель для прогнозирования. перед отправкой я просто изменяю размер и изменяю форму изображения.
Проблема
Даже после получения точности выше 95% я не могу получить точные прогнозы при запуске его на живой камере. Я запускаю камеру и использую вычитание фона, чтобы получить черно-белое изображение, и отправляю каждое изображение после изменения формы и изменения размера в модель для прогнозов. Но я не получаю точных ответов.
ПРОГРАММА ПРОГНОЗИРОВАНИЯ
import cv2
import imutils
import numpy as np
# global variables
bg = None
def run_avg(image, aWeight):
global bg
# initialize the background
if bg is None:
bg = image.copy().astype("float")
return
# compute weighted average, accumulate it and update the background
cv2.accumulateWeighted(image, bg, aWeight)
def segment(image, threshold=25):
global bg
# find the absolute difference between background and current frame
diff = cv2.absdiff(bg.astype("uint8"), image)
# threshold the diff image so that we get the foreground
thresholded = cv2.threshold(diff,
threshold,
255,
cv2.THRESH_BINARY)[1]
# get the contours in the thresholded image
(cnts, _) = cv2.findContours(thresholded.copy(),
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
# return None, if no contours detected
if len(cnts) == 0:
return
else:
# based on contour area, get the maximum contour which is the hand
segmented = max(cnts, key=cv2.contourArea)
return (thresholded, segmented)
if __name__ == "__main__":
# initialize weight for running average
aWeight = 0.5
# get the reference to the webcam
camera = cv2.VideoCapture(0)
# region of interest (ROI) coordinates
top, right, bottom, left = 10, 350, 225, 590
# initialize num of frames
num_frames = 0
# keep looping, until interrupted
while(True):
# get the current frame
(grabbed, frame) = camera.read()
# resize the frame
frame = imutils.resize(frame, width=700)
# flip the frame so that it is not the mirror view
frame = cv2.flip(frame, 1)
# clone the frame
clone = frame.copy()
# get the height and width of the frame
(height, width) = frame.shape[:2]
# get the ROI
roi = frame[top:bottom, right:left]
# convert the roi to grayscale and blur it
gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (7, 7), 0)
# to get the background, keep looking till a threshold is reached
# so that our running average model gets calibrated
if num_frames < 30:
run_avg(gray, aWeight)
else:
# segment the hand region
hand = segment(gray)
# check whether hand region is segmented
if hand is not None:
# if yes, unpack the thresholded image and
# segmented region
(thresholded, segmented) = hand
# draw the segmented region and display the frame
cv2.drawContours(clone, [segmented + (right, top)], -1, (0, 0, 255))
cv2.imshow("Thesholded", thresholded)
RESHAPE--> thresholded = cv2.resize(roi,(64,64))
RESIZE--> thresholded = np.reshape(thresholded,[1,64,64,3])
Predict--> classes = classifier.predict_classes(thresholded)
print(classes)
# draw the segmented hand
cv2.rectangle(clone, (left, top), (right, bottom), (0,255,0), 2)
# increment the number of frames
num_frames += 1
# display the frame with segmented hand
cv2.imshow("Video Feed", clone)
# observe the keypress by the user
keypress = cv2.waitKey(1) & 0xFF
# if the user pressed "q", then stop looping
if keypress == ord("q"):
break
# free up memory
camera.release()
cv2.destroyAllWindows()