Created
December 15, 2019 19:28
-
-
Save smellslikeml/a3d6dfb3d06e393528ccc63fa3afb549 to your computer and use it in GitHub Desktop.
A simple script to perform webcam visual anomaly detection with autoencoders built with Keras
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
from __future__ import absolute_import, print_function | |
import cv2 | |
import numpy as np | |
from time import sleep, time | |
from collections import deque | |
from tensorflow.keras.models import Model | |
from tensorflow.keras.optimizers import RMSprop | |
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D, ZeroPadding2D | |
from tensorflow.keras.callbacks import History | |
def build_model(img_size=32): | |
input_img = Input(shape=(img_size, img_size, 1)) | |
x = Conv2D(32, (5, 5), activation='relu', padding='same')(input_img) | |
x = MaxPooling2D((2, 2), padding='same')(x) | |
x = Conv2D(8, (3, 3), activation='relu', padding='same')(x) | |
encoded = MaxPooling2D((2, 2), padding='same', name='encoder')(x) | |
x = Conv2D(8, (3, 3), activation='relu', padding='same')(encoded) | |
x = UpSampling2D((2, 2))(x) | |
x = Conv2D(32, (3, 3), activation='relu', padding='same')(x) | |
x = UpSampling2D((2, 2))(x) | |
decoded = Conv2D(1, (5, 5), activation='sigmoid', padding='same')(x) | |
autoencoder = Model(input_img, decoded) | |
autoencoder.compile(optimizer=RMSprop(lr=lr), loss='binary_crossentropy') | |
return autoencoder | |
def load_run_render(frame): | |
im = cv2.resize(frame, (img_size, img_size)) | |
im = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY) | |
im = np.expand_dims(np.expand_dims(im, axis=0).astype(np.float32), axis=-1) / 255 | |
history = History() | |
start_time = time() | |
autoencoder.fit(im, im, | |
epochs=1, | |
batch_size=1, | |
shuffle=True, | |
callbacks=[history]) | |
end_time = time() | |
return history.history['loss'][-1] | |
def main(): | |
# Begin Video Capture | |
cam = cv2.VideoCapture(0) | |
idx = 0 | |
while True: | |
try: | |
ret, frame = cam.read() | |
ts = int(time() * 1000) | |
print(idx) | |
if ret: | |
loss = load_run_render(frame) | |
q.append(loss) | |
if len(q) > 50: | |
prev_hist = list(q)[:-1] | |
threshold = 5 * np.std(prev_hist) | |
if np.abs(loss - np.mean(prev_hist)) > threshold: | |
print(loss, 'anomaly') | |
else: | |
print(loss, 'normal') | |
else: | |
pass | |
except Exception as e: | |
print(e) | |
pass | |
sleep(DELAY) | |
idx += 1 | |
if __name__ == '__main__': | |
# Declare Parameters | |
lr = 1e-4 | |
DELAY = 0.2 | |
img_size=128 | |
q = deque(maxlen=300) | |
# Build the Autoencoder | |
autoencoder = build_model(img_size=img_size) | |
# Run the Training/Inference Loop | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment