Created
February 25, 2021 13:14
-
-
Save MrPanch/5d561fc4b0d9ba203365e867beb247a7 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| import cv2 | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| from PIL import Image | |
| import math | |
| def plot_one_image(image: np.ndarray) -> None: | |
| """ | |
| Отобразить изображение с помощью matplotlib. | |
| Вспомогательная функция. | |
| :param image: изображение для отображения | |
| :return: None | |
| """ | |
| fig, axs = plt.subplots(1, 1, figsize=(8, 7)) | |
| axs.imshow(image) | |
| axs.axis('off') | |
| plt.plot() | |
| plt.show() | |
| def rotate(image, point: tuple, angle: float) -> np.ndarray: | |
| """ | |
| Повернуть изображение по часовой стрелке на угол от 0 до 360 градусов и преобразовать размер изображения. | |
| :param image: исходное изображение | |
| :param point: значение точки (x, y), вокруг которой повернуть изображение | |
| :param angle: угол поворота | |
| :return: повернутное изображение | |
| """ | |
| M1 = np.float32([[1, 0, point[1]], [0, 1, point[0]]]) | |
| image_shift = cv2.warpAffine(image.copy(), M1, (image.shape[1] + point[0], image.shape[0] + point[1])) | |
| height, width = image.shape[:2] # image shape has 3 dimensions | |
| image_center = (width/2, height/2) # getRotationMatrix2D needs coordinates in reverse order (width, height) compared to shape | |
| rotation_mat = cv2.getRotationMatrix2D(image_center, angle, 1.) | |
| # rotation calculates the cos and sin, taking absolutes of those. | |
| abs_cos = abs(rotation_mat[0,0]) | |
| abs_sin = abs(rotation_mat[0,1]) | |
| # find the new width and height bounds | |
| bound_w = int(height * abs_sin + width * abs_cos) | |
| bound_h = int(height * abs_cos + width * abs_sin) | |
| # subtract old image center (bringing image back to origo) and adding the new image center coordinates | |
| rotation_mat[0, 2] += bound_w/2 - image_center[0] | |
| rotation_mat[1, 2] += bound_h/2 - image_center[1] | |
| # rotate image with the new bounds and translated rotation matrix | |
| rotated_mat = cv2.warpAffine(image, rotation_mat, (bound_w, bound_h)) | |
| return rotated_mat | |
| # angle = math.radians(angle) # converting degrees to radians | |
| # cosine = math.cos(angle) | |
| # sine = math.sin(angle) | |
| # | |
| # x1y1 = M @ np.array([0,0,1]).T | |
| # x1y2 = M @ np.array([0, image.shape[1], 1]) | |
| # x2y1 = M @ np.array([image.shape[0], 0, 1]) | |
| # x2y2 = M @ np.array([image.shape[0], image.shape[1], 1]) | |
| # | |
| # border_points = np.vstack((x1y1, x1y2, x2y1, x2y2)) | |
| # print(x1y1, x1y2, x2y1, x2y2) | |
| # x_min = min(border_points[:,0]) | |
| # x_max = max(border_points[:,0]) | |
| # y_min = min(border_points[:,1]) | |
| # y_max = max(border_points[:,1]) | |
| # | |
| # new_width = round(x_max-x_min) | |
| # new_height = round(y_max-y_min) | |
| # | |
| # result = cv2.warpAffine(image_shift.copy(), M, (500, 500)) | |
| # | |
| # | |
| # return result | |
| def apply_warpAffine(image, points1, points2) -> np.ndarray: | |
| """ | |
| Применить афинное преобразование согласно переходу точек points1 -> points2 и | |
| преобразовать размер изображения. | |
| :param image: | |
| :param points1: | |
| :param points2: | |
| :return: преобразованное изображение | |
| """ | |
| M = cv2.getAffineTransform(points1, points2) | |
| h, w, _ = image.shape | |
| x1y1 = M @ np.array([0,0,1]).T | |
| x1y2 = M @ np.array([0, h, 1]).T | |
| x2y1 = M @ np.array([w, 0, 1]).T | |
| x2y2 = M @ np.array([w, h, 1]).T | |
| border_points = np.vstack((x1y1, x1y2, x2y1, x2y2)) | |
| x_min = min(border_points[:,0]) | |
| x_max = max(border_points[:,0]) | |
| y_min = min(border_points[:,1]) | |
| y_max = max(border_points[:,1]) | |
| M[0, 2] -= x_min | |
| M[1, 2] -= y_min | |
| image = cv2.warpAffine(image.copy(), M, (round(x_max - x_min), round(y_max - y_min))) | |
| return image | |
| if __name__ == '__main__': | |
| test_image = cv2.imread('task_3/lk.jpg') | |
| test_image = cv2.cvtColor(test_image, cv2.COLOR_BGR2RGB) | |
| test_point_1 = np.float32([[50, 50], [400, 50], [50, 200]]) | |
| test_point_2 = np.float32([[100, 100], [200, 20], [100, 250]]) | |
| transformed_image = apply_warpAffine(test_image, test_point_1, test_point_2) | |
| plot_one_image(transformed_image) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment