3
3
import cv2
4
4
import numpy as np
5
5
6
- from einops import rearrange
6
+ from einops import repeat
7
7
8
8
9
- class if_result :
9
+ class ifResult :
10
+ def __init__ (self ):
11
+ self .result_img = None
12
+ self .empty_windows = 0
13
+ self .heading = 0
14
+ self .slope = 0
15
+
10
16
pass
11
17
12
18
@@ -27,8 +33,8 @@ def __init__(self):
27
33
# self.fit is set in Plot_Line
28
34
self .fit = None
29
35
# These two are set below
30
- self ._binary_warped = None | np . ndarray
31
- self ._histogram = None | np . ndarray
36
+ self ._binary_warped = None
37
+ self ._histogram = None
32
38
33
39
# Need to determine if these should remain properties
34
40
# Or if they should be passed as arguments to Plot_Line
@@ -39,22 +45,26 @@ def _binary_warped(self, value: np.ndarray):
39
45
self .binary_warped [self .binary_warped .shape [0 ] // 2 :, :], axis = 0
40
46
)
41
47
42
- def plot_line (self ) -> if_result :
48
+ def plot_line (self ) -> ifResult :
43
49
if not self ._binary_warped :
44
50
raise Exception ("no binary warp specified" )
45
51
46
52
# Image to visualize output
47
- out_img = rearrange ()
48
- (
49
- np .dstack (
50
- (self ._binary_warped , self ._binary_warped , self ._binary_warped )
51
- )
52
- * 255
53
- )
53
+ out_img = repeat (self ._binary_warped , 'h w -> h w c' , repeat = 3 ) * 255
54
+
55
+ ##These outputs need to be confirmed compatible
56
+ # out_img = (
57
+ # np.dstack(
58
+ # self._binary_warped, self._binary_warped, self._binary_warped
59
+ # )
60
+ # * 255
61
+ # )
54
62
55
63
window_height = np .int32 (
56
64
self ._binary_warped .shape [0 ] / IndividualFollower .NWINDOWS
57
65
)
66
+ ##Create result class:
67
+ result = ifResult ()
58
68
59
69
lane_inds = []
60
70
@@ -99,7 +109,8 @@ def plot_line(self) -> if_result:
99
109
empty_windows += 1
100
110
101
111
if len (lane_inds ) == 0 :
102
- return None , 0 , 0 , 0
112
+ return result
113
+
103
114
lane_array = np .concatenate (lane_inds )
104
115
lane_x_pos = nonzero_x [lane_array ]
105
116
lane_y_pos = nonzero_y [lane_array ]
@@ -124,34 +135,55 @@ def plot_line(self) -> if_result:
124
135
##Generates the search window area
125
136
window_img = np .zeros_like (out_img )
126
137
##These lines should be broken up accordingly: They render the search area
127
- line_window1 = np .array (
138
+
139
+ window_1 = np .vstack (
128
140
[
129
- np .transpose (
130
- np .vstack (
131
- [
132
- polynomial - IndividualFollower .SEARCH_WIDTH ,
133
- plotting_coordinates ,
134
- ]
135
- )
136
- )
141
+ polynomial - IndividualFollower .SEARCH_WIDTH ,
142
+ plotting_coordinates ,
137
143
]
138
- )
139
- line_window2 = np .array (
140
- [
141
- np .transpose (
142
- np .vstack (
143
- [
144
- polynomial + IndividualFollower .SEARCH_WIDTH ,
145
- plotting_coordinates ,
146
- ]
147
- )
148
- )
149
- ]
150
- )
151
- line_pts = np .hstack ((line_window1 , line_window2 ))
144
+ ).T
145
+
146
+ window_2 = np .vstack (
147
+ [
148
+ polynomial - IndividualFollower .SEARCH_WIDTH ,
149
+ plotting_coordinates ,
150
+ ]
151
+ ).T
152
+
153
+ # These replacements also need to be tested
154
+
155
+ # line_window1 =
156
+ # np.array(
157
+ # [
158
+ # np.transpose(
159
+ # np.vstack(
160
+ # [
161
+ # polynomial - IndividualFollower.SEARCH_WIDTH,
162
+ # plotting_coordinates,
163
+ # ]
164
+ # )
165
+ # )
166
+ # ]
167
+ # )
168
+ # line_window2 = np.array(
169
+ # [
170
+ # np.transpose(
171
+ # np.vstack(
172
+ # [
173
+ # polynomial + IndividualFollower.SEARCH_WIDTH,
174
+ # plotting_coordinates,
175
+ # ]
176
+ # )
177
+ # )
178
+ # ]
179
+ # )
180
+
181
+ line_pts = np .hstack ((window_1 , window_2 ))
152
182
cv2 .fillPoly (
153
183
window_img , np .int_ ([line_pts ]), color = IndividualFollower .BOX_COLOR
154
184
)
185
+ # This seems to be a lot of numpy fluff that should be replaced with einops
186
+ # or removed altogether.
155
187
line_pts = np .array (
156
188
[np .transpose (np .vstack ([polynomial , plotting_coordinates ]))],
157
189
dtype = np .int32 ,
@@ -168,10 +200,11 @@ def plot_line(self) -> if_result:
168
200
##TODO: Make this use the furthest found box. This way, we'll use the most accurate heading
169
201
y_lower = 0
170
202
y_upper = (IndividualFollower .NWINDOWS + 1 ) * window_height
171
- slope = np .polyval (self .fit , y_lower ) - np .polyval (
203
+
204
+ result .slope = np .polyval (self .fit , y_lower ) - np .polyval (
172
205
self .fit , y_upper
173
206
) / (y_upper - y_lower )
174
- heading = math . atan ( slope )
175
- result = cv2 . addWeighted ( out_img , 1 , window_img , 0.3 , 0 )
176
- # TODO: Determine what result really is, and annotate efficiently
177
- return result , empty_windows , heading , slope
207
+ result . result_img = cv2 . addWeighted ( out_img , 1 , window_img , 0.3 , 0 )
208
+ result . heading = math . atan ( result . slope )
209
+
210
+ return result
0 commit comments