From 4f185e1998d823c10dcc189d68ad265e3df3b996 Mon Sep 17 00:00:00 2001 From: Joel Steffens <joel.steffens@stud.hs-bochum.de> Date: Mon, 22 May 2023 12:15:18 +0200 Subject: [PATCH] Programmstruktur mit Filterliste erweitert --- .gitignore | 4 +- filter_pipeline.py | 117 ++++++++++++++++++++++++++++++++ filters.py | 163 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 filter_pipeline.py create mode 100644 filters.py diff --git a/.gitignore b/.gitignore index ad61a4e..a5fbee1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ # Videos NICHT hochladen -/Videomaterial \ No newline at end of file +/Videomaterial + +/__pycache__ \ No newline at end of file diff --git a/filter_pipeline.py b/filter_pipeline.py new file mode 100644 index 0000000..c44ffcd --- /dev/null +++ b/filter_pipeline.py @@ -0,0 +1,117 @@ +import cv2 +import numpy as np +import matplotlib.pyplot as plt +import time +from datetime import datetime +import pandas as pd + +VIDEO = 'Videomaterial/WIN_20230414_13_41_55_Pro.mp4' +capture = cv2.VideoCapture(VIDEO) + + +last = None +frame = None +diff = None +window = 'Filter' + +# Einstellungen +min_threshold = 30 +max_threshold = 110 +img_threshold = 100 +line_threshold = 30 + +spanne = 2 + +def overlay_imgs(base, top): + topgray = cv2.cvtColor(top, cv2.COLOR_RGB2GRAY) + + _, mask = cv2.threshold(topgray, 10, 255, cv2.THRESH_BINARY) + mask_inv = cv2.bitwise_not(mask) + # Now black-out the area of overlay + img1_bg = cv2.bitwise_and(base,base,mask = mask_inv) + # Take only region of from logo image. + img2_fg = cv2.bitwise_and(top,top,mask = mask) + + return cv2.add(img1_bg, img2_fg) + +def nothing_cb(val): + pass + +# To control the Size of the Disply +cv2.namedWindow(window, cv2.WINDOW_AUTOSIZE) +cv2.createTrackbar('Line Threshold: ', window, line_threshold, 100, nothing_cb) + +import filters +pipeline = [ + ('Original', filters.none), + ('Gray scale', filters.grayscale), + ('Contrast and Blur', filters.medianBlur), + ('Video Diff', filters.video_absdiff), + ('Canny edge detection', filters.filter_canny), + ('Morph close', filters.filter_close), + #('Morph open', filters.filter_open), + ('Point extraction', filters.points_extract), + ('Polyfit lines', filters.points_overlay) +] + +state = {} # Empty dictionary to store filters state + +info = { + 'abs_diff': 5, # 5 images for difference, + 'dim': (1920, 1080), # + 'params': {} +} + +result = None +visible_filter_idx = 0 +while capture.isOpened(): + # ret is the stat of the reading + ret, frame = capture.read() + if ret == True: + frame, _ = filters.resize(None, frame, None) + + # Apply + info['params']['line'] = cv2.getTrackbarPos('Line Threshold: ', window) + + result = frame + for i, (name, filter) in enumerate(pipeline): + # Apply each filter + result, overlay = filter(info, result, state) + + if result is None: + break + + if visible_filter_idx == i: + image = result.copy() + + if overlay: + image = overlay_imgs(frame, image) + + cv2.putText(image, f'Filter #{i}: {name}', (10, 30), cv2.FONT_HERSHEY_PLAIN, + 1, (255, 0, 0), 2, cv2.LINE_AA) + cv2.imshow('Filter', image) + + + + code = cv2.waitKey(33) & 0xFF + if code == ord('s'): + now = datetime.now() + str = now.strftime("%d_%m_%Y_%H_%M_%S") + cv2.imwrite(f'Filter/IMG_{str}.png', result) + elif code == ord('d'): + visible_filter_idx += 1 + if visible_filter_idx >= len(pipeline): + visible_filter_idx = len(pipeline) - 1 + elif code == ord('a'): + visible_filter_idx -= 1 + if visible_filter_idx < 0: + visible_filter_idx = 0 + elif code & 0xFF == ord('q'): + break + + else: + break + +capture.release() + +cv2.destroyAllWindows() \ No newline at end of file diff --git a/filters.py b/filters.py new file mode 100644 index 0000000..af1770a --- /dev/null +++ b/filters.py @@ -0,0 +1,163 @@ +import cv2 as cv +import numpy as np +import pandas as pd + +def none(info, image, state): + return image, False + +# Resize image to 1280x720 pixels +def resize(info, image, state): + res = cv.resize(image, (1280, 720)) + return res, False + + +# Convert to Gray scale image +def grayscale(info, image, state): + res = cv.cvtColor(image, cv.COLOR_BGR2GRAY) + return res, False + +def medianBlur(info, image, state): + # median of all the pixels under the kernel area + blur = cv.medianBlur(image, 7) + # adding tow images + sharp = cv.addWeighted(image, 1.5, blur, -0.5, 0.0) + return sharp, False + +# def plot_points(x, y, px, py): +# fig = plt.figure() +# ax = fig.add_subplot() +# ax.scatter(px, py, c='r') +# ax.plot(x, y) +# ax.set_xlim([0, 1280]) +# ax.set_ylim([720, 0]) +# plt.show() + +spanne = 5 + +def find_points(image): + indices = np.where(image > 0) + if (indices[1].size > 0): + x_so = indices[1] + y_so = indices[0] + + list_xy = np.column_stack((x_so, y_so)).astype(np.int32) + # list_xy = np.sort(list_xy, axis=0) + # print( list_xy) + + df = pd.DataFrame(list_xy,columns=['x','y']) + + df = df.sort_values(by=['x'], ascending=True) + + n_list = [] + + df_un = df.x.unique() + for el in df_un[::2]: + + med = (df.y.where(df.x >= el-spanne).where(el+spanne >= df.x)).median() + n_list.append([el,med]) + + + n_list = np.array(n_list).astype(np.int32) + return n_list + + return None + + +def polyfit(n_list): + if n_list is not None: + p = np.polyfit(n_list[:,0], n_list[:,1], 6) + x = np.arange(n_list[:,0][0], n_list[:,0][-1], 1) + y = np.polyval(p,x) + points = np.column_stack((x, y)).astype(np.int32) + return points + + return None + +min_threshold = 30 +max_threshold = 110 + +def filter_canny(info, image, state): + image = cv.Canny(image, min_threshold, max_threshold) + return image, False + +def filter_open(info, image, state): + ksize = (3,3) + # kernel = np.ones(ksize,np.uint8) + kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, ksize) + image = cv.morphologyEx(image, cv.MORPH_OPEN, kernel) + + return image, False + +def filter_close(info, image, state): + ksize = (3,3) + # kernel = np.ones(ksize,np.uint8) + kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, ksize) + image = cv.morphologyEx(image, cv.MORPH_CLOSE, kernel) + + return image, False + + +def points_extract(info, image, state): + points = find_points(image) + overlay = np.zeros((image.shape[0], image.shape[1], 3), np.uint8) + + for y, x in points: + if x < image.shape[0] and y < image.shape[1]: + overlay[x, y] = (255, 0, 0) + + + #cv.polylines(overlay, [points], False, (255, 0, 0), thickness=1) + + state['points'] = points + return overlay, False + + +def points_overlay(info, image, state): + points = state['points'] + poly_points = polyfit(points) + + overlay = np.zeros((image.shape[0], image.shape[1], 3), np.uint8) + # draw a polygon on the image + cv.polylines(overlay, [poly_points], False, (255, 0, 0), thickness=5) + return overlay, True + +def filter_all(info, image, state): + image = image.copy() + + # construct a rectangular kernel from the current size / rect shaped kernel + kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (1,1)) + + # Opening operation + image = cv.morphologyEx(image, cv.MORPH_OPEN, kernel) + + # perform erosion on the image + image = cv.erode(image, (3,3)) + + # Closing operation / closing small holes + # image = cv2.morphologyEx(image, cv2.MORPH_CLOSE, (1,1)) + image = cv.morphologyEx(image, cv.MORPH_CLOSE, (5,5)) + # # image = cv2.morphologyEx(image, cv2.MORPH_CLOSE, (4,4)) + + # dilation + kernel2 = cv.getStructuringElement(cv.MORPH_ELLIPSE, (2,2)) + image = cv.dilate(image,kernel2,iterations = 1) + + # Use canny edge detection + image = cv.Canny(image, min_threshold, max_threshold) + + points = find_points(image) + overlay = np.zeros((image.shape[0], image.shape[1], 3), np.uint8) + # draw a polygon on the image + cv.polylines(overlay, [points], False, (255, 0, 0), thickness=6) + return overlay, True + + +def video_absdiff(info, image, state): + if 'last' not in state or state['last'] is None: + state['last'] = image + return None, False + + diff = cv.absdiff(image, state['last']) + state['last'] = image + return diff, False + -- GitLab