laser point detection

laser point detection

本文主要目的是通过检测激光点,通过相机光轴、激光束和激光点之前形成的几何关系求解距离信息,达到单目相机测距的功能。
  • 检测结果
    laser point detection_第1张图片

  • 参考

    1.DIY专区一、 用摄像头及激光来测距(opencv)
    2.opencv激光点追踪代码
    3.opencv-python中文教程:颜色空间转换
    4.github.com/Ankur/OpenCV-Laser-Tracker
    5.OpenCV-Laser-Tracker
    6. Laser pointer detect and track
    7.stack overflow:laser curved line detection using opencv and python
    8.Python视觉处理(四)HSV处理
    9.用python3 opencv3 实现相机学生证的实时跟踪
    10.Opencv中SimpleBlobDetector的使用(斑点检测)
    11.【转】使用OpenCV进行斑点检测Blob Detection Using OpenCV ( Python, C++ )
    12.重点参考该内容:pyimagesearch.com:Detecting multiple bright spots in an image with Python and OpenCV
    13.OpenCV 形状分析(上):计算轮廓中心
    14.三角测距法的原理

  • code

#!/usr/bin/python3
# import the necessary packages
from imutils import contours
from skimage import measure
import numpy as np
#import argparse
import imutils
import cv2
import math

CAM=2
cap = cv2.VideoCapture(CAM)


def nothing(x):
        pass

#添加参数控制
cv2.namedWindow("params")
cv2.createTrackbar("manual","params",0,1,nothing)
cv2.createTrackbar("pixels_num","params",0,2000,nothing)

ret,frame=cap.read()
W=frame.shape[0]
H=frame.shape[1]

while True:
    ret,frame=cap.read()
    image=frame
    # load the image, convert it to grayscale, and blur it
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    blurred = cv2.GaussianBlur(gray, (11, 11), 0)

    # threshold the image to reveal light regions in the
    # blurred image
    thresh = cv2.threshold(blurred, 200, 255, cv2.THRESH_BINARY)[1]

    # perform a series of erosions and dilations to remove
    # any small blobs of noise from the thresholded image
    thresh = cv2.erode(thresh, None, iterations=2)
    thresh = cv2.dilate(thresh, None, iterations=4)


    # perform a connected component analysis on the thresholded
    # image, then initialize a mask to store only the "large"
    # components
    labels = measure.label(thresh, neighbors=8, background=0)
    mask = np.zeros(thresh.shape, dtype="uint8")

    MANUAL=cv2.getTrackbarPos("manual","params")
    PIXEL_THRESH=cv2.getTrackbarPos("pixels_num","params") if MANUAL==1 else 500
    # loop over the unique components
    for label in np.unique(labels):
        # if this is the background label, ignore it
        if label == 0:
            continue
        # otherwise, construct the label mask and count the
        # number of pixels
        labelMask = np.zeros(thresh.shape, dtype="uint8")
        labelMask[labels == label] = 255
        numPixels = cv2.countNonZero(labelMask)

        # 通过斑点的像素面积确定激光斑点 
        #if numPixels > 300:
        #print(numPixels) #debug

        cv2.putText(image, "pixel_num:{}".format(numPixels), (10, 10),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
        if numPixels #亮斑过滤,可调参数149 ,500,1269
            mask = cv2.add(mask, labelMask)

    # find the contours in the mask, then sort them from left to
    # right
    cnts= cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    #不同返回参数,不是一个算法!!? 打包成一个对象了
    #im,cnts,hierarchy = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)


    if len(cnts) <2:
        print("未检测到轮廓")
        continue

    cnts = cnts[0] if imutils.is_cv2() else cnts[1]  #用以区分OpenCV2.4和OpenCV3  
    #cnts = contours.sort_contours(cnts)[0]
    cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:5] #保留最大轮廓  

    # loop over the contours
    for (i, c) in enumerate(cnts):
        # draw the bright spot on the image
        (x, y, w, h) = cv2.boundingRect(c)
        ((cX, cY), radius) = cv2.minEnclosingCircle(c)
        cv2.circle(image, (int(cX), int(cY)), int(radius),(0, 255, 0), 3)
        cv2.circle(image, (int(H/2), int(W/2)), int(3),(0, 0, 255), -1)

        cv2.putText(image, "#{} at ({},{})".format(i + 1,x,y), (x, y - 15),cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)

        X=math.pow(abs(W/2-y),2) #|方向
        X=X+math.pow(abs(H/2-x),2) #-方向
        X1=abs(H/2-x)
        X2=abs(W/2-y)
        print("X_:",X1)
        print("X|:",X2)

        #X=math.sqrt(X)
        X=X1
        if X==0:
            continue
        print("X:",X)
        D=797.292/X*3.5  #camL f=797.29
        #D=832.52/X*3.5   #camR f=832.52
        print("D:",D,"cm")
        break
    cv2.imshow("mask",mask)
    cv2.imshow("image",image)
    k=cv2.waitKey(40)&0xff
    if k==27:
        break
cap.release()
cv2.destoryAllWindows()

你可能感兴趣的:(机器视觉)