我的任务是找到线(startX、startY、endX、endY)和矩形(4 线)的坐标.这是输入文件:
我使用下一个代码:
img = cv2.imread(image_src)灰色 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)ret, thresh1 = cv2.threshold(灰色,127,255,cv2.THRESH_BINARY)边缘 = cv2.Canny(thresh1,50,150,apertureSize = 3)minLineLength = 100最大线间隙 = 10线 = cv2.HoughLinesP(edges,1,np.pi/180,10,minLineLength,maxLineGap)打印(长度(行))对于行中的行:cv2.line(img,(line[0][0],line[0][1]),(line[0][2],line[0][3]),(0,0,255),6)我得到下一个结果:
从最后一张图片中,您可以看到大量的小红线.
问题:
我终于完成了流水线:
还有 572 行.在我的合并线段"之后,我们只有 89 行
My task is to find coordinates of lines (startX, startY, endX, endY) and rectangles (4 lines). Here is input file:
I use the next code:
img = cv2.imread(image_src)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh1 = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
edges = cv2.Canny(thresh1,50,150,apertureSize = 3)
minLineLength = 100
maxLineGap = 10
lines = cv2.HoughLinesP(edges,1,np.pi/180,10,minLineLength,maxLineGap)
print(len(lines))
for line in lines:
cv2.line(img,(line[0][0],line[0][1]),(line[0][2],line[0][3]),(0,0,255),6)
I get the next results:
From the last image you can see big amount of small red lines.
Questions:
I have finally completed the pipeline:
Please find the code and results:
def get_lines(lines_in):
if cv2.__version__ < '3.0':
return lines_in[0]
return [l[0] for l in lines_in]
def process_lines(image_src):
img = mpimg.imread(image_src)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh1 = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
thresh1 = cv2.bitwise_not(thresh1)
edges = cv2.Canny(thresh1, threshold1=50, threshold2=200, apertureSize = 3)
lines = cv2.HoughLinesP(thresh1, rho=1, theta=np.pi/180, threshold=50,
minLineLength=50, maxLineGap=30)
# l[0] - line; l[1] - angle
for line in get_lines(lines):
leftx, boty, rightx, topy = line
cv2.line(img, (leftx, boty), (rightx,topy), (0,0,255), 6)
# merge lines
#------------------
# prepare
_lines = []
for _line in get_lines(lines):
_lines.append([(_line[0], _line[1]),(_line[2], _line[3])])
# sort
_lines_x = []
_lines_y = []
for line_i in _lines:
orientation_i = math.atan2((line_i[0][1]-line_i[1][1]),(line_i[0][0]-line_i[1][0]))
if (abs(math.degrees(orientation_i)) > 45) and abs(math.degrees(orientation_i)) < (90+45):
_lines_y.append(line_i)
else:
_lines_x.append(line_i)
_lines_x = sorted(_lines_x, key=lambda _line: _line[0][0])
_lines_y = sorted(_lines_y, key=lambda _line: _line[0][1])
merged_lines_x = merge_lines_pipeline_2(_lines_x)
merged_lines_y = merge_lines_pipeline_2(_lines_y)
merged_lines_all = []
merged_lines_all.extend(merged_lines_x)
merged_lines_all.extend(merged_lines_y)
print("process groups lines", len(_lines), len(merged_lines_all))
img_merged_lines = mpimg.imread(image_src)
for line in merged_lines_all:
cv2.line(img_merged_lines, (line[0][0], line[0][1]), (line[1][0],line[1][1]), (0,0,255), 6)
cv2.imwrite('prediction/lines_gray.jpg',gray)
cv2.imwrite('prediction/lines_thresh.jpg',thresh1)
cv2.imwrite('prediction/lines_edges.jpg',edges)
cv2.imwrite('prediction/lines_lines.jpg',img)
cv2.imwrite('prediction/merged_lines.jpg',img_merged_lines)
return merged_lines_all
def merge_lines_pipeline_2(lines):
super_lines_final = []
super_lines = []
min_distance_to_merge = 30
min_angle_to_merge = 30
for line in lines:
create_new_group = True
group_updated = False
for group in super_lines:
for line2 in group:
if get_distance(line2, line) < min_distance_to_merge:
# check the angle between lines
orientation_i = math.atan2((line[0][1]-line[1][1]),(line[0][0]-line[1][0]))
orientation_j = math.atan2((line2[0][1]-line2[1][1]),(line2[0][0]-line2[1][0]))
if int(abs(abs(math.degrees(orientation_i)) - abs(math.degrees(orientation_j)))) < min_angle_to_merge:
#print("angles", orientation_i, orientation_j)
#print(int(abs(orientation_i - orientation_j)))
group.append(line)
create_new_group = False
group_updated = True
break
if group_updated:
break
if (create_new_group):
new_group = []
new_group.append(line)
for idx, line2 in enumerate(lines):
# check the distance between lines
if get_distance(line2, line) < min_distance_to_merge:
# check the angle between lines
orientation_i = math.atan2((line[0][1]-line[1][1]),(line[0][0]-line[1][0]))
orientation_j = math.atan2((line2[0][1]-line2[1][1]),(line2[0][0]-line2[1][0]))
if int(abs(abs(math.degrees(orientation_i)) - abs(math.degrees(orientation_j)))) < min_angle_to_merge:
#print("angles", orientation_i, orientation_j)
#print(int(abs(orientation_i - orientation_j)))
new_group.append(line2)
# remove line from lines list
#lines[idx] = False
# append new group
super_lines.append(new_group)
for group in super_lines:
super_lines_final.append(merge_lines_segments1(group))
return super_lines_final
def merge_lines_segments1(lines, use_log=False):
if(len(lines) == 1):
return lines[0]
line_i = lines[0]
# orientation
orientation_i = math.atan2((line_i[0][1]-line_i[1][1]),(line_i[0][0]-line_i[1][0]))
points = []
for line in lines:
points.append(line[0])
points.append(line[1])
if (abs(math.degrees(orientation_i)) > 45) and abs(math.degrees(orientation_i)) < (90+45):
#sort by y
points = sorted(points, key=lambda point: point[1])
if use_log:
print("use y")
else:
#sort by x
points = sorted(points, key=lambda point: point[0])
if use_log:
print("use x")
return [points[0], points[len(points)-1]]
# https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.cdist.html
# https://stackoverflow.com/questions/32702075/what-would-be-the-fastest-way-to-find-the-maximum-of-all-possible-distances-betw
def lines_close(line1, line2):
dist1 = math.hypot(line1[0][0] - line2[0][0], line1[0][0] - line2[0][1])
dist2 = math.hypot(line1[0][2] - line2[0][0], line1[0][3] - line2[0][1])
dist3 = math.hypot(line1[0][0] - line2[0][2], line1[0][0] - line2[0][3])
dist4 = math.hypot(line1[0][2] - line2[0][2], line1[0][3] - line2[0][3])
if (min(dist1,dist2,dist3,dist4) < 100):
return True
else:
return False
def lineMagnitude (x1, y1, x2, y2):
lineMagnitude = math.sqrt(math.pow((x2 - x1), 2)+ math.pow((y2 - y1), 2))
return lineMagnitude
#Calc minimum distance from a point and a line segment (i.e. consecutive vertices in a polyline).
# https://nodedangles.wordpress.com/2010/05/16/measuring-distance-from-a-point-to-a-line-segment/
# http://paulbourke.net/geometry/pointlineplane/
def DistancePointLine(px, py, x1, y1, x2, y2):
#http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/source.vba
LineMag = lineMagnitude(x1, y1, x2, y2)
if LineMag < 0.00000001:
DistancePointLine = 9999
return DistancePointLine
u1 = (((px - x1) * (x2 - x1)) + ((py - y1) * (y2 - y1)))
u = u1 / (LineMag * LineMag)
if (u < 0.00001) or (u > 1):
#// closest point does not fall within the line segment, take the shorter distance
#// to an endpoint
ix = lineMagnitude(px, py, x1, y1)
iy = lineMagnitude(px, py, x2, y2)
if ix > iy:
DistancePointLine = iy
else:
DistancePointLine = ix
else:
# Intersecting point is on the line, use the formula
ix = x1 + u * (x2 - x1)
iy = y1 + u * (y2 - y1)
DistancePointLine = lineMagnitude(px, py, ix, iy)
return DistancePointLine
def get_distance(line1, line2):
dist1 = DistancePointLine(line1[0][0], line1[0][1],
line2[0][0], line2[0][1], line2[1][0], line2[1][1])
dist2 = DistancePointLine(line1[1][0], line1[1][1],
line2[0][0], line2[0][1], line2[1][0], line2[1][1])
dist3 = DistancePointLine(line2[0][0], line2[0][1],
line1[0][0], line1[0][1], line1[1][0], line1[1][1])
dist4 = DistancePointLine(line2[1][0], line2[1][1],
line1[0][0], line1[0][1], line1[1][0], line1[1][1])
return min(dist1,dist2,dist3,dist4)
There are still 572 lines. After my "merging line segments" we have only 89 lines
这篇关于如何在 HoughLinesP 之后合并行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!
如何在python中的感兴趣区域周围绘制一个矩形How to draw a rectangle around a region of interest in python(如何在python中的感兴趣区域周围绘制一个矩形)
如何使用 OpenCV 检测和跟踪人员?How can I detect and track people using OpenCV?(如何使用 OpenCV 检测和跟踪人员?)
如何在图像的多个矩形边界框中应用阈值?How to apply threshold within multiple rectangular bounding boxes in an image?(如何在图像的多个矩形边界框中应用阈值?)
如何下载 Coco Dataset 的特定部分?How can I download a specific part of Coco Dataset?(如何下载 Coco Dataset 的特定部分?)
根据文本方向检测图像方向角度Detect image orientation angle based on text direction(根据文本方向检测图像方向角度)
使用 Opencv 检测图像中矩形的中心和角度Detect centre and angle of rectangles in an image using Opencv(使用 Opencv 检测图像中矩形的中心和角度)