1

我们是一些 IT 专业的学生,​​我们正在研究 NAO(所以我们是初学者)。我们希望使用 NAO 相机在地面上通过线检测来实现寻路。为此,我们在 Choregraphe 中开发了一个Python 脚本框,但我们无法正确订阅和取消订阅“ ALVideoDevice

这是 Python 脚本框的代码:

import sys
import numpy as np
import cv2
from naoqi import ALProxy
import PIL
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import vision_definitions as vd

def avg_lines_angles(lines):
    angle_sum = 0
    for line in lines:
        angle_sum = angle_sum + get_angle(line[0])
    return angle_sum/len(lines)

def get_angle(tupl):
    x1,y1,x2,y2 = tupl
    dy = (y2-y1)
    dx = (x2-x1)
    angle = np.arctan2(dy,dx)
    if angle < 0:
        angle = angle + np.pi
    return angle

class MyClass(GeneratedClass):
    def __init__(self):
        GeneratedClass.__init__(self)

    def onLoad(self):
        self.nameID = "test_subscribe"
        self.videoDevice = ALProxy('ALVideoDevice')
        self.captureDevice = self.videoDevice.subscribe(self.nameID, vd.k4VGA, vd.kRGBColorSpace, 20)

    def onUnload(self):
        #put clean-up code here
        self.videoDevice.unsubscribe(self.nameID)

    def onInput_onStart(self):
        index = None
        # get image
        result = self.videoDevice.getImageRemote(self.captureDevice);
        if result == None:
            print 'cannot capture.'
            #self.onUnload()
            self.onError()
        # show image
        else:
            basewidth = 600
            img = Image.fromstring("RGB",(result[0],result[1]),result[6])
            self.videoDevice.releaseImage(self.nameID)
            img = img.crop((img.size[0]/4,3*img.size[1]/5,3*img.size[0]/4,img.size[1]))
            wpercent = (basewidth/float(img.size[0]))
            hsize = int((float(img.size[1])*float(wpercent)))
            img = img.resize((basewidth,hsize), Image.ANTIALIAS)
            gray = img.convert("L")
            gray = np.array(gray)
            edges = cv2.Canny(gray,50,150,apertureSize = 3)
            cv2.imwrite("/home/nao/Pictures/debug.jpg",edges)
            lines = cv2.HoughLinesP(edges,1,np.pi/180,60,minLineLength=50,maxLineGap=30)
            try:
                angle = avg_lines_angles(lines)
                self.onStopped(angle)
            except:
                self.onError()
            #self.onUnload()


    def onInput_onStop(self):
        #self.onUnload() #it is recommended to reuse the clean-up as the box is stopped
        self.onStopped(-1) #activate the output of the box

我们在加载类时订阅服务,并且在卸载类时取消订阅。真正奇怪的是取消订阅时的错误:

[ERROR] vision.videodevice :unsubscribe:0 Can't unsubscribe "test_subscribe", subscriber is unknown.

我们的盒子处于一个循环中,订阅者的数量限制了我们可以做的事情。我们能够从 ALVideoDevice 获取图像,所以我们订阅了。但是使用相同的名称退订根本不起作用。我们在 Python SDK API 中没有找到任何内容,只有一些准确描述我们正在做什么的教程(订阅 -> 使用 ALVideoDevice 的代码 -> 取消订阅)

4

1 回答 1

1

您的问题是您使用订阅者的名称取消订阅,而您应该使用订阅时提供给您的句柄来取消订阅 - 所以在您的情况下,您应该这样做

self.videoDevice.unsubscribe(self.captureDevice)
于 2018-06-13T07:42:52.540 回答