datdo2717 commited on
Commit
7124da5
·
1 Parent(s): d0ca0cf
Files changed (2) hide show
  1. Segmentation.py +58 -0
  2. perpestive_transform.py +188 -0
Segmentation.py ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ultralytics import YOLO
2
+ import cv2
3
+ import os
4
+ import shutil
5
+ import numpy as np
6
+ def black_mask(results):
7
+ # Đường dẫn đến thư mục "runs"
8
+ runs_folder = "mask"
9
+ # Kiểm tra xem thư mục "mask" đã tồn tại chưa
10
+ if not os.path.exists(runs_folder):
11
+ # Nếu chưa tồn tại, tạo thư mục "mask"
12
+ os.makedirs(runs_folder)
13
+ for mask_index in range(len(results[0].masks)):
14
+ # Lấy mặt nạ
15
+ mask_raw = results[0].masks[mask_index].cpu().data.numpy().transpose(1, 2, 0)
16
+ # Chuyển đổi mặt nạ thành 3 kênh màu
17
+ mask_3channel = cv2.merge((mask_raw, mask_raw, mask_raw))
18
+ # Lấy kích thước của ảnh gốc (chiều cao, chiều rộng, số kênh)
19
+ h2, w2, c2 = results[0].orig_img.shape
20
+ # Thay đổi kích thước mặt nạ thành cùng kích thước với ảnh gốc
21
+ mask = cv2.resize(mask_3channel, (w2, h2))
22
+ # Chuyển đổi ảnh mặt nạ thành không gian màu HSV
23
+ hsv = cv2.cvtColor(mask, cv2.COLOR_BGR2HSV)
24
+ # Xác định phạm vi độ sáng trong không gian màu HSV
25
+ lower_black = np.array([0, 0, 0])
26
+ upper_black = np.array([0, 0, 1])
27
+ # Tạo mặt nạ dựa trên phạm vi độ sáng
28
+ mask = cv2.inRange(mask, lower_black, upper_black)
29
+ # Đảo ngược mặt nạ để lấy mọi thứ trừ màu đen
30
+ mask = cv2.bitwise_not(mask)
31
+ # Áp dụng mặt nạ vào ảnh gốc
32
+ masked = cv2.bitwise_and(results[0].orig_img, results[0].orig_img, mask=mask)
33
+ # Chuyển mọi pixel màu đen thành màu trắng
34
+ black_color = [0, 0, 0]
35
+ white_color = [255, 255, 255]
36
+ result_image = np.where(np.all(masked == black_color, axis=-1, keepdims=True), masked, white_color)
37
+ name = "mask/"+str(mask_index) + '.png'
38
+ # Show the masked part of the image
39
+ cv2.imwrite(name,result_image)
40
+ def segmentation_doc(image):
41
+ model = YOLO('Model/Seg65ep.pt')
42
+ runs_folder = "runs"
43
+ folder="mask"
44
+ # Xóa thư mục runs
45
+ if os.path.exists(runs_folder) and os.path.isdir(runs_folder):
46
+ # Xóa thư mục runs
47
+ shutil.rmtree(runs_folder)
48
+ if os.path.exists(folder) and os.path.isdir(folder):
49
+ # Xóa thư mục runs
50
+ shutil.rmtree(folder)
51
+ color = [255, 255, 255] # Màu trắng
52
+ padding_size = 50
53
+ image = cv2.copyMakeBorder(image, padding_size, padding_size, padding_size, padding_size, cv2.BORDER_CONSTANT, value=color)
54
+ results = model(image,save=True,retina_masks = True, conf=0.7)
55
+ black_mask(results)
56
+ return image
57
+ # image=cv2.imread("test1.jpg")
58
+ # segmentation_doc(image)
perpestive_transform.py ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ import matplotlib.pyplot as plt
4
+ from deskew import determine_skew
5
+ import math
6
+ from typing import Tuple, Union
7
+ def rotate(image: np.ndarray, angle: float, background: Union[int, Tuple[int, int, int]]) -> np.ndarray:
8
+ old_width, old_height = image.shape[:2]
9
+ angle_radian = math.radians(angle)
10
+ width = abs(np.sin(angle_radian) * old_height) + abs(np.cos(angle_radian) * old_width)
11
+ height = abs(np.sin(angle_radian) * old_width) + abs(np.cos(angle_radian) * old_height)
12
+
13
+ image_center = tuple(np.array(image.shape[1::-1]) / 2)
14
+ rot_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0)
15
+ rot_mat[1, 2] += (width - old_width) / 2
16
+ rot_mat[0, 2] += (height - old_height) / 2
17
+
18
+ return cv2.warpAffine(image, rot_mat, (int(round(height)), int(round(width))), borderValue=background)
19
+
20
+
21
+ def check(my_list):
22
+ unique_elements = []
23
+
24
+ # Sử dụng vòng lặp để kiểm tra từng phần tử trong danh sách
25
+ for item in my_list:
26
+ # Nếu phần tử không xuất hiện trong danh sách các phần tử duy nhất, thêm nó vào danh sách đó
27
+ if item not in unique_elements:
28
+ unique_elements.append(item)
29
+ return len(unique_elements)
30
+
31
+
32
+ def order_points(pts):
33
+ rect = np.zeros((4, 2), dtype="float32")
34
+ pts = np.array(pts)
35
+ s = pts.sum(axis=1)
36
+ rect[0] = pts[np.argmin(s)]
37
+ rect[2] = pts[np.argmax(s)]
38
+
39
+ diff = np.diff(pts, axis=1)
40
+ rect[1] = pts[np.argmin(diff)]
41
+ rect[3] = pts[np.argmax(diff)]
42
+ return rect.astype("int").tolist()
43
+
44
+
45
+ def find_dest(pts):
46
+ (tl, tr, br, bl) = pts
47
+ widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
48
+ widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
49
+ maxWidth = max(int(widthA), int(widthB))
50
+ heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
51
+ heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
52
+ maxHeight = max(int(heightA), int(heightB))
53
+ destination_corners = [[0, 0], [maxWidth, 0], [maxWidth, maxHeight], [0, maxHeight]]
54
+ return order_points(destination_corners)
55
+ def extract(ori_img, img, image_size=384, BUFFER=100):
56
+ img=img.astype(np.uint8)
57
+ gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
58
+ angle = determine_skew(gray_image)
59
+ img = rotate(img, angle, (0, 0, 0))
60
+ ori_img = rotate(ori_img, angle, (0, 0, 0))
61
+ #get size of image
62
+ size = img.shape
63
+ top_pad = 10 # Số pixel padding ở phía trên
64
+ bottom_pad = 10 # Số pixel padding ở phía dưới
65
+ left_pad = 10 # Số pixel padding ở phía trái
66
+ right_pad = 10 # Số pixel padding ở phía phải
67
+
68
+ # Tạo hình ảnh mới với kích thước lớn hơn, bằng cách thêm pixel màu đen (0) vào xung quanh
69
+ height, width, channels = img.shape
70
+ new_height = height + top_pad + bottom_pad
71
+ new_width = width + left_pad + right_pad
72
+
73
+ # Tạo một hình ảnh mới với màu đen (0) là màu nền
74
+ padded_img = np.zeros((new_height, new_width, channels), dtype=np.uint8)
75
+
76
+ # Copy nội dung của hình ảnh gốc vào vị trí tương ứng trong hình ảnh mới
77
+ padded_img[top_pad:top_pad + height, left_pad:left_pad + width] = img
78
+ img = padded_img
79
+
80
+ height, width, channels = ori_img.shape
81
+ new_height = height + top_pad + bottom_pad
82
+ new_width = width + left_pad + right_pad
83
+
84
+ # Tạo một hình ảnh mới với màu đen (0) là màu nền
85
+ padded_ori_img = np.full((new_height, new_width, channels), 255, dtype=np.uint8)
86
+
87
+ # Copy nội dung của hình ảnh gốc vào vị trí tương ứng trong hình ảnh mới
88
+ padded_ori_img[top_pad:top_pad + height, left_pad:left_pad + width] = ori_img
89
+ ori_img = padded_ori_img
90
+
91
+ imH, imW, C = img.shape
92
+ IMAGE_SIZE = image_size
93
+ img_rs = cv2.resize(img, (IMAGE_SIZE, IMAGE_SIZE), interpolation=cv2.INTER_NEAREST)
94
+
95
+ # imH, imW, C = img.shape
96
+ # IMAGE_SIZE=image_size
97
+ scale_x = imW / IMAGE_SIZE
98
+ scale_y = imH / IMAGE_SIZE
99
+ # img=cv2.resize(img, (IMAGE_SIZE, IMAGE_SIZE), interpolation=cv2.INTER_NEAREST)
100
+
101
+ canny = cv2.Canny(img_rs.astype(np.uint8), 225, 255)
102
+ canny = cv2.dilate(canny, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)))
103
+ contours, _ = cv2.findContours(canny, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
104
+ page = sorted(contours, key=cv2.contourArea, reverse=True)[0]
105
+ epsilon = (0.02* cv2.arcLength(page, True))
106
+ corners = cv2.approxPolyDP(page, epsilon, True)
107
+ corners = np.concatenate(corners).astype(np.float32)
108
+ corners[:, 0] *= scale_x
109
+ corners[:, 1] *= scale_y
110
+
111
+ # corners[:, 0] -= half
112
+ # corners[:, 1] -= half
113
+ for corner in corners:
114
+ x, y = corner.astype(int)
115
+ cv2.circle(img, (int(x), int(y)), 20, (0, 255, 0), -1) # Vẽ một hình tròn màu xanh lên ảnh
116
+
117
+ if len(corners) > 4:
118
+ left_pad, top_pad, right_pad, bottom_pad = 0, 0, 0, 0
119
+ rect = cv2.minAreaRect(corners.reshape((-1, 1, 2)))
120
+ box = cv2.boxPoints(rect)
121
+ box_corners = np.int32(box)
122
+ # box_corners = minimum_bounding_rectangle(corners)
123
+
124
+ box_x_min = np.min(box_corners[:, 0])
125
+ box_x_max = np.max(box_corners[:, 0])
126
+ box_y_min = np.min(box_corners[:, 1])
127
+ box_y_max = np.max(box_corners[:, 1])
128
+
129
+ # Find corner point which doesn't satify the image constraint
130
+ # and record the amount of shift required to make the box
131
+ # corner satisfy the constraint
132
+ if box_x_min <= 0:
133
+ left_pad = abs(box_x_min) + BUFFER
134
+
135
+ if box_x_max >= imW:
136
+ right_pad = (box_x_max - imW) + BUFFER
137
+
138
+ if box_y_min <= 0:
139
+ top_pad = abs(box_y_min) + BUFFER
140
+
141
+ if box_y_max >= imH:
142
+ bottom_pad = (box_y_max - imH) + BUFFER
143
+ box_corners[:, 0] += left_pad
144
+ box_corners[:, 1] += top_pad
145
+ corners = box_corners
146
+
147
+ if check(order_points(corners)) >= 4:
148
+ corners = order_points(corners)
149
+ else:
150
+ pass
151
+
152
+ # Define the amount to increase the rectangle size
153
+ # (tl, tr, br, bl) = corners
154
+ # widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
155
+ # widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
156
+ # maxWidth = max(int(widthA), int(widthB))
157
+ # heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
158
+ # heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
159
+ # maxHeight = max(int(heightA), int(heightB))
160
+
161
+ # # Increase the x-coordinate of the top-right and bottom-right points
162
+ # corners[1][0] += maxWidth/30
163
+ # corners[2][0] += maxWidth/30
164
+
165
+ # # Decrease the x-coordinate of the top-left and bottom-left points
166
+ # corners[0][0] -= maxWidth/30
167
+ # corners[3][0] -= maxWidth/30
168
+ # # Increase the y-coordinate of the bottom-right and bottom-left points
169
+ # corners[2][1] += maxHeight/30
170
+ # corners[3][1] += maxHeight/30
171
+
172
+ # # Decrease the y-coordinate of the top-left and top-right points
173
+ # corners[0][1] -= maxHeight/30
174
+ # corners[1][1] -= maxHeight/30
175
+
176
+ # print(corners)
177
+
178
+ destination_corners = find_dest(corners)
179
+ M = cv2.getPerspectiveTransform(np.float32(corners), np.float32(destination_corners))
180
+ final = cv2.warpPerspective(ori_img, M, (destination_corners[2][0], destination_corners[2][1]),
181
+ flags=cv2.INTER_LANCZOS4)
182
+ return final
183
+ # ori=cv2.imread("runs\segment\predict\image0.jpg")
184
+ # img=cv2.imread("mask/2.png")
185
+ # final=extract(ori,img)
186
+ # plt.imshow(final)
187
+ # plt.show()
188
+ # # print(img.shape)