nao作为一个机器人,视觉对其非常重要,也就是它的摄像头。在nao这个平台上如何从摄像头获取图像数据进而进行处理?首先看看给的例子:
#include <alproxies/alvideodeviceproxy.h>
#include <alimage.h>
#include <alvisiondefinitions.h>
// Opencv includes.
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <iostream>
#include <string>
using namespace AL;
void showImages(const std::string& robotIp)
{
// Create a proxy to ALVideoDevice on the robot.
ALPtr<ALVideoDeviceProxy> camProxy = makeALPtr(new ALVideoDeviceProxy(robotIp, 9559));
// Subscribe a client image requiring 320*240 and BGR colorspace.
const std::string clientName = camProxy->subscribe("test", kQVGA, kBGRColorSpace, 30);
// Create an iplimage header to wrap into an opencv image.
IplImage* imgHeader = cvCreateImageHeader(cvSize(320, 240), 8, 3);
cvNamedWindow("images");
// Main loop. Exit when pressing ESC.
while (cvWaitKey(30) != 64)
{
// Retrieve an image from the camera.
ALValue img = camProxy->getImageRemote(clientName);
// Assign our image binary to the opencv image.
imgHeader->imageData = (char*)img[6].GetBinary();
// Display it on screen.
cvShowImage("images", imgHeader);
}
// Cleanup.
camProxy->unsubscribe(clientName);
cvReleaseImageHeader(&imgHeader);
}
int main(int argc, char* argv[])
{
if (argc < 2)
{
std::cerr << "Usage 'getimages robotIp'" << std::endl;
return 1;
}
const std::string robotIp(argv[1]);
try
{
showImages(robotIp);
}
catch (const ALError& e)
{
std::cerr << "Caught exception " << e.what() << std::endl;
}
return 0;
}
能够看出来首先是要定义一个ALVideoDeviceProxy 用于操作视频设备,其中最为重要的一个操作是const std::string clientName = camProxy->subscribe("test", kQVGA, kBGRColorSpace, 30);,这个相当是从nao的视频管理那订阅了视频,然后是ALValue img = camProxy->getImageRemote(clientName);,把图像取出来。剩下了就是不断的取出图像显示,当按下Esc时退出。最后在程序结束前释放订阅的视频,释放分配的图像内存。从这个例子我们可以看出,要操作图像有4个步骤:1、申请ALVideoDeviceProxy 的代理,2、订阅subscribe 3、获取图像,4、退定unsubscribe。这个例子是可执行的,可以直接在电脑上运行,远程的获取摄像头的图像数据。然后我们需要的是一个module。
在图像处理的过程中,一要考虑的是循环调用,二要考虑速度,也就是会不断的读取图像处理图像。在这里我们暂时没有用例子里的视觉模板,而是自己生成的module。
所在自己的module里主要有三个部分 申请 处理 退订。故而处理部分就会被循环的调用。
申请:
AL::ALPtr<AL::ALVideoDeviceProxy> openCamera;
openCamera = AL::ALPtr<ALVideoDeviceProxy>(new ALVideoDeviceProxy(getParentBroker()));
moduleName =openCamera->subscribe(moduleName,kQVGA,kBGRColorSpace, 30 );
这里只是主要步骤,为了提高速度,会将图像部分的变量定义为成员变量。
处理:
imageln = (ALImage*)openCamera->getImageLocal(moduleName);
ballimg->imageData = (char*)imageln->getFrame();
openCamera->releaseImage(moduleName);
在ballimg->imageData里就是图像的数据,可以循环的调用进行你的处理了。
退订:
openCamera->unsubscribe(moduleName);
cvReleaseImage(&ballimg);
cvReleaseImage(&ballimg_gray);
cvReleaseImage(&ballimg_rgb);
cvReleaseImage(&ballimgtohsv);
cvReleaseImage(&dstContourBallImg);
cvReleaseImage(&