139 |
139 |
@brief connect given lines
|
140 |
140 |
@author humkyung
|
141 |
141 |
@date 2018.04.11
|
|
142 |
@history 2018.05.16 Jeongwoo Connect Lines with long distance points
|
142 |
143 |
'''
|
143 |
144 |
def connectLines(self, lines, toler):
|
144 |
145 |
res = []
|
145 |
146 |
|
146 |
|
if len(lines) == 2:
|
147 |
|
lhs = lines[0]
|
148 |
|
rhs = lines[1]
|
149 |
|
|
150 |
|
# start - start
|
151 |
|
dx = lhs[0][0] - rhs[0][0]
|
152 |
|
dy = lhs[0][1] - rhs[0][1]
|
153 |
|
length = math.sqrt(dx*dx + dy*dy)
|
154 |
|
if length < toler:
|
155 |
|
for i in reversed(range(len(lhs))):
|
156 |
|
res.append(lhs[i])
|
157 |
|
for i in range(1,len(rhs)):
|
158 |
|
res.append(rhs[i])
|
159 |
|
|
160 |
|
# end - start
|
161 |
|
dx = lhs[-1][0] - rhs[0][0]
|
162 |
|
dy = lhs[-1][1] - rhs[0][1]
|
163 |
|
length = math.sqrt(dx*dx + dy*dy)
|
164 |
|
if length < toler:
|
165 |
|
for i in range(len(lhs)):
|
166 |
|
res.append(lhs[i])
|
167 |
|
for i in range(1,len(rhs)):
|
168 |
|
res.append(rhs[i])
|
169 |
|
|
170 |
|
# start - end
|
171 |
|
dx = lhs[0][0] - rhs[-1][0]
|
172 |
|
dy = lhs[0][1] - rhs[-1][1]
|
173 |
|
length = math.sqrt(dx*dx + dy*dy)
|
174 |
|
if length < toler:
|
175 |
|
for i in reversed(range(len(lhs))):
|
176 |
|
res.append(lhs[i])
|
177 |
|
for i in reversed(range(len(rhs)-1)):
|
178 |
|
res.append(rhs[i])
|
179 |
|
|
180 |
|
# end - end
|
181 |
|
dx = lhs[-1][0] - rhs[-1][0]
|
182 |
|
dy = lhs[-1][1] - rhs[-1][1]
|
183 |
|
length = math.sqrt(dx*dx + dy*dy)
|
184 |
|
if length < toler:
|
185 |
|
for i in range(len(lhs)):
|
186 |
|
res.append(lhs[i])
|
187 |
|
for i in reversed(range(len(rhs)-1)):
|
188 |
|
res.append(rhs[i])
|
189 |
|
|
190 |
|
# align line along x or y axis
|
191 |
|
dx = math.fabs(res[-1][0] - res[0][0])
|
192 |
|
dy = math.fabs(res[-1][1] - res[0][1])
|
193 |
|
length = math.sqrt(dx*dx + dy*dy)
|
194 |
|
dx /= length
|
195 |
|
dy /= length
|
196 |
|
if dx < 0.1:
|
197 |
|
for pt in res:
|
198 |
|
pt[0] = res[0][0]
|
199 |
|
elif dy < 0.1:
|
200 |
|
for pt in res:
|
201 |
|
pt[1] = res[0][1]
|
202 |
|
# up to here
|
203 |
|
|
204 |
|
return res
|
205 |
|
|
206 |
|
return None
|
|
147 |
pts = []
|
|
148 |
for line in lines:
|
|
149 |
pts.append(line[0])
|
|
150 |
pts.append(line[1])
|
|
151 |
|
|
152 |
maxLength = None
|
|
153 |
for lpt in pts:
|
|
154 |
for rpt in pts:
|
|
155 |
if lpt != rpt:
|
|
156 |
dx = rpt[0] - lpt[0]
|
|
157 |
dy = rpt[1] - lpt[1]
|
|
158 |
length = math.sqrt(dx * dx + dy * dy)
|
|
159 |
if maxLength is None or maxLength < length:
|
|
160 |
maxLength = length
|
|
161 |
res.clear()
|
|
162 |
res.append(lpt)
|
|
163 |
res.append(rpt)
|
|
164 |
|
|
165 |
return res
|
207 |
166 |
|
208 |
167 |
'''
|
209 |
168 |
@brief symbol을 기준으로 양쪽으로 이미지에서 직선을 검출한다.
|
... | ... | |
254 |
213 |
@author humkyung
|
255 |
214 |
@date 2018.04.11
|
256 |
215 |
@history humkyung 2018.04.12 continue loop if line is not in connectedLines
|
|
216 |
Jeongwoo 2018.05.16 Make comments if-statement
|
257 |
217 |
'''
|
258 |
218 |
def mergeLines(self, connectedLines, toler):
|
259 |
219 |
try:
|
... | ... | |
262 |
222 |
matches = [param for param in connectedLines if (line != param) and self.isCollinear(line, param, toler)]
|
263 |
223 |
if len(matches) > 0:
|
264 |
224 |
matches.append(line)
|
265 |
|
if len(matches) > 2: matches = matches[-2:] # pick last two objects
|
|
225 |
#if len(matches) > 2: matches = matches[0:2] # pick last two objects
|
266 |
226 |
mergedLine = self.connectLines(matches, toler)
|
267 |
|
if mergedLine is not None:
|
|
227 |
if mergedLine is not None and len(mergedLine) > 0:
|
268 |
228 |
connectedLines.append(mergedLine)
|
269 |
229 |
for match in matches: connectedLines.remove(match)
|
270 |
230 |
except Exception as ex:
|
... | ... | |
316 |
276 |
'''
|
317 |
277 |
def connectLineToLine(self, lhs, rhs):
|
318 |
278 |
try:
|
319 |
|
polyline = [(rhs[0][0], rhs[1][1]), (rhs[-1][0], rhs[-1][1])]
|
320 |
|
shapelyPoly = shapely.geometry.LineString(polyline)
|
|
279 |
dx = rhs[-1][0] - rhs[0][0]
|
|
280 |
dy = rhs[-1][1] - rhs[0][1]
|
|
281 |
length = math.sqrt(dx*dx + dy*dy)
|
|
282 |
dx /= length
|
|
283 |
dy /= length
|
|
284 |
rightLine = [(rhs[0][0]-dx*20, rhs[0][1]-dy*20), (rhs[-1][0]+dx*20, rhs[-1][1]+dy*20)]
|
|
285 |
shapelyRightLine = shapely.geometry.LineString(rightLine)
|
321 |
286 |
|
322 |
|
dx = lhs[0][0] - lhs[-1][0]
|
323 |
|
dy = lhs[0][1] - lhs[-1][1]
|
|
287 |
dx = lhs[-1][0] - lhs[0][0]
|
|
288 |
dy = lhs[-1][1] - lhs[0][1]
|
324 |
289 |
length = math.sqrt(dx*dx + dy*dy)
|
325 |
290 |
dx /= length
|
326 |
291 |
dy /= length
|
327 |
|
line = [(lhs[0][0]+dx*20, lhs[0][1]+dy*20), (lhs[-1][0]-dx*20, lhs[-1][1]-dy*20)]
|
|
292 |
line = [(lhs[0][0]-dx*20, lhs[0][1]-dy*20), (lhs[-1][0]+dx*20, lhs[-1][1]+dy*20)]
|
328 |
293 |
shapelyLine = shapely.geometry.LineString(line)
|
329 |
294 |
|
330 |
|
pt = shapelyPoly.intersection(shapelyLine)
|
|
295 |
pt = shapelyRightLine.intersection(shapelyLine)
|
331 |
296 |
if (pt is not None) and (type(pt) == shapely.geometry.point.Point):
|
332 |
|
if self.distanceTo(lhs[0], (pt.x, pt.y)) < self.distanceTo(lhs[-1], (pt.x, pt.y)):
|
333 |
|
lhs[0][0] = pt.x
|
334 |
|
lhs[0][1] = pt.y
|
335 |
|
else:
|
336 |
|
lhs[-1][0] = pt.x
|
337 |
|
lhs[-1][1] = pt.y
|
|
297 |
if self.isExternalPoint(lhs, pt):
|
|
298 |
if self.distanceTo(lhs[0], (pt.x, pt.y)) < self.distanceTo(lhs[-1], (pt.x, pt.y)):
|
|
299 |
lhs[0][0] = pt.x
|
|
300 |
lhs[0][1] = pt.y
|
|
301 |
else:
|
|
302 |
lhs[-1][0] = pt.x
|
|
303 |
lhs[-1][1] = pt.y
|
|
304 |
|
|
305 |
if self.isExternalPoint(rhs, pt):
|
|
306 |
if self.distanceTo(rhs[0], (pt.x, pt.y)) < self.distanceTo(rhs[-1], (pt.x, pt.y)):
|
|
307 |
rhs[0][0] = pt.x
|
|
308 |
rhs[0][1] = pt.y
|
|
309 |
else:
|
|
310 |
rhs[-1][0] = pt.x
|
|
311 |
rhs[-1][1] = pt.y
|
|
312 |
except Exception as ex:
|
|
313 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
|
|
314 |
|
|
315 |
def isExternalPoint(self, line, pt):
|
|
316 |
try:
|
|
317 |
dx = line[1][0] - line[0][0]
|
|
318 |
dy = line[1][1] - line[0][1]
|
|
319 |
lineLength = math.sqrt(dx * dx + dy * dy)
|
|
320 |
|
|
321 |
dx = pt.x - line[0][0]
|
|
322 |
dy = pt.y - line[0][1]
|
|
323 |
length = math.sqrt(dx * dx + dy * dy)
|
|
324 |
if length > lineLength:
|
|
325 |
return True
|
|
326 |
|
|
327 |
dx = pt.x - line[1][0]
|
|
328 |
dy = pt.y - line[1][1]
|
|
329 |
length = math.sqrt(dx * dx + dy * dy)
|
|
330 |
if length > lineLength:
|
|
331 |
return True
|
|
332 |
|
|
333 |
return False
|
338 |
334 |
except Exception as ex:
|
339 |
335 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
|
340 |
336 |
|
... | ... | |
355 |
351 |
if ([1,0] == dir):
|
356 |
352 |
image = self.image[(pt[1]-yHalf):(pt[1]+yHalf), pt[0]:self.width]
|
357 |
353 |
imgWidth, imgHeight = image.shape[::-1]
|
|
354 |
i = 0
|
358 |
355 |
for i in range(imgWidth-windowSize[0]):
|
359 |
356 |
window = image[0:windowSize[1], i:i+windowSize[0]]
|
360 |
357 |
if (white == window[0:windowSize[1],0:windowSize[0]]).all(): break
|
... | ... | |
364 |
361 |
elif ([-1,0] == dir):
|
365 |
362 |
image = self.image[(pt[1]-yHalf):(pt[1]+yHalf), 0:pt[0]]
|
366 |
363 |
imgWidth, imgHeight = image.shape[::-1]
|
|
364 |
i = 0
|
367 |
365 |
for i in range(imgWidth-windowSize[0], -1, -1):
|
368 |
366 |
window = image[0:windowSize[1], i:i+windowSize[0]]
|
369 |
367 |
if (white == window[0:windowSize[1],0:windowSize[0]]).all(): break
|
... | ... | |
391 |
389 |
|
392 |
390 |
image = self.image[0:pt[1], int(pt[0]-xHalf):int(pt[0]+xHalf)]
|
393 |
391 |
imgWidth, imgHeight = image.shape[::-1]
|
|
392 |
i = 0
|
394 |
393 |
for i in range(imgHeight-windowSize[1], -1, -1):
|
395 |
394 |
window = image[i:i+windowSize[1], 0:windowSize[0]]
|
396 |
395 |
if (white == window[0:windowSize[1],0:windowSize[0]]).all(): break
|