当前位置:   article > 正文

Python 轨道区域检测(基于霍夫变换)_基于霍夫变换的轨道线检测

基于霍夫变换的轨道线检测

效果演示:(顺时针方向 - Ori-image(裁剪过)/After canny/Final area/Hough lines)

在这里插入图片描述

在这里插入图片描述

Main

def getline(imgpath):

    save_Edges = True
    save_Lines = True

    # Default - rate = 0.25
    img, general_point = img_Preprocess(imgpath)  
    gray, edges, orgb, orgb_lines, lines = mask_Preprocess(img, general_point)
	filted_lines, slopes = line_filter(lines)
    try:
        orgb, orgb_lines = draw_rail(orgb, orgb_lines, filted_lines, slopes)
    except:
        pass

    return orgb_lines,edges, orgb
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

1.传入图片路径或者图片 对应ROI区域坐标(默认为原图中间1/2大小区域)

def img_Preprocess(imgpath, rate = 0.25):

    if str(imgpath):
        img = cv2.imread(imgpath)
    else :
        img = imgpath

    h, w = img.shape[:2]
    left_top, right_top, right_buttom, left_buttom = (int(w * rate), int(h * rate)), \
                                                     (int(w * (1 - rate)), int(h * rate)), \
                                                     (int(w * (1 - rate)), int(h * (1 - rate))), \
                                                     (int(w * rate), int(h * (1 - rate)))
    general_point = [left_top, right_top, right_buttom, left_buttom]

    return img, general_point
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2.按位运算(扣出原图中的ROI区域),Gray+高斯Blur,Canny边缘检测,霍夫变换

def mask_Preprocess(img, pts):

    ROI_img = bitwise(img, pts)
    Gray = cv2.cvtColor(ROI_img, cv2.COLOR_BGR2GRAY)
    Blur_Gray = cv2.GaussianBlur(Gray, (17, 17), 0, 0)
    edges = cv2.Canny(Blur_Gray, 10, 70)
    orgb_lines, lines = Hough_line(img, edges)
    ROI_edges = bitwise(edges, pts)
    return Gray, ROI_edges, img, orgb_lines, lines
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3.按照斜率过滤一些lines

    def line_filter(lines):
    filted_lines = []
    slopes = []
    for i, line in enumerate(lines):
        x1, y1, x2, y2 = line[0]
        if abs(slope((x1,y1),(x2,y2))) > 1 :
            slopes.append(slope((x1, y1), (x2, y2)))
            filted_lines.append(line)
            cv2.line(orgb_lines, (x1, y1), (x2, y2), (0, 255, 255), 1)

    return filted_lines, slopes
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

4.过滤后的lines,根据最小斜率和最大斜率找到直线(可以根据slopes聚类或其他方法),根据原图shape绘制轨道区域

def draw_rail(orgb, orgb_lines, filted_lines, slopes):
    h, w = orgb.shape[:2]
    a, b, c, d = filted_lines[slopes.index(max(slopes))][0]
    q, w, e, r = filted_lines[slopes.index(min(slopes))][0]
    cv2.line(orgb_lines, (a, b), (c, d), (0, 0, 255), 3)
    cv2.line(orgb_lines, (q, w), (e, r), (0, 0, 255), 3)
    # w_line1 = np.polyfit((a, b), (c, d), 1)
    # w_line2 = np.polyfit((q, w), (e, r), 1)  ######polyfit 有问题  斜率不是直线方程 不知道怎么求的
    k1,b1 = GeneralEquation(a,b,c,d)
    k2,b2 = GeneralEquation(q,w,e,r)
    w_line1 = [k1,b1]
    w_line2 = [k2,b2]

    left_buttom = int((h - w_line1[1]) // w_line1[0])
    right_buttom = int((h - w_line2[1]) // w_line2[0])
    left_top = int((h/3 - w_line1[1]) // w_line1[0])
    right_top = int((h/3 - w_line2[1]) // w_line2[0])
    rail_pts = np.array([[(left_buttom, h), (right_buttom, h), (right_top, h//3), (left_top, h//3)]])

    zeros = np.zeros((orgb.shape), dtype=np.uint8)
    mask = cv2.fillPoly(zeros, rail_pts, color=(0,255,0))
    orgb = 0.6 * mask + orgb

    return orgb, orgb_lines
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

很久以前的代码了 记不清了 看着改着用吧…
链接:https://pan.baidu.com/s/1ele_c31qhbmK7TivVJE-cw
提取码:ds1f

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/680026
推荐阅读
相关标签
  

闽ICP备14008679号