欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

laser point detection

程序员文章站 2022-05-21 22:21:24
...

laser point detection

本文主要目的是通过检测激光点,通过相机光轴、激光束和激光点之前形成的几何关系求解距离信息,达到单目相机测距的功能。
#!/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 <PIXEL_THRESH:  #亮斑过滤,可调参数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()