-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathh2_1.py
More file actions
167 lines (132 loc) · 6.1 KB
/
h2_1.py
File metadata and controls
167 lines (132 loc) · 6.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import cv2
import math
import numpy as np
from matplotlib import pyplot as plt
def show_image(name, img):
cv2.namedWindow(name, cv2.WINDOW_NORMAL)
cv2.imshow(name, img)
def detect_lines(img, shift, roi):
# detect lines in the roi of image
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # RGB -> Gray
# cv2.imwrite("../output/gray.jpg", gray)
gray = cv2.GaussianBlur(gray, (5, 5), 1) # denoise
# cv2.imshow("gray", gray)
# cv2.imwrite("../output/denoise.jpg", gray)
up, bottom, left, right = roi
# plt.hist(gray[up: bottom, left: right].ravel(), bins=256, range=(0, 256)) # histogram of roi
# plt.show()
h, w = img.shape[:2]
height, width, channel = h - shift[0], w - shift[1], 1
background = np.zeros((height, width), dtype=np.uint8)
background = cv2.merge([background] * channel)
# print('bb', background.shape)
# cv2.imshow('background', background)
edges = cv2.Canny(gray[up: bottom, left: right], 64, 128) # detect edges
# cv2.imshow("edge", edges)
# cv2.imwrite("../output/edge.jpg", edges)
background[up: bottom, left: right] = edges
# cv2.imshow("merge", black_image)
lines = cv2.HoughLinesP(background, rho=1, theta=np.pi / 180, threshold=160,
minLineLength=312, maxLineGap=2) # detect lines # v1 todo
if lines is None:
raise RuntimeError("No lines are detected!")
return lines
def filter_lines(lines):
res = []
for line in lines:
[[x1, y1, x2, y2]] = line
# calculate line equation: y = kx + b
if x1 != x2:
k = (y2 - y1) / (x2 - x1) # slop of the line
else:
continue
b = y2 - k * x2 # intercept
theta = math.degrees(math.atan(k)) # bank angle (-90, 90)
# filter the lines by bank angle, (-30, 0) U (0, 75) is needed
if -75 <= theta < -15:
d = math.sqrt((y2 - y1) ** 2 + (x2 - x1) ** 2) # length of the line
res.append([x1, y1, x2, y2, k, b, d])
res = sorted(res, key=lambda x: x[-1], reverse=True)[:16] # choose 16 longest lines among all lines
return res
def get_vanishing_point(img, lines, err=0.01):
# computer all the intersection points among all lines combination
vp = []
h, w = img.shape[:2]
for i in range(len(lines)):
for j in range(i + 1, len(lines)):
k1, b1 = lines[i][4], lines[i][5]
k2, b2 = lines[j][4], lines[j][5]
if k1 / k2 > 0 and k1 != k2 and abs(k1 - k2) > err:
x0 = (b1 - b2) / (k2 - k1)
y0 = k1 * x0 + b1
if any([x0 < 0, x0 > w, y0 < 0, y0 > h]):
print("Existing vp out of the image.")
continue # discard the points out of the image
vp.append([x0, y0])
line_color, point_color = (255, 0, 0), (0, 0, 255)
cv2.line(img, (lines[i][0], lines[i][1]), (int(x0), int(y0)), line_color, 1)
cv2.line(img, (lines[j][0], lines[j][1]), (int(x0), int(y0)), line_color, 1)
cv2.circle(img, (int(x0), int(y0)), 4, point_color, -1)
# cv2.imshow("vanishing points", img)
# cv2.imwrite("../output/vp.jpg", img)
return np.array(vp)
if __name__ == "__main__":
img = cv2.imread("../assets/pic2.jpg")
h, w = img.shape[:2]
print('origin img size:', (h, w))
# roi = [int(h / 3), int(h - h / 7), int(w / 6), int(w - w / 8)] # roi (up, bottom, left, right)
roi = [0, h, 0, w] # roi (up, bottom, left, right)
up, bottom, left, right = 0, 0, 750, 0 # padding settings
img = cv2.copyMakeBorder(img, up, bottom, left, right, cv2.BORDER_CONSTANT, value=0) # image padding
# show_image("img pad", img)
img_copy = img.copy()
# cv2.imshow("padding image", img)
# cv2.imwrite("../output/padding.jpg", img)
roi = [roi[0] + up, roi[1] + up, roi[2] + left, roi[3] + left] # roi after padding
print('localization of roi in padding image:', roi)
lines = detect_lines(img, shift=(bottom, right), roi=roi) # detect lines in the image
lines = filter_lines(lines) # filter lines based on bank angle
for line in lines:
cv2.line(img, (line[0], line[1]), (line[2], line[3]), (0, 255, 0), 2)
# cv2.imshow("lines in image", img)
# show_image("lines", img)
# cv2.imwrite("../output/lines.jpg", img)
vp = get_vanishing_point(img, lines, err=0.01) # calculate vanishing points
vl = []
for i in range(0, vp.shape[0] - 1, 2):
p1, p2 = np.array([int(vp[i][0]), int(vp[i][1]), 1]), np.array([int(vp[i + 1][0]), int(vp[i + 1][1]), 1])
cv2.line(img, p1[:-1], p2[:-1], (0, 165, 255), 2) # todo
vl.append(np.cross(p1, p2))
# cv2.imshow("vanishing points and lines", img)
show_image("vp and vl", img)
# cv2.imwrite("../output/vl.jpg", img)
# points = []
#
#
# def choose_point(event, x, y, flags, param):
# if event == cv2.EVENT_LBUTTONDOWN:
# points.append([x, y])
# print("Selected Point:", x, y)
# cv2.circle(img_copy, (x, y), 4, (0, 0, 255), -1)
# cv2.imshow("image", img_copy)
# if len(points) >= 4:
# print("4 points collected")
# print(points)
#
#
# cv2.imshow("image", img_copy)
# cv2.setMouseCallback("image", choose_point)
# src = np.array(points).astype(np.float32)
src = np.array([[849, 525], [1214, 291], [840, 888], [1212, 816]]).astype(np.float32)
for i in range(src.shape[0]):
cv2.circle(img, (int(src[i][0]), int(src[i][1])), 4, (0, 0, 255), -1)
show_image("point", img)
dst = np.array([[800, 400], [1200, 400], [800, 800], [1200, 800]]).astype(np.float32)
H = cv2.getPerspectiveTransform(src, dst)
print("projection transform", H)
h, w = img_copy.shape[:2]
dst = cv2.warpPerspective(img_copy, H, (w, h))
show_image("warp", dst)
cv2.imwrite("../output/h2/pro_1.jpg", dst)
cv2.waitKey()
cv2.destroyAllWindows()