• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    python实现Nao机器人的单目测距

     本文实例为大家分享了python实现Nao机器人单目测距的具体代码,供大家参考,具体内容如下

    此代码适于用做对Nao机器人做视觉识别和测距实验,只提供关键代码部分,尝试利用cv2去优化代码会更加简洁哟!

    此代码的主要功能:

    1.初始姿态下,通过更换摄像头和转头去寻找目标
    2.通过颜色阈值识别目标,计算目标与Nao的距离和角度

    可以扩展功能:

    1.在运动过程中对方向和距离进行多次测量和校正,提高准确度
    2.找到目标后,通过对目标的测量,选择使用哪个脚去踢目标

    #!/usr/bin/python2.7
    #-*- encoding: UTF-8 -*-
    import vision_definitions
    #----------------------单目测距--------------------------------
    #***********************************************
    #@函数名:   DistAndDirect_cal(cxnum,rynum,colsum,rowsum,Head_angle,cameraID)
    #@参数:     (cxnum,rynum)是通过图像识别得到球心的像素点坐标
    #           (colsum,rowsum)是图片总大小:640*480
    #            cameraID=0,取上摄像头;cameraID=1,取下摄像头
    #@返回值:   无
    #@功能说明: 采用机器人的下摄像头进行测量球离机器人的相关角度与距离
    def DistAndDirect_cal(cxnum,rynum,colsum,rowsum,Head_angle,cameraID):
        distx=-(cxnum-colsum/2)
        disty=rynum-rowsu/2
        print distx,disty
        Picture_angle=disty*47.64/480
    
        if cameraID ==0:
            h=0.62
            Camera_angle=12
        else:
            h=0.57
            Camera_angle=38
        #Head_angle[0]机器人仰俯角度
        Total_angle=math.pi*(Picture_angle+Camera_angle)/180+Head_angle[0]
        d1=h/math.tan(Total_angle)
    
        alpha=math.pi*(distx*60.92/640)/180
        d2=d1/math.cos(alpha)
        #Head_angle[1]机器人左右角度
        Forward_Distance=d2*math.cos(alpha+Head_angle[1])
        Sideward_Distance=-d2*math.sin(alpha+Head_angle[1])
    #***********************************************
    
    #@函数名:   GetNaoImage(IP,PORT,cameraID)
    #@参数:     略
    #@返回值:   无
    #@功能说明: 采调用机器人内置摄像头控制模块,对当前场景进行拍摄并保持。
    #           由于球距离机器人约小于0.6m时,机器人额头摄像头无法看到,
    #           所以需要变换摄像头,cameraID=0,取上摄像头;
    #           cameraID=1,取下摄像头
    def Get NaoImage(IP,PORT,cameraID):
        camProxy=ALProxy("ALVideoDevice",IP,PORT)
        resolition=2 #VGA格式640*480
        colorSpace=11#RGB
    
        #选择并启用摄像头
        camProxy.setParam(vision_definitions.kCameraSelectID,cameraID)
        videoClient=camProxy.subscribe("python_client",resolition,colorSpace,5)
    
        #获取摄像机图像。
        #image [6]包含以ASCII字符数组形式传递的图像数据。
        naoImage=camProxy.getImageRemote(videoClient)
    
        camProxy.unsubscribe(videoClient)
        #获取图像大小和像素阵列。
        imageWidth=naoImage[0]
        imageHeight=naoImage[1]
        array=naoImage[6]
        #从我们的像素阵列创建一个PIL图像。
        im=Image.fromstring("RGB",(imageWidth,imageHeight),array)
        #保存图像。
        im.save("temp.jpg","JPEG")
    
    #***********************************************
    #@函数名:   findColorPattern(img,pattern)
    #@参数:     略
    #@返回值:   无
    #@功能说明:  将RGB图像转化为二值图:此方法用的是cv,可以尝试用cv2代码会更加简洁
    def  findColorPattern(img,pattern):
        channels=[None,None,None]
        channels[0]=cv.CreateImage(cv.GetSize(img),8,1)
        channels[1]=cv.CreateImage(cv.GetSize(img),8,1)
        channels[2]=cv.CreateImage(cv.GetSize(img),8,1)
        ch0=cv.CreateImage(cv.GetSize(img),8,1)
        ch1=cv.CreateImage(cv.GetSize(img),8,1)
        ch2=cv.CreateImage(cv.GetSize(img),8,1)
        cv.Split(img,ch0,ch1,ch2,None)
        dest=[None,None,None,None]
        dest[0]=cv.CreateImage(cv.GetSize(img),8,1)
        dest[1]=cv.CreateImage(cv.GetSize(img),8,1)
        dest[2]=cv.CreateImage(cv.GetSize(img),8,1)
        dest[3]=cv.CreateImage(cv.GetSize(img),8,1)
        cv.Smooth(ch0,channels[0],cv.CV_GAUSSIAN,3,3,0)
        cv.Smooth(ch1,channels[1],cv.CV_GAUSSIAN,3,3,0)
        cv.Smooth(ch2,channels[2],cv.CV_GAUSSIAN,3,3,0)
        for i in range(3):
            k=2-i
            lower=pattern[k]-75#设置阈值
            upper=pattern[k]+75
            cv.InRangeS(channels[i],lower,upper,dest[i])
    
        cv.And(dest[0],dest[1],dest[3])
        temp=cv.CreateImage(cv.GetSize(img),8,1)
        cv.And(dest[2],dest[3],temp)
        '''
        cv.NameWindow("result",cv.CV_WINDOW_AUTOSIZE)
        cv.ShowImage("result",temp)
        cv.WaitKey(0)
        '''
        return temp
    
    #***********************************************
    #@函数名:   xyProject(matrix,imgaesize)
    #@参数:     matrix
    #           imgaesize
    #@返回值:   无
    #@功能说明: 利用二值图,计算球的像素坐标。其原理是:遍历各行各列
    #           像素的数值的和,最大的组合即为球心坐标
    def xyProject(matrix,imagesize):
        #声明一个数据类型为8位型单通道的imagessize[1]*1/1*imagessize[0]矩阵(初始值为 0)。
        colmask=cv.CreateMat(imagessize[1],1,cv.CV_8UC1)
        rowmask=cv.CreateMat(1,imagessize[0],cv.CV_8UC1)
        cv.Set(colmask,1)
        cv.Set(rowmask,1)
    
        colsum=[]
        for i in range(imagesize[0]):
            col=cv.GetCol(matrix,i)
            #计算向量点积
            a=cv.DotProduct(colmask,col)
            colsum.append(a)
    
        rowsum=[]
        for i in range(imagesize[1]):
            row=cv.GetRow(matrix,i)
            a=cv.DotProduct(rowmask,row)
            rowsum.append(a)
    
        return(colsum,rowsum)#得到各行各列“1”值的和
    
    def crMax(colsum,rowsum):
        cx=max(colsum)
        ry=max(rowsum)
        for i in range(len(colsum)):
            if colsum[i]==cx:
                cxnum=i
        for i in range(len(rowsum)):
            if rowsum[i]==ry:
                rynum=i
        return(cxnum,rynum)
    #***********************************************
    #@函数名:  GetHeadAngles(robotIP,PORT)
    #@参数:    略
    #@返回值:   无
    #@功能说明:
    def GetHeadAngles(robotIP,PORT):
        motionProxy=ALProxy("ALMotion",robotIP,PORT)
        names=["HeadPitch","HeadYaw"]
        useSensors=1
        sensorAngles=motionProxy.getAngles(names,useSensors)
        return sensorAngles
    #***********************************************
    #@函数名:  SetHeadAngles(robotIP,PORT,angles)
    #@参数:    略
    #@返回值:   无
    #@功能说明:
    def SetHeadAngles(robotIP,PORT,angles):
        motionProxy=ALProxy("ALMotion",robotIP,PORT)
        motionProxy.setStiffnesses("Head",1.0)
    
        names=["HeadPitch","HeadYaw"]
        fractionMaxSpeed=0.2
        motionProxy.setAngles(names,angles,fractionMaxSpeed)
    
        time.sleep(2.0)
        motionProxy.setStiffnesses("Head",0.0)
    
    #***********************************************
    #@函数名:   Capture_Picture(IP,PORT,cameraID,angles,pattern_colors)
    #@参数:     angles
    #           pattern_colors
    #@返回值:   无
    #@功能说明: 将上面的一系列函数整合起来
    
    def Capture_Picture(IP,PORT,cameraID,angles,pattern_colors):
        SetHeadAngles(IP,PORT,angles)
        GetNaoImage(IP,PORT,cameraID)
        image=cv.LoadImage("temp.jpg")
        imagesize=cv.GetSize(image) #返回数值,两个元素分别为列数和行数
        matrix=findColorPattern(image,pattern_colors)
        (colsum,rowsum)=xyProject(matrix,imagesize)
        (cxnum,rynum)=crMax(colsum,rowsum)
        cv.SaveImage("result.jpg",matrix)
    
        return (cxnum,rynum,colsum,rowsum)
    
     
    
    #***********************************************
    #@函数名:   Target_Detect_and_Distance(IP,PORT)
    #@参数:
    #@返回值:   无
    #@功能说明: 当上摄像头无法找到球时,切换到下摄像头,然后在左转右转。
    #       在这个过程中,如果发现目标,则计算距离并输出距离
    #       若始终未找到目标,则输出距离为0。
    
    def Target_Detect_and_Distance(IP,PORT):
        pattern_colors=(255,150,50)
        cameraID=0# 默认上摄像头
        angles=[0,0]
        (cxnum,rynum,colsum,rowsum)=Capture_Picture(IP,PORT,cameraID,angles)
    
        if(cxnum,rynum)==(639,479):
            cameraID=1
            (cxnum,rynum,colsum,rowsum)=Capture_Picture(IP,PORT,cameraID,angles)
        if(cxnum,rynum)==(639,479):
            cameraID=0
            angles=[0.0.7]
            (cxnum,rynum,colsum,rowsum)=Capture_Picture(IP,PORT,cameraID,angles)
        if(cxnum,rynum)==(639,479):
            cameraID=0
            angles=[0,-0.7]
            (cxnum,rynum,colsum,rowsum)=Capture_Picture(IP,PORT,cameraID,angles)
        HeadAngles-GetHeadAngles(IP,PORT)
        ###############
        (Forward_Distance,Sideward_Distance)=DistAndDirect_cal(cxnum,rynum,colsum,rowsum,Head_angle,cameraID)
        if(cxnum,rynum)==(639,479):
            (Forward_Distance,Sideward_Distance)=(0,0)
        print "Forward_Distance=",Forward_Distance,"meters"
        print "Sideward_Distance="+Sideward_Distance+"meters"
    
    #***********************************************
    #@函数名:   Target_Detect_and_Distance(IP,PORT)
    #@参数:
    #@返回值:   无
    #@功能说明: 当找到球后,可能会存在一定的误差。
    #           因此需要判断球位于机器人前方的哪一侧,再来确定用哪只脚踢球
    
    def Final_See(robotIP,PORT):
        pattern_colors=(255,150,50)
        angles=[0.5,0]
        SetHeadAngles(robotIP,PORT,angles)
    
        cameraID=1
    
        GetNaoImage(robotIP,PORT,cameraID)
        image=cv.LoadImage("temp.jpg")
        imagesize=cv.GetNaoImage(image)
    
        matrix=findColorPattern(image,pattern_colors)
    
        (colsum,rowsum)=xyProject(matrix,imgaesize)
        (cxnum,rynum)=crMax(colsum,rowsum)
        cv.SaveImage("result.jpg",matrix)
    
        HeadAngles=GetHeadAngles(robotIP,PORT)
        #########################
        (Forward_Distance,Sideward_Distance)=DistAndDirect_cal(cxnum,rynum,colsum,rowsum,Head_angle,cameraID)
    
        if cxnumlen(colsum)/2:
            side=0#左脚
        else:
            side=1#右脚
        print "side=",side
        print "last distance=",Forward_Distance
        return (side,Forward_Distance)

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    您可能感兴趣的文章:
    • python距离测量的方法
    • python控制nao机器人身体动作实例详解
    • python实现nao机器人身体躯干和腿部动作操作
    • python实现nao机器人手臂动作控制
    • python程序控制NAO机器人行走
    上一篇:python读取mnist数据集方法案例详解
    下一篇:Python3.8官网文档之类的基础语法阅读
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    python实现Nao机器人的单目测距 python,实现,Nao,机器,人的,