aruco识别,python实现

需要配置anaconda,用spyder进行python语言编辑,实现对aruco码的编写。代码比较垃圾,不喜勿喷。

配置过程如下:

视觉系统的运行需要搭建视觉环境,包括,软件的下载安装、Opencv环境的搭建、插件的下载、执行文件的打包等等。首先需要下载安装Anaconda软件,建立可运行python程序的Spyder的环境。aruco识别,python实现_第1张图片

在下在安装好Anaconda后,通过install下载Spyder,建立python开发环境。然后通过命令版Ananconda Prompt下载安装视觉开发环境所需的插件,安装命令为 pip install xx。例如:pip install opencv-contrib-python。

aruco识别,python实现_第2张图片

 通过命令板的pip install 命令下载插件,根据功能需要进行下载。本系统中需要的视觉插件包括Opencv、Opencv-contrib-python、Pyserial、Pyrelsense2、PyQt5、Pyinstaller等插件。在进行完视觉的python程序开发之后,需要将程序打包为exe执行文件,以便于lattepanda对程序的执行,所需要的模块PyQt5、Pyinstaller。通过Pyinstaller -F xxx.Py命令进行打包,生成exe后即可在lattepanda上运行程序。

aruco识别,python实现_第3张图片

aruco识别,python实现_第4张图片

aruco识别,python实现_第5张图片

视觉系统python程序及基于Opencv的Aruco码识别环境的搭建和执行文件的生成流程如下:

aruco识别,python实现_第6张图片

python的代码 如下:

import pyrealsense2 as rs
import serial
import numpy as np
import cv2
import cv2.aruco as aruco
import math
# import socket
# import wmi
# import sys

# c = wmi.WMI()
# for physical_disk in c.Win32_DiskDrive():
#       if physical_disk.SerialNumber=='6b13130f' :#and board_id.SerialNumber=='Default string':#shibeiquanxian
#           print('go on')
#       else:
#           print('The computer is not authorized ')
#           sys.exit()

 #波特率,标准值之一:50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200

#超时设置,None:永远等待操作,0为立即返回请求结果,其他值为等待超时时间(单位为秒)

# 打开串口,并得到串口对象


ser = serial.Serial('COM8', 57600, timeout=0)  # COM8

def send(val):
    data = bytes(val, 'UTF8')
    ser.write(data)
    

# 配置摄像头与开启pipeline

pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
profile = pipeline.start(config)
align_to = rs.stream.color
align = rs.align(align_to)

# 获取对齐的rgb和深度图

def get_aligned_images():
    frames = pipeline.wait_for_frames()
    depth_frame = frames.get_depth_frame()
    aligned_frames = align.process(frames)
    aligned_depth_frame = aligned_frames.get_depth_frame()
    color_frame = aligned_frames.get_color_frame()
    # 获取intelrealsense参数
    intr = color_frame.profile.as_video_stream_profile().intrinsics
    # 内参矩阵,转ndarray方便后续opencv直接使用
    intr_matrix = np.array([
        [intr.fx, 0, intr.ppx], [0, intr.fy, intr.ppy], [0, 0, 1]
    ])
    # 深度图-16位
    depth_image = np.asanyarray(aligned_depth_frame.get_data())
    # 深度图-8位
    depth_image_8bit = cv2.convertScaleAbs(depth_image, alpha=0.03)
    pos = np.where(depth_image_8bit == 0)
    depth_image_8bit[pos] = 255
    # rgb图
    color_image = np.asanyarray(color_frame.get_data())
    # return: rgb图,深度图,相机内参,相机畸变系数(intr.coeffs)
    return color_image, depth_image, intr_matrix, np.array(intr.coeffs), depth_frame


te=[0 for x in range(0, 21)]
t=np.array(te,dtype='uint8')  #uint8型矩阵
cs=[0 for x in range(0, 6)]
D=0x00ff
H=0xff00
R=50

if __name__ == "__main__":
    n = 0
    while 1:
        textsend='{'
        
        rgb, depth, intr_matrix, intr_coeffs, depth_frame = get_aligned_images()
        rgb_copy = rgb.copy()
        # 获取dictionary, 4x4的码,指示位50个
        aruco_dict = aruco.Dictionary_get(aruco.DICT_4X4_50)#aruco.DICT_6X6_250 aruco.DICT_4X4_50
        # 创建detector parameters
        parameters = aruco.DetectorParameters_create()
        # 输入rgb图, aruco的dictionary, 相机内参, 相机的畸变参数
        corners, ids, rejected_img_points = aruco.detectMarkers(rgb, aruco_dict, parameters=parameters,cameraMatrix=intr_matrix, distCoeff=intr_coeffs)
        # n = len(ids)

        idstr1=str(ids)
        idstr2=idstr1.replace('[','')
        idstr3=idstr2.replace(']','')
        idstr4=idstr3.replace(' ','')
        idstr5=idstr4.split('\n')
        # n1=len(idstr1)       
        n5=len(idstr5) 
        # print(idstr1)
        # print(idstr5)
        # print(ids)
        # print(n1)
        # print(n5)
        width = depth_frame.get_width();
        height = depth_frame.get_height();
        imgcenterx = int(width/2)
        imgcentery = int(height/2)
        
        depth_intrin = depth_frame.profile.as_video_stream_profile().intrinsics
        imgcenterdist = depth_frame.get_distance(imgcenterx,imgcentery)
        depth_pointimgcenter = rs.rs2_deproject_pixel_to_point(depth_intrin, [imgcenterx, imgcentery], imgcenterdist)
        cx=depth_pointimgcenter[0]
        cy=depth_pointimgcenter[1]
        cz=depth_pointimgcenter[2]
       
        # print(depth_pointimgcenter)
        # 估计出aruco码的位姿,0.045对应markerLength(二维码的真实大小)参数,单位是meter
        rvec, tvec, markerPoints = aruco.estimatePoseSingleMarkers(corners, 0.045, intr_matrix, intr_coeffs)
        # print(rvec)
        # print(tvec)

        if idstr3==str(None):
          t[0]=(0xeb)
          t[1]=(0x90)
          t[2]=(0x11)
          t[3]=(0x10)
          t[4]=(0x00)
          t[17]=(0xff)
          t[18]=(0xff)
          S=sum(t,0)
          t[19]=(S&D)           
          text=str(t)
          print(text)
          send(text)
        try:
            for i in range(rvec.shape[0]):
                aruco.drawAxis(rgb_copy, intr_matrix, intr_coeffs, rvec[i, :, :], tvec[i, :, :], 0.1)
                aruco.drawDetectedMarkers(rgb_copy, corners,ids)
                #print()
        	# 在图片上标出aruco码的位置
            # aruco.drawDetectedMarkers(rgb, corners,ids)
            # # 根据aruco码的位姿标注出对应的xyz轴, 0.05对应length参数,代表xyz轴画出来的长度 
            # aruco.drawAxis(rgb, intr_matrix, intr_coeffs, rvec, tvec, 0.05)
            for i in range(len(corners)):
                # print(corner[0][0])
                cornerdist = depth_frame.get_distance(corners[i][0][0][0],corners[i][0][0][1])
                xyz_corner = rs.rs2_deproject_pixel_to_point(depth_intrin, corners[i][0][0], cornerdist)
                pointx0=int(corners[i][0][0][0])
                pointy0=int(corners[i][0][0][1])
                pointy1=int(corners[i][0][1][1])
                pointx1=int(corners[i][0][1][0])
                pointy2=int(corners[i][0][2][1])
                Lx01=pointx1 - pointx0
                Ly01=pointy1 - pointy0
                tan=Ly01 / Lx01
                Ls=int((((Ly01)**2)+(Lx01)**2)**0.5)
                sin=Ly01 /Ls
                pianhang=int(math.degrees((math.asin(sin)) )) #偏航角角度值
                if  pointy2 < pointy1:                    
                    phcorner=180-(abs(pianhang))
                else:
                    phcorner=abs(pianhang)
                if pianhang<0:
                    phcorner=abs(360-phcorner)                     
                dx = 100*round(xyz_corner[0]-cx,3)#-depth_pointimgcenter[0]
                xi=int(dx)
                xz=abs(int(dx))
                x=hex(abs(xz))
                
                if xi>0:
                    a=0x01
                elif xi==00:
                    a=0x00
                else:
                    a=0x02
                dy = 100*round(xyz_corner[1]-cy,3)#-depth_pointimgcenter[1]
                yi=int(dy)
                yz=abs(int(dy))
                y=hex(abs(yz))
                if yi>0:
                    b=0x01
                elif yi==0:
                    b=0x00
                else:
                    b=0x02
                # dz = round(depth_pointcenter[2]-depth_pointimgcenter[2],3)
                h  = 100*round((xyz_corner[2]+cz)/2,3)#((xyz_corner[2]+depth_pointimgcenter[2])/2,3)
                # print(depth_pointimgcenter)
                hi=int(h)
                hz=abs(int(h))
                z=hex(abs(int(h)))
                if hi>0:
                    c=0x01
                elif hi==0:
                    c=0x00
                else:
                    c=0x02
                # print(dx,dy,h)
        
                if pianhang>0:
                    d=0x01
                elif pianhang==0:
                    d=0x00
                else:
                    d=0x02  
                if hi>=320 and hi<1100:
                    hz=hz-620
                elif hi>1100:
                    hz=hz-750
                elif hz<320 :
                    hz=hz
                point=np.array(idstr5,dtype='uint8')
                n6=len(point)
                t[0]=(0xeb)
                t[1]=(0x90)
                t[2]=(0x11)
                t[3]=(0x10)
                t[4]=(0x01)
                t[5]=(xz&H)>>8
                t[6]=(xz&D)
                t[7]=(yz&H)>>8
                t[8]=(yz&D)
                t[9]=(hz&H)>>8
                t[10]=(hz&D)
                t[11]=(phcorner&H)>>8
                t[12]=(phcorner&D)
                t[13]=(a)
                t[14]=(b)
                t[15]=(c)
                t[16]=(d)
                t[17]=(int(idstr5[i]))
                t[18]=(n5)
                S=sum(t,0)
                t[19]=(S&D) 
                t[20]=(0xff)
                idl=1
                idb=6
                cp=300
                hdpian=math.radians(phcorner)
                bujiao=math.radians(45)
               #text="id:"+idstr5[i]+" x:"+str(x)+" y:"+str(y)+" z:"+str(z)+" a:"+str(a)+" b:"+str(b)+" c:"+str(c)
                textsend=textsend+text
                textsend=textsend+';'
                # print(text)
                cv2.putText(rgb_copy, text, (int(corners[i][0][0][0]),int(corners[i][0][0][1])), cv2.FONT_HERSHEY_COMPLEX, 0.5, (255, 20, 20), 2)
                
                # text3="dy:"+str(dy)
                # cv2.putText(image_copy, text3, (200, 20), cv2.FONT_HERSHEY_COMPLEX, 0.5, (255, 20, 20), 2)
                # text2="h:"+str(h)        
                # cv2.putText(image_copy, text2, (10, 60), cv2.FONT_HERSHEY_COMPLEX, 0.5, (255, 20, 20), 2)
                # text4="dz:"+str(dz)
                # cv2.putText(image_copy, text4, (200, 60), cv2.FONT_HERSHEY_COMPLEX, 0.5, (255, 20, 20), 2)

            cv2.imshow('RGB image', rgb_copy)
            
           # send(text)
        except:
            cv2.imshow('RGB image', rgb_copy)
        key = cv2.waitKey(1)
        # 按键盘q退出程序
        if key & 0xFF == ord('q') or key == 27:
            pipeline.stop()
            ser.close()
            break
        # 按键盘s保存图片
        elif key == ord('s'):
            n = n + 1
            # 保存rgb图
           # cv2.imwrite('D:/Anaconda/spyderchengxu/gongxun/arucoresult/rgb' + str(n) + '.jpg', rgb_copy)

    cv2.destroyAllWindows()

奥对了,摄像头用的是D435i深度摄像头,采用的红外测距,你也可以用普通的双目。

你可能感兴趣的:(视觉,aruco,python)