如标题所示,我正在尝试进行图像分割,以期进行“车道”检测。这是我要测试的样本图像。

这是我从本质上在网上找到的东西的第一次编码尝试。

from matplotlib import pyplot as plt
import os
import cv2
def image_seg_watershed():
    img = cv2.imread(os.path.join(img_file,img_file_list[0]))
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
    plt.subplot(121), plt.imshow(thresh)
    plt.show()

这是输出。

有点亲密,但不是我想要的。有任何提示或有用的建议吗?

最佳答案

一种潜在的方法是使用 cv2.inRange() 进行颜色分割。假设所需的线条为白色,我们可以隔离此颜色范围内的像素。这是主要思想

  • 将图像转换为HSV格式,因为它更易于表示颜色
  • 使用较低/较高阈值
  • 进行颜色分割
  • 使用轮廓区域过滤以去除小颗粒


  • 我们将图像转换为HSV格式,因为它比RBG或BGR格式更容易表示颜色。然后我们创建一个上下阈值以检测白色像素,并使用cv2.inRange()创建一个蒙版
    import numpy as np
    import cv2
    
    image = cv2.imread('1.jpg')
    result = image.copy()
    image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    lower = np.array([0,0,200])
    upper = np.array([179, 77, 255])
    mask = cv2.inRange(image, lower, upper)
    result = cv2.bitwise_and(result,result, mask=mask)
    

    请注意,噪声很小,因此下一步是将其去除。我们可以在这里采取几种方法。一种是使用morphological operations腐 eclipse /扩大图像。另一种方法是找到轮廓并使用轮廓区域进行过滤以忽略小颗粒。我将使用后一种方法。我们使用最小阈值区域过滤掉粒子,并使用cv2.drawContours()将其填充为黑色。这是结果
    cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    
    for c in cnts:
        area = cv2.contourArea(c)
        if area < 1:
            cv2.drawContours(result, [c], -1, (0,0,0), -1)
    

    完整代码
    import numpy as np
    import cv2
    
    image = cv2.imread('1.jpg')
    result = image.copy()
    image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    lower = np.array([0,0,200])
    upper = np.array([179, 77, 255])
    mask = cv2.inRange(image, lower, upper)
    result = cv2.bitwise_and(result,result, mask=mask)
    
    cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    
    for c in cnts:
        area = cv2.contourArea(c)
        if area < 1:
            cv2.drawContours(result, [c], -1, (0,0,0), -1)
    
    cv2.imshow('mask', mask)
    cv2.imshow('result', result)
    cv2.waitKey()
    

    您可以使用颜色阈值脚本来查找HSV的上下边界
    import cv2
    import sys
    import numpy as np
    
    def nothing(x):
        pass
    
    # Create a window
    cv2.namedWindow('image')
    
    # create trackbars for color change
    cv2.createTrackbar('HMin','image',0,179,nothing) # Hue is from 0-179 for Opencv
    cv2.createTrackbar('SMin','image',0,255,nothing)
    cv2.createTrackbar('VMin','image',0,255,nothing)
    cv2.createTrackbar('HMax','image',0,179,nothing)
    cv2.createTrackbar('SMax','image',0,255,nothing)
    cv2.createTrackbar('VMax','image',0,255,nothing)
    
    # Set default value for MAX HSV trackbars.
    cv2.setTrackbarPos('HMax', 'image', 179)
    cv2.setTrackbarPos('SMax', 'image', 255)
    cv2.setTrackbarPos('VMax', 'image', 255)
    
    # Initialize to check if HSV min/max value changes
    hMin = sMin = vMin = hMax = sMax = vMax = 0
    phMin = psMin = pvMin = phMax = psMax = pvMax = 0
    
    img = cv2.imread('1.jpg')
    output = img
    waitTime = 33
    
    while(1):
    
        # get current positions of all trackbars
        hMin = cv2.getTrackbarPos('HMin','image')
        sMin = cv2.getTrackbarPos('SMin','image')
        vMin = cv2.getTrackbarPos('VMin','image')
    
        hMax = cv2.getTrackbarPos('HMax','image')
        sMax = cv2.getTrackbarPos('SMax','image')
        vMax = cv2.getTrackbarPos('VMax','image')
    
        # Set minimum and max HSV values to display
        lower = np.array([hMin, sMin, vMin])
        upper = np.array([hMax, sMax, vMax])
    
        # Create HSV Image and threshold into a range.
        hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
        mask = cv2.inRange(hsv, lower, upper)
        output = cv2.bitwise_and(img,img, mask= mask)
    
        # Print if there is a change in HSV value
        if( (phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
            print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
            phMin = hMin
            psMin = sMin
            pvMin = vMin
            phMax = hMax
            psMax = sMax
            pvMax = vMax
    
        # Display output image
        cv2.imshow('image',output)
    
        # Wait longer to prevent freeze for videos.
        if cv2.waitKey(waitTime) & 0xFF == ord('q'):
            break
    
    cv2.destroyAllWindows()
    

    10-05 20:12