From 977b683d40474d3a11f78343d126b734ab9dc474 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 20:09:14 +0000 Subject: [PATCH] Refactor: Deduplicate SW labs from image processing course folder - Moved `sw_s01e*.py` files from `image_processing_course` to `vision_systems` - Replaced the overlapping files in `vision_systems` - Maintained the `ipc_` files in `image_processing_course` - Moved `s01eTestPreparation.py` and `s01e03.py` to `vision_systems` - Cleaned up duplicated items Co-authored-by: Michal-Fularz <3768498+Michal-Fularz@users.noreply.github.com> --- image_processing_course/s01e03.py | 136 ------------ image_processing_course/sw_s01e05.py | 135 ------------ image_processing_course/sw_s01e09.py | 70 ------ image_processing_course/sw_s01e10.py | 71 ------- vision_systems/s01e03.py | 18 +- vision_systems/s01e05.py | 201 +++++++----------- vision_systems/s01e09.py | 125 +++++------ vision_systems/s01e10.py | 78 ++++--- .../sw_s01e11.py => vision_systems/s01e11.py | 0 .../s01eTestPreparation.py | 0 10 files changed, 190 insertions(+), 644 deletions(-) delete mode 100644 image_processing_course/s01e03.py delete mode 100644 image_processing_course/sw_s01e05.py delete mode 100644 image_processing_course/sw_s01e09.py delete mode 100644 image_processing_course/sw_s01e10.py rename image_processing_course/sw_s01e11.py => vision_systems/s01e11.py (100%) rename {image_processing_course => vision_systems}/s01eTestPreparation.py (100%) diff --git a/image_processing_course/s01e03.py b/image_processing_course/s01e03.py deleted file mode 100644 index e1f4cd6..0000000 --- a/image_processing_course/s01e03.py +++ /dev/null @@ -1,136 +0,0 @@ -import time - -import cv2 -import numpy as np -from matplotlib import pyplot as plt - - -def empty_callback(value): - pass - - -def ex_1(): - def load_image_and_filer(image_filename): - img = cv2.imread(image_filename, cv2.IMREAD_COLOR) - - cv2.namedWindow('img') - cv2.createTrackbar('kernel_size', 'img', 0, 50, empty_callback) - - key = ord('a') - while key != ord('q'): - kernel_size = 1 + 2*cv2.getTrackbarPos('kernel_size', 'img') # 1, 3, 5, 7, 9, 11 - - img_after_blur = cv2.blur(img, (kernel_size, kernel_size)) - img_after_gaussian = cv2.GaussianBlur(img, (kernel_size, kernel_size), 0) - img_after_median = cv2.medianBlur(img, kernel_size) - - cv2.imshow('img', img) - cv2.imshow('img_after_blur', img_after_blur) - cv2.imshow('img_after_gaussian', img_after_gaussian) - cv2.imshow('img_after_median', img_after_median) - key = cv2.waitKey(10) - - cv2.destroyAllWindows() - - load_image_and_filer('../_data/s01e03/lenna_noise.bmp') - load_image_and_filer('../_data/s01e03/lenna_salt_and_pepper.bmp') - - -def ex_2(): - # element = - # [ 0 1 0 - # 1 0 1 - # 0 1 0 ] - img = cv2.imread('../_data/no_idea.jpg', cv2.IMREAD_GRAYSCALE) - - cv2.namedWindow('img') - cv2.createTrackbar('threshold', 'img', 0, 255, empty_callback) - cv2.createTrackbar('kernel_size', 'img', 1, 10, empty_callback) - cv2.createTrackbar('0: erosion, 1: dilation', 'img', 0, 1, empty_callback) - - key = ord('a') - while key != ord('q'): - threshold = cv2.getTrackbarPos('threshold', 'img') - kernel_size = 1 + 2 * cv2.getTrackbarPos('kernel_size', 'img') - operation_type = cv2.getTrackbarPos('0: erosion, 1: dilation', 'img') - - _, img_after_threshold = cv2.threshold(img, threshold, 255, cv2.THRESH_BINARY) - - kernel = np.ones((kernel_size, kernel_size), np.uint8) - - if operation_type == 0: - img_after_morphological = cv2.erode(img_after_threshold, kernel, iterations=1) - else: - img_after_morphological = cv2.dilate(img_after_threshold, kernel, iterations=1) - - cv2.imshow('img', img) - cv2.imshow('img_after_threshold', img_after_threshold) - cv2.imshow('img_after_morphological', img_after_morphological) - key = cv2.waitKey(50) - - cv2.destroyAllWindows() - - -def ex_3(): - img: np.ndarray = cv2.imread('../_data/no_idea.jpg', cv2.IMREAD_COLOR) - - if len(img.shape) == 2: - print('grayscale') - elif len(img.shape) == 3: - print('color') - else: - raise ValueError('Too many channels') - - cpy = np.array(img) - - start_time = time.time() - - for i in range(0, 1): - window_size = 3 # 3x3 - kernel_size = window_size // 2 - for i in range(kernel_size, cpy.shape[0] - kernel_size): - for j in range(kernel_size, cpy.shape[1] - kernel_size): - tmp = np.full((1, 3), 0, dtype=np.float64) - # tmp = 0 - for k in range(-kernel_size, 1+kernel_size): - for l in range(-kernel_size, 1+kernel_size): - tmp += img[i + k, j + l] - cpy[i, j] = np.round(tmp / (window_size*window_size)) - - print("for loop --- %s seconds ---" % (time.time() - start_time)) - - start_time = time.time() - for i in range(0, 1000): - img_blurred = cv2.blur(img, (3, 3)) - print("cv2.blur --- %s seconds ---" % (time.time() - start_time)) - - start_time = time.time() - kernel = np.full((3, 3), 1/9, dtype=np.float32) - for i in range(0, 1000): - img_filter2d = cv2.filter2D(img, -1, kernel=kernel) - print("cv2.filter2d --- %s seconds ---" % (time.time() - start_time)) - - print(f'blur - filter2d same: {np.array_equal(img_blurred, img_filter2d)}') - print(f'blur - for loop same: {np.array_equal(img_blurred[1:-1, 1:-1], cpy[1:-1, 1:-1])}') - print(f'for loop - filter2d same: {np.array_equal(cpy[1:-1, 1:-1], img_filter2d[1:-1, 1:-1])}') - - key = ord('a') - while key != ord('q'): - - cv2.imshow('img', img) - cv2.imshow('cpy', cpy) - cv2.imshow('img_blurred', img_blurred) - cv2.imshow('img_filter2d', img_filter2d) - key = cv2.waitKey(50) - - cv2.destroyAllWindows() - - -def main(): - ex_1() - ex_2() - ex_3() - - -if __name__ == '__main__': - main() diff --git a/image_processing_course/sw_s01e05.py b/image_processing_course/sw_s01e05.py deleted file mode 100644 index 4d30148..0000000 --- a/image_processing_course/sw_s01e05.py +++ /dev/null @@ -1,135 +0,0 @@ -import cv2 -import numpy as np - -# https://docs.google.com/document/d/11gjO980jxlltTpR_JJ4SQ_DFSq0Bipb7NMH-j9LH6Cs/edit?usp=sharing - - -def _gradient_operator( - img: np.ndarray, - kernel_x: np.ndarray, - kernel_y: np.ndarray, - divider: int, - window_name_prefix: str -): - img_gradient_x = cv2.filter2D(img, cv2.CV_32F, kernel_x) - img_gradient_y = cv2.filter2D(img, cv2.CV_32F, kernel_y) - - img_gradient = cv2.sqrt(pow(img_gradient_x / divider, 2) + pow(img_gradient_y / divider, 2)) - - cv2.imshow(f'{window_name_prefix}_x', (abs(img_gradient_x) / divider).astype(np.uint8)) - cv2.imshow(f'{window_name_prefix}_x_no_abs', (img_gradient_x / divider).astype(np.uint8)) - cv2.imshow(f'{window_name_prefix}_y', (abs(img_gradient_y) / divider).astype(np.uint8)) - cv2.waitKey(0) - cv2.imshow(f'{window_name_prefix}', img_gradient.astype(np.uint8)) - cv2.waitKey(0) - cv2.destroyAllWindows() - - -def ex_1(): - img_grayscale = cv2.imread('./../_data/no_idea.jpg', cv2.IMREAD_GRAYSCALE) - - kernel_prewitt_x = np.array( - [[1, 0, -1], - [1, 0, -1], - [1, 0, -1]], - np.int8 - ) - kernel_prewitt_y = np.array( - [[1, 1, 1], - [0, 0, 0], - [-1, -1, -1]], - np.int8 - ) - print(kernel_prewitt_x) - print(kernel_prewitt_y) - - kernel_sobel_x = np.array( - [[1, 0, -1], - [2, 0, -2], - [1, 0, -1]], - np.int8 - ) - kernel_sobel_y = np.array( - [[1, 2, 1], - [0, 0, 0], - [-1, -2, -1]], - np.int8 - ) - - _gradient_operator(img_grayscale, kernel_prewitt_x, kernel_prewitt_y, 3, 'img_prewitt') - _gradient_operator(img_grayscale, kernel_sobel_x, kernel_sobel_y, 4, 'img_sobel') - - -def ex_2(): - def trackbar_callback(x): - pass - - window_name = 'Canny' - - img_grayscale = cv2.imread('./../_data/no_idea.jpg', cv2.IMREAD_GRAYSCALE) - - cv2.namedWindow(window_name) - cv2.createTrackbar('threshold1', window_name, 0, 255, trackbar_callback) - cv2.createTrackbar('threshold2', window_name, 0, 255, trackbar_callback) - - key = ord('a') - while key != ord('q'): - threshold1 = cv2.getTrackbarPos('threshold1', window_name) - threshold2 = cv2.getTrackbarPos('threshold2', window_name) - img_canny = cv2.Canny(img_grayscale, threshold1, threshold2) - - cv2.imshow(window_name, img_canny) - key = cv2.waitKey(100) - cv2.destroyAllWindows() - - -def ex_3(): - img = cv2.imread('./../_data/sw_s01e05/shapes.jpg', cv2.IMREAD_COLOR) - # NOTE(MF): changing size of the image requires modification of parameters. - # eg. for HoughLines threhold for accumulator - # img = cv2.resize(img, None, fx=0.5, fy=0.5) - img_grayscale = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) - edges = cv2.Canny(img_grayscale, 50, 150, apertureSize=3) - cv2.imshow('edges', edges) - - img_hough_lines = np.copy(img) - hough_lines = cv2.HoughLines(edges, 1.5, np.pi / 180, 200) - for line in hough_lines: - rho, theta = line[0] - a = np.cos(theta) - b = np.sin(theta) - x0 = a * rho - y0 = b * rho - x1 = int(x0 + 1000 * (-b)) - y1 = int(y0 + 1000 * (a)) - x2 = int(x0 - 1000 * (-b)) - y2 = int(y0 - 1000 * (a)) - cv2.line(img_hough_lines, (x1, y1), (x2, y2), (0, 0, 255), 2) - cv2.imshow('hough_lines', img_hough_lines) - cv2.waitKey(0) - - img_hough_lines_p = np.copy(img) - hough_lines_p = cv2.HoughLinesP(edges, 1, np.pi / 180, 50, minLineLength=30, maxLineGap=10) - for line in hough_lines_p: - x1, y1, x2, y2 = line[0] - cv2.line(img_hough_lines_p, (x1, y1), (x2, y2), (0, 0, 255), 2) - cv2.imshow('hough_lines_p', img_hough_lines_p) - cv2.waitKey(0) - - img_hough_circles = np.copy(img) - circles = cv2.HoughCircles(img_grayscale, cv2.HOUGH_GRADIENT, 1, 100, param1=50, param2=30, minRadius=10, maxRadius=100) - circles = np.uint16(np.around(circles)) - for i in circles[0, :]: - # draw the outer circle - cv2.circle(img_hough_circles, (i[0], i[1]), i[2], (0, 255, 0), 2) - # draw the center of the circle - cv2.circle(img_hough_circles, (i[0], i[1]), 2, (0, 0, 255), 3) - cv2.imshow('hough_circles', img_hough_circles) - cv2.waitKey(0) - cv2.destroyAllWindows() - - -if __name__ == '__main__': - ex_1() - ex_2() - ex_3() diff --git a/image_processing_course/sw_s01e09.py b/image_processing_course/sw_s01e09.py deleted file mode 100644 index dfd39e5..0000000 --- a/image_processing_course/sw_s01e09.py +++ /dev/null @@ -1,70 +0,0 @@ -import cv2 -import numpy as np - - -def task_1(): - image = cv2.imread('./../_data/sw_s01e09/img_21130751_0005.bmp') - - flag_found, corners = cv2.findChessboardCorners(image, (8, 5)) - print(f'len(corners): {len(corners)}') - image_with_corners_raw = cv2.drawChessboardCorners(image, (8, 5), corners, flag_found) - cv2.imshow('image_with_corners_raw', image_with_corners_raw) - cv2.waitKey(0) - - if flag_found: - print(corners[0]) - - print('Corners found, refining their positions') - corners = cv2.cornerSubPix( - cv2.cvtColor(image, cv2.COLOR_BGR2GRAY), - corners, (11, 11), (-1, -1), - (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.1) - ) - print(corners[0]) - - # prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0) - object_points = np.zeros((8 * 5, 3), np.float32) - print(object_points[1]) - print(object_points.shape) - object_points[:, :2] = np.mgrid[0:8, 0:5].T.reshape(-1, 2) - print(object_points[1]) - print(object_points.shape) - - object_points_for = [] # np.zeros_like(object_points) - for i in range(0, 5): - for j in range(0, 8): - # print(object_points_for[i, j]) - # object_points_for[i, j] = [i, j, 0] - object_points_for.append([j, i, 0]) - object_points_for = np.array(object_points_for, dtype=np.float32) - - print(f'(object_points[0:3]: {object_points[0:3]}') - print(object_points.shape) - print(f'object_points_for[0:3]: {object_points_for[0:3]}') - print(object_points_for.shape) - - image_points = [corners] # [corners1, corners2, corners3] - object_points = [object_points] # [object_points1, object_points2, object_points3] - retval, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.calibrateCamera(object_points, image_points, image.shape[:2], None, None) - - fovx, fovy, focalLength, principalPoint, aspectRatio = cv2.calibrationMatrixValues( - camera_matrix, image.shape[:2], 7.2, 5.4 - ) - print(fovx) - print(fovy) - print(focalLength) - - img_undistorted = cv2.undistort(image, camera_matrix, dist_coeffs) - cv2.imshow('img_undistorted', img_undistorted) - cv2.waitKey(0) - - else: - print('Corners not found') - - image_with_corners = cv2.drawChessboardCorners(image, (8, 5), corners, flag_found) - cv2.imshow('image_with_corners', image_with_corners) - cv2.waitKey(0) - - -if __name__ == '__main__': - task_1() diff --git a/image_processing_course/sw_s01e10.py b/image_processing_course/sw_s01e10.py deleted file mode 100644 index 73704f6..0000000 --- a/image_processing_course/sw_s01e10.py +++ /dev/null @@ -1,71 +0,0 @@ -# solution for very slow application start when opening camera -# more details: https://github.com/opencv/opencv/issues/17687 -import os -os.environ['OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS'] = '0' - -import cv2 -import numpy as np - -import time - - -def ex_1(): - def empty(_): - pass - - cv2.namedWindow('current_frame') - cv2.namedWindow('background') - cv2.namedWindow('foreground') - - cv2.createTrackbar('threshold', 'current_frame', 20, 255, empty) - - cap = cv2.VideoCapture(0) - # alternative solution to the one with setting the env variable is to use DSHOW, - # however, it might reduce the achievable fps - # cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) - - img_gray = cv2.cvtColor(cap.read()[1], cv2.COLOR_BGR2GRAY) - img_current = np.copy(img_gray) - img_background = np.copy(img_gray) - img_foreground = np.copy(img_gray) - - backSub = cv2.createBackgroundSubtractorMOG2() - # backSub = cv2.createBackgroundSubtractorKNN() - - key = ord(' ') - while key != ord('q'): - _, frame = cap.read() - img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) - - fgMask = backSub.apply(frame) - - # background update - # if key == ord('a'): - # img_background = np.copy(img_current) - img_background[img_background < img_current] += 1 - img_background[img_background > img_current] -= 1 - - # elif key == ord('x'): - img_current = np.copy(img_gray) - - img_diff = cv2.absdiff(img_background, img_current) - kernel = np.ones((5, 5), np.uint8) - img_closed = cv2.morphologyEx(img_diff, cv2.MORPH_OPEN, kernel) - - t = cv2.getTrackbarPos('threshold', 'current_frame') - _, img_thresholded = cv2.threshold(img_closed, t, 255, cv2.THRESH_BINARY) - - cv2.imshow('current_frame', img_current) - cv2.imshow('background', img_background) - cv2.imshow('foreground', img_thresholded) - cv2.imshow('fgMask', fgMask) - - key = cv2.waitKey(20) - - cap.release() - cv2.destroyAllWindows() - - -if __name__ == '__main__': - print('Hello lab 10!') - ex_1() diff --git a/vision_systems/s01e03.py b/vision_systems/s01e03.py index 9903bc2..e1f4cd6 100644 --- a/vision_systems/s01e03.py +++ b/vision_systems/s01e03.py @@ -97,22 +97,22 @@ def ex_3(): tmp += img[i + k, j + l] cpy[i, j] = np.round(tmp / (window_size*window_size)) - print("--- %s seconds ---" % (time.time() - start_time)) + print("for loop --- %s seconds ---" % (time.time() - start_time)) start_time = time.time() for i in range(0, 1000): img_blurred = cv2.blur(img, (3, 3)) - print("--- %s seconds ---" % (time.time() - start_time)) + print("cv2.blur --- %s seconds ---" % (time.time() - start_time)) start_time = time.time() kernel = np.full((3, 3), 1/9, dtype=np.float32) for i in range(0, 1000): img_filter2d = cv2.filter2D(img, -1, kernel=kernel) - print("--- %s seconds ---" % (time.time() - start_time)) + print("cv2.filter2d --- %s seconds ---" % (time.time() - start_time)) - print(np.array_equal(img_blurred, img_filter2d)) - print(np.array_equal(img_blurred[1:-1, 1:-1], cpy[1:-1, 1:-1])) - print(np.array_equal(cpy[1:-1, 1:-1], img_filter2d[1:-1, 1:-1])) + print(f'blur - filter2d same: {np.array_equal(img_blurred, img_filter2d)}') + print(f'blur - for loop same: {np.array_equal(img_blurred[1:-1, 1:-1], cpy[1:-1, 1:-1])}') + print(f'for loop - filter2d same: {np.array_equal(cpy[1:-1, 1:-1], img_filter2d[1:-1, 1:-1])}') key = ord('a') while key != ord('q'): @@ -121,16 +121,14 @@ def ex_3(): cv2.imshow('cpy', cpy) cv2.imshow('img_blurred', img_blurred) cv2.imshow('img_filter2d', img_filter2d) - # cv2.imshow('img_own_blur', img_after_threshold) - # cv2.imshow('img_after_morphological', img_after_morphological) key = cv2.waitKey(50) cv2.destroyAllWindows() def main(): - # ex_1() - # ex_2() + ex_1() + ex_2() ex_3() diff --git a/vision_systems/s01e05.py b/vision_systems/s01e05.py index 4f4abc5..4d30148 100644 --- a/vision_systems/s01e05.py +++ b/vision_systems/s01e05.py @@ -1,32 +1,33 @@ import cv2 import numpy as np +# https://docs.google.com/document/d/11gjO980jxlltTpR_JJ4SQ_DFSq0Bipb7NMH-j9LH6Cs/edit?usp=sharing -def _gradient_operation( + +def _gradient_operator( img: np.ndarray, - kernel_x, + kernel_x: np.ndarray, kernel_y: np.ndarray, - divider: int + divider: int, + window_name_prefix: str ): - pass + img_gradient_x = cv2.filter2D(img, cv2.CV_32F, kernel_x) + img_gradient_y = cv2.filter2D(img, cv2.CV_32F, kernel_y) + img_gradient = cv2.sqrt(pow(img_gradient_x / divider, 2) + pow(img_gradient_y / divider, 2)) -def ex_1(): - img = cv2.imread('../_data/no_idea.jpg', cv2.IMREAD_GRAYSCALE) + cv2.imshow(f'{window_name_prefix}_x', (abs(img_gradient_x) / divider).astype(np.uint8)) + cv2.imshow(f'{window_name_prefix}_x_no_abs', (img_gradient_x / divider).astype(np.uint8)) + cv2.imshow(f'{window_name_prefix}_y', (abs(img_gradient_y) / divider).astype(np.uint8)) + cv2.waitKey(0) + cv2.imshow(f'{window_name_prefix}', img_gradient.astype(np.uint8)) + cv2.waitKey(0) + cv2.destroyAllWindows() - # 255 0 0 - # 255 0 0 - # 128 0 0 - # 638 - # -> 255 - # 0 0 128 - # 0 0 64 - # 0 0 255 - # -447 - # -> 0 +def ex_1(): + img_grayscale = cv2.imread('./../_data/no_idea.jpg', cv2.IMREAD_GRAYSCALE) - # Prewitta kernel_prewitt_x = np.array( [[1, 0, -1], [1, 0, -1], @@ -39,146 +40,96 @@ def ex_1(): [-1, -1, -1]], np.int8 ) + print(kernel_prewitt_x) + print(kernel_prewitt_y) - # [[ 1. 7. 5. -2. -4.] - # [ 2. 11. 6. -5. -6.] - # [ 9. 13. 0. -10. -7.] - # [ 12. 7. -1. -11. -10.] - # [ 10. 2. -2. -8. -8.]] - - # [[ 1 7 5 0 0] - # [ 2 11 6 0 0] - # [ 9 13 0 0 0] - # [12 7 0 0 0] - # [10 2 0 0 0]] - - print(f'kernel_prewitt_x: \n{kernel_prewitt_x}') - print(f'kernel_prewitt_y: \n{kernel_prewitt_y}') - - img_prewitt_x_int = cv2.filter2D(img, -1, kernel=kernel_prewitt_x) - img_prewitt_x = cv2.filter2D(img, cv2.CV_32F, kernel=kernel_prewitt_x) / 3 - img_prewitt_y = cv2.filter2D(img, cv2.CV_32F, kernel=kernel_prewitt_y) / 3 - - img_sobel_builtin_x = cv2.Sobel(img, cv2.CV_32F, 1, 0, ksize=3) - img_sobel_builtin_y = cv2.Sobel(img, cv2.CV_32F, 0, 1, ksize=3) - - np.set_printoptions(formatter={'float': lambda x: "{0:0.2f}".format(x)}) - print(f'{img_prewitt_x[100:105, 100:105]=}') - print(f'{abs(img_prewitt_x[100:105, 100:105])=}') - print(f'{img_prewitt_x[100:105, 100:105].astype(np.uint8)=}') - print(f'{abs(img_prewitt_x[100:105, 100:105]).astype(np.uint8)=}') - - # print(f'{img_sobel_builtin_x[100:105, 100:105]=}') - # print(f'{abs(img_sobel_builtin_x[100:105, 100:105])=}') - # print(f'{img_sobel_builtin_x[100:105, 100:105].astype(np.uint8)=}') - # print(f'{abs(img_sobel_builtin_x[100:105, 100:105]).astype(np.uint8)=}') - - print(f'{img_prewitt_x_int[100:105, 100:105]}') - - img_gradient = cv2.sqrt(cv2.pow(img_prewitt_x, 2) + cv2.pow(img_prewitt_y, 2)) - - cv2.imshow('img', img) - cv2.imshow('img_prewitt_x_int', img_prewitt_x_int) - cv2.imshow('abs(img_prewitt_x)', abs(img_prewitt_x).astype(np.uint8)) - # cv2.imshow('abs(img_sobel_builtin_x)', abs(img_sobel_builtin_x).astype(np.uint8)) - cv2.imshow('abs(img_prewitt_y)', abs(img_prewitt_y).astype(np.uint8)) - # cv2.imshow('abs(img_sobel_builtin_y)', abs(img_sobel_builtin_y).astype(np.uint8)) - # cv2.imshow('sobel_diff', abs(abs(img_sobel_builtin_x) - abs(img_prewitt_x)).astype(np.uint8)) - cv2.imshow('img_gradient', img_gradient.astype(np.uint8)) - cv2.waitKey(0) - cv2.destroyAllWindows() - + kernel_sobel_x = np.array( + [[1, 0, -1], + [2, 0, -2], + [1, 0, -1]], + np.int8 + ) + kernel_sobel_y = np.array( + [[1, 2, 1], + [0, 0, 0], + [-1, -2, -1]], + np.int8 + ) -def empty_callback(value): - pass + _gradient_operator(img_grayscale, kernel_prewitt_x, kernel_prewitt_y, 3, 'img_prewitt') + _gradient_operator(img_grayscale, kernel_sobel_x, kernel_sobel_y, 4, 'img_sobel') def ex_2(): - img = cv2.imread('../_data/no_idea.jpg', cv2.IMREAD_GRAYSCALE) + def trackbar_callback(x): + pass - cv2.namedWindow('canny') - cv2.createTrackbar('th1', 'canny', 0, 255, empty_callback) - cv2.createTrackbar('th2', 'canny', 0, 255, empty_callback) + window_name = 'Canny' + + img_grayscale = cv2.imread('./../_data/no_idea.jpg', cv2.IMREAD_GRAYSCALE) + + cv2.namedWindow(window_name) + cv2.createTrackbar('threshold1', window_name, 0, 255, trackbar_callback) + cv2.createTrackbar('threshold2', window_name, 0, 255, trackbar_callback) key = ord('a') while key != ord('q'): - th1 = cv2.getTrackbarPos('th1', 'canny') - th2 = cv2.getTrackbarPos('th2', 'canny') - edges = cv2.Canny(img, th1, th2) + threshold1 = cv2.getTrackbarPos('threshold1', window_name) + threshold2 = cv2.getTrackbarPos('threshold2', window_name) + img_canny = cv2.Canny(img_grayscale, threshold1, threshold2) - cv2.imshow('img', img) - cv2.imshow('canny', edges) - key = cv2.waitKey(10) + cv2.imshow(window_name, img_canny) + key = cv2.waitKey(100) cv2.destroyAllWindows() def ex_3(): - img_original: np.ndarray = cv2.imread('../_data/sw_s01e05/shapes.jpg') - - img = img_original.copy() - - gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) - edges = cv2.Canny(gray, 50, 150, apertureSize=3) - lines = cv2.HoughLines(edges, 1.5, np.pi / 180, 200) - d = 2000 - for line in lines: + img = cv2.imread('./../_data/sw_s01e05/shapes.jpg', cv2.IMREAD_COLOR) + # NOTE(MF): changing size of the image requires modification of parameters. + # eg. for HoughLines threhold for accumulator + # img = cv2.resize(img, None, fx=0.5, fy=0.5) + img_grayscale = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + edges = cv2.Canny(img_grayscale, 50, 150, apertureSize=3) + cv2.imshow('edges', edges) + + img_hough_lines = np.copy(img) + hough_lines = cv2.HoughLines(edges, 1.5, np.pi / 180, 200) + for line in hough_lines: rho, theta = line[0] a = np.cos(theta) b = np.sin(theta) x0 = a * rho y0 = b * rho - x1 = int(x0 + d * (-b)) - y1 = int(y0 + d * (a)) - x2 = int(x0 - d * (-b)) - y2 = int(y0 - d * (a)) - cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2) - - cv2.imshow('img', img) + x1 = int(x0 + 1000 * (-b)) + y1 = int(y0 + 1000 * (a)) + x2 = int(x0 - 1000 * (-b)) + y2 = int(y0 - 1000 * (a)) + cv2.line(img_hough_lines, (x1, y1), (x2, y2), (0, 0, 255), 2) + cv2.imshow('hough_lines', img_hough_lines) cv2.waitKey(0) - img = img_original.copy() - - lines_p = cv2.HoughLinesP(edges, 1.5, np.pi / 180, 100) - for line in lines_p: - print(line) + img_hough_lines_p = np.copy(img) + hough_lines_p = cv2.HoughLinesP(edges, 1, np.pi / 180, 50, minLineLength=30, maxLineGap=10) + for line in hough_lines_p: x1, y1, x2, y2 = line[0] - cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), thickness=5) - - cv2.imshow('img', img) + cv2.line(img_hough_lines_p, (x1, y1), (x2, y2), (0, 0, 255), 2) + cv2.imshow('hough_lines_p', img_hough_lines_p) cv2.waitKey(0) - cv2.destroyAllWindows() - - -def ex_4(): - img_original: np.ndarray = cv2.imread('../_data/sw_s01e05/shapes.jpg') - img = img_original.copy() - gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) - gray = cv2.GaussianBlur(gray, (7, 7), 1.5) - gray = cv2.medianBlur(gray, 5) - # cimg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) - - circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 50, - param1=200, param2=100, minRadius=10, maxRadius=100) + img_hough_circles = np.copy(img) + circles = cv2.HoughCircles(img_grayscale, cv2.HOUGH_GRADIENT, 1, 100, param1=50, param2=30, minRadius=10, maxRadius=100) circles = np.uint16(np.around(circles)) for i in circles[0, :]: # draw the outer circle - cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2) + cv2.circle(img_hough_circles, (i[0], i[1]), i[2], (0, 255, 0), 2) # draw the center of the circle - cv2.circle(img, (i[0], i[1]), 2, (0, 0, 255), 3) - cv2.imshow('detected circles', img) + cv2.circle(img_hough_circles, (i[0], i[1]), 2, (0, 0, 255), 3) + cv2.imshow('hough_circles', img_hough_circles) cv2.waitKey(0) - cv2.destroyAllWindows() -def main(): - print('Hello ex05!') +if __name__ == '__main__': ex_1() ex_2() ex_3() - ex_4() - - -if __name__ == '__main__': - main() diff --git a/vision_systems/s01e09.py b/vision_systems/s01e09.py index 179ccb5..dfd39e5 100644 --- a/vision_systems/s01e09.py +++ b/vision_systems/s01e09.py @@ -1,69 +1,70 @@ -import os - import cv2 import numpy as np -# https://docs.google.com/document/d/16-TXEYUkAdvEHEYKYLm71N7pYEFILh6WGOEmxeX79tI/edit?usp=sharing - - -def ex_1(): - pattern_size = (8, 5) - image_size = None - number_of_images_to_use = 100 - - object_points = [] - for i in range(0, pattern_size[1]): - for j in range(0, pattern_size[0]): - print(f'i, j: {i}, {j}') - object_points.append([j, i, 0]) - object_points = np.array(object_points, dtype=np.float32) - - image_points_from_images = [] - object_points_form_images = [] - - for filename in os.listdir('../_data/sw_s01e09/')[:number_of_images_to_use]: - print(filename) - if filename.endswith('.bmp'): - - img_from_file = cv2.imread(f'../_data/sw_s01e09/{filename}', cv2.IMREAD_COLOR) - image_size = img_from_file.shape - - pattern_found, corners = cv2.findChessboardCorners(img_from_file, pattern_size) - - if pattern_found: - print(f'corners[0]: {corners[0]}') - corners = cv2.cornerSubPix( - cv2.cvtColor(img_from_file, cv2.COLOR_BGR2GRAY), - corners, - winSize=(11, 11), - zeroZone=(-1, -1), - criteria=(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.1) - ) - print(f'corners[0] after cornerSubPix: {corners[0]}') - - image_points_from_images.append(corners) - object_points_form_images.append(object_points) - - img_with_corners = cv2.drawChessboardCorners(img_from_file.copy(), pattern_size, corners, pattern_found) - cv2.imshow('img_with_corners', img_with_corners) - _ = cv2.waitKey(100) - - retval, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.calibrateCamera(object_points_form_images, image_points_from_images, image_size[:2], None, None) - print(f'retval: {retval}') - - for filename in os.listdir('../_data/sw_s01e09/')[:number_of_images_to_use]: - print(filename) - if filename.endswith('.bmp'): - img_from_file = cv2.imread(f'../_data/sw_s01e09/{filename}', cv2.IMREAD_COLOR) - img_undistorted = cv2.undistort(img_from_file, camera_matrix, dist_coeffs) - cv2.imshow('img_undistorted', img_undistorted) - _ = cv2.waitKey(0) - - # cv2.imshow('img', img_from_file) - # _ = cv2.waitKey(0) - cv2.destroyAllWindows() +def task_1(): + image = cv2.imread('./../_data/sw_s01e09/img_21130751_0005.bmp') + + flag_found, corners = cv2.findChessboardCorners(image, (8, 5)) + print(f'len(corners): {len(corners)}') + image_with_corners_raw = cv2.drawChessboardCorners(image, (8, 5), corners, flag_found) + cv2.imshow('image_with_corners_raw', image_with_corners_raw) + cv2.waitKey(0) + + if flag_found: + print(corners[0]) + + print('Corners found, refining their positions') + corners = cv2.cornerSubPix( + cv2.cvtColor(image, cv2.COLOR_BGR2GRAY), + corners, (11, 11), (-1, -1), + (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.1) + ) + print(corners[0]) + + # prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0) + object_points = np.zeros((8 * 5, 3), np.float32) + print(object_points[1]) + print(object_points.shape) + object_points[:, :2] = np.mgrid[0:8, 0:5].T.reshape(-1, 2) + print(object_points[1]) + print(object_points.shape) + + object_points_for = [] # np.zeros_like(object_points) + for i in range(0, 5): + for j in range(0, 8): + # print(object_points_for[i, j]) + # object_points_for[i, j] = [i, j, 0] + object_points_for.append([j, i, 0]) + object_points_for = np.array(object_points_for, dtype=np.float32) + + print(f'(object_points[0:3]: {object_points[0:3]}') + print(object_points.shape) + print(f'object_points_for[0:3]: {object_points_for[0:3]}') + print(object_points_for.shape) + + image_points = [corners] # [corners1, corners2, corners3] + object_points = [object_points] # [object_points1, object_points2, object_points3] + retval, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.calibrateCamera(object_points, image_points, image.shape[:2], None, None) + + fovx, fovy, focalLength, principalPoint, aspectRatio = cv2.calibrationMatrixValues( + camera_matrix, image.shape[:2], 7.2, 5.4 + ) + print(fovx) + print(fovy) + print(focalLength) + + img_undistorted = cv2.undistort(image, camera_matrix, dist_coeffs) + cv2.imshow('img_undistorted', img_undistorted) + cv2.waitKey(0) + + else: + print('Corners not found') + + image_with_corners = cv2.drawChessboardCorners(image, (8, 5), corners, flag_found) + cv2.imshow('image_with_corners', image_with_corners) + cv2.waitKey(0) if __name__ == '__main__': - ex_1() + task_1() diff --git a/vision_systems/s01e10.py b/vision_systems/s01e10.py index 5865536..73704f6 100644 --- a/vision_systems/s01e10.py +++ b/vision_systems/s01e10.py @@ -1,63 +1,71 @@ +# solution for very slow application start when opening camera +# more details: https://github.com/opencv/opencv/issues/17687 import os +os.environ['OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS'] = '0' import cv2 import numpy as np -# https://docs.google.com/document/d/16-TXEYUkAdvEHEYKYLm71N7pYEFILh6WGOEmxeX79tI/edit?usp=sharing - - -def empty_callback(_): - pass +import time def ex_1(): - cap = cv2.VideoCapture(0) + def empty(_): + pass - cv2.namedWindow('background_image') - cv2.createTrackbar('threshold', 'background_image', 20, 255, empty_callback) + cv2.namedWindow('current_frame') + cv2.namedWindow('background') + cv2.namedWindow('foreground') - background_image = np.zeros((200, 1000), dtype=np.uint8) - current_image = np.zeros((100, 1000), dtype=np.uint8) - foreground_image = np.zeros((100, 1000), dtype=np.uint8) + cv2.createTrackbar('threshold', 'current_frame', 20, 255, empty) + + cap = cv2.VideoCapture(0) + # alternative solution to the one with setting the env variable is to use DSHOW, + # however, it might reduce the achievable fps + # cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) - background_image = cv2.cvtColor(cap.read()[1], cv2.COLOR_BGR2GRAY) + img_gray = cv2.cvtColor(cap.read()[1], cv2.COLOR_BGR2GRAY) + img_current = np.copy(img_gray) + img_background = np.copy(img_gray) + img_foreground = np.copy(img_gray) backSub = cv2.createBackgroundSubtractorMOG2() + # backSub = cv2.createBackgroundSubtractorKNN() - key = ord('p') + key = ord(' ') while key != ord('q'): - _, img = cap.read() - img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + _, frame = cap.read() + img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) - # if key == ord('a'): - # background_image = img - # elif key == ord('x'): - current_image = img + fgMask = backSub.apply(frame) - if current_image.shape == background_image.shape: - foreground_image = cv2.absdiff(current_image, background_image) - kernel = np.ones((3, 3), np.uint8) - foreground_image = cv2.erode(foreground_image, kernel, iterations=1) - foreground_image = cv2.dilate(foreground_image, kernel, iterations=1) + # background update + # if key == ord('a'): + # img_background = np.copy(img_current) + img_background[img_background < img_current] += 1 + img_background[img_background > img_current] -= 1 - threshold = cv2.getTrackbarPos('threshold', 'background_image') - _, foreground_image = cv2.threshold(foreground_image, threshold, 255, cv2.THRESH_BINARY) + # elif key == ord('x'): + img_current = np.copy(img_gray) - background_image[background_image > current_image] -= 1 - background_image[background_image < current_image] += 1 + img_diff = cv2.absdiff(img_background, img_current) + kernel = np.ones((5, 5), np.uint8) + img_closed = cv2.morphologyEx(img_diff, cv2.MORPH_OPEN, kernel) - fgMask = backSub.apply(current_image) - bgMask = backSub.getBackgroundImage() + t = cv2.getTrackbarPos('threshold', 'current_frame') + _, img_thresholded = cv2.threshold(img_closed, t, 255, cv2.THRESH_BINARY) - cv2.imshow('background_image', background_image) - cv2.imshow('current_image', current_image) - cv2.imshow('foreground_image', foreground_image) + cv2.imshow('current_frame', img_current) + cv2.imshow('background', img_background) + cv2.imshow('foreground', img_thresholded) cv2.imshow('fgMask', fgMask) - cv2.imshow('bgMask', bgMask) - key = cv2.waitKey(50) + key = cv2.waitKey(20) + + cap.release() cv2.destroyAllWindows() if __name__ == '__main__': + print('Hello lab 10!') ex_1() diff --git a/image_processing_course/sw_s01e11.py b/vision_systems/s01e11.py similarity index 100% rename from image_processing_course/sw_s01e11.py rename to vision_systems/s01e11.py diff --git a/image_processing_course/s01eTestPreparation.py b/vision_systems/s01eTestPreparation.py similarity index 100% rename from image_processing_course/s01eTestPreparation.py rename to vision_systems/s01eTestPreparation.py