如何用Python的openCV识别图片中道路的位置?

像这样的一副图片, 我想用 opencv 把道路的坐标确定出来应该怎么操作? 我从网上找了这个识别轮廓的代码,

import numpy as np
import cv2

im = cv2.imread(‘path.png’) imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) ret,thresh = cv2.threshold(imgray,127,255,0) im2, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

cv2.namedWindow(“Contours”, cv2.WINDOW_NORMAL) cv2.imshow(“Contours”, im2)

cv2.drawContours(im, contours, -1, (0,255,0), 3) cv2.drawContours(im, contours, 3, (0,255,0), 3) cnt = contours[4] cv2.drawContours(im, [cnt], 0, (0,255,0), 3)

等待键盘输入

cv2.waitKey(0) cv2.destroyAllWindows()

pic

得到的结果是黑的... 所以我想知道如何获取这个道路的位置。~

pic2


如何用Python的openCV识别图片中道路的位置?

16 回复

你是想把道路给分割出来么?


import cv2
import numpy as np

def detect_road_in_image(image_path):
    """
    使用OpenCV识别图片中的道路区域
    主要思路:颜色过滤 -> 边缘检测 -> 霍夫变换找直线 -> 区域提取
    """
    # 1. 读取图片
    img = cv2.imread(image_path)
    if img is None:
        print("无法读取图片")
        return None
    
    # 保存原始图片用于显示
    original = img.copy()
    
    # 2. 转换为HSV颜色空间(更容易识别道路颜色)
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    
    # 3. 定义道路颜色的HSV范围(灰色/沥青色)
    # 注意:这些值可能需要根据实际图片调整
    lower_gray = np.array([0, 0, 50])
    upper_gray = np.array([180, 50, 200])
    
    # 4. 创建颜色掩码
    mask = cv2.inRange(hsv, lower_gray, upper_gray)
    
    # 5. 形态学操作去除噪声
    kernel = np.ones((5,5), np.uint8)
    mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
    mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
    
    # 6. 边缘检测
    edges = cv2.Canny(mask, 50, 150)
    
    # 7. 霍夫变换检测直线(道路边界)
    lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=50, 
                           minLineLength=100, maxLineGap=10)
    
    # 8. 绘制检测到的道路区域
    road_mask = np.zeros_like(mask)
    
    if lines is not None:
        # 提取所有直线的端点
        all_points = []
        for line in lines:
            x1, y1, x2, y2 = line[0]
            all_points.append([x1, y1])
            all_points.append([x2, y2])
            # 可选:绘制检测到的直线
            cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
        
        # 如果检测到足够的点,计算凸包作为道路区域
        if len(all_points) >= 3:
            points = np.array(all_points)
            hull = cv2.convexHull(points)
            cv2.fillPoly(road_mask, [hull], 255)
    
    # 9. 将道路区域应用到原图
    road_area = cv2.bitwise_and(original, original, mask=road_mask)
    
    # 10. 可视化结果
    cv2.imshow('Original', original)
    cv2.imshow('Color Mask', mask)
    cv2.imshow('Edges', edges)
    cv2.imshow('Detected Lines', img)
    cv2.imshow('Road Area', road_area)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    return road_mask, road_area

# 使用示例
if __name__ == "__main__":
    # 替换为你的图片路径
    road_mask, road_area = detect_road_in_image('road_image.jpg')
    
    # 保存结果
    if road_mask is not None:
        cv2.imwrite('road_mask.jpg', road_mask)
        cv2.imwrite('road_area.jpg', road_area)

核心思路:

  1. 颜色过滤:道路通常是灰色/黑色,用HSV颜色空间更容易识别
  2. 边缘检测:找到道路边界
  3. 直线检测:用霍夫变换找道路标线或边界
  4. 区域提取:用凸包或最小外接矩形确定道路区域

参数调整建议:

  • lower_gray/upper_gray:根据实际道路颜色调整HSV范围
  • cv2.HoughLinesP参数:调整thresholdminLineLength适应不同图片
  • 形态学核大小:根据图片分辨率调整去噪效果

一句话总结: 用颜色分割加几何特征来定位道路区域。

色差没调好,你能二维化出来什么?

你这个要 RGB 三个通道分离后做阈值处理,从路的颜色与其他物体(草地,石头等)不一样这个思路入手

大胆猜测下,这要是做外挂吗?

阈值不对? 实在不行腐蚀膨胀一下再提取

。。。。。。
其实我是瞎 bb 的-.-!

你这是通过找连通域来定位路,这个可以,但是你二值化应该有问题。可以尝试边缘检测定位路,常见的道路检测也是这个原理。从计算机视觉跳到大数据,好久不弄快忘记了

可以用直方图均衡把图片对比度弄高点,通过连通区域检测,应该可以分离出几处独立的区域。

暗黑三诶?

谢谢 我看下怎么调色差。

其实我觉得就是找出路的颜色然后在图里面做对比是比较好的。 但是不知道怎么做。

自己玩的, 最近玩了玩暗黑 2, 点鼠标太累了, 就想电脑能不能做, 自己娱乐用的, 做外挂要是我这个技术也不用干了 : D

~~ 我试下, 主要这个不怎么懂, 就看了一下午教程一头雾水哈哈

谢谢 我再研究一下边缘检测
好的 谢谢



类似图像增强的方法都可以考虑

转成 gray 之后保存下来,用类似 PS 的软件打开,可以看到路的颜色范围其实比较大,而且范围和其他区域有重叠,所以直接用 threshold 的效果不太好。

回到顶部