分享

【转】用pcDuino做猫脸识别

 xiaofenglib 2013-08-29
- 猫脸识别 – Kick off

今天确定了新代一目标:

能够在开发板上收到视频信号,并自动识别其中的物体(第一步不一定是猫脸)


关于猫脸识别

Open CV可以做到对任意形状的识别(Haar-like feature object detection),只要你做好训练就行。所以猫脸识别是有戏的~(不过能否区分咪大和花花的脸还未知)

找到的一些资料:

1. 用OpcenCV 做腿部识别的教学视频

2. 另一个Haar Training做人脸识别的文章

3. Haar Training算法剖析


开发板选型

考察了Raspberry Pi和MK820 mini PC以及pcDuino开发板

1. Raspberry

优势:名气最大,套件、资源挺多,开发环境搭建方便

劣势:如果要做haar-like feature detection的话,性能不够用。

2. MK820 mini PC

优势:便宜,性能好(Coretex 8 1GHz CPU   Mali 400 GPU)

劣势:不是开发板,开发环境支持、

3. pcDuino

优势:

a. 主要硬件指标和MK820差不多、性能好;

b. 开发板,有开源社区支持,开发环境搭建比MK820简单些;

c. 价格适中(¥370)

d. 和Arduino兼容!很方便和arduino级联。

所以,硬件方案就选pcDuino套件了!(淘宝已下单)


开发环境建立

找到一个牛人的博客,上面写的是MK802开发环境建立的文章,非常详尽。树莓派、pcDuino都是Linux的环境,这些建立过程都大体是通用的,这两篇文章帮助很大:

1. 基于MK802的应用开发和相关的工具

2. 基于MK802 MiniPC的扩展开发应用-软/硬件修改和扩展


关于摄像头、舵机等配件

之前我买的智能小车上这些都有~

这段时间的成果:

1. pcDuino板子启动正常,串口调试、XServer、SSH全部联通;

2. 升级固件和linux到最新版本(支持UVC通用驱动)、摄像头工作顺利;

3. 编译环境准备完毕。


一些填过的坑和经验:

1. USB电源线一定要买好的,我就是摊上一根有问题的,搞得前几天板子一直起不来,各种调试、各种升级、各种揣测,浪费了我至少4天的时间!

2. 串口调试要买一个FT232模块,它的驱动是通用的,google上可以查到。连上板子前,需要根据spec把线对好,GND直接相连,RXD和TXD分别交换链接。FT232连上电脑后,可以在设备管理里串口里面看到是哪个COM。

3. X11VNC当X Server不错,配置好开机自启动后,加上SSH,完全不需要显示屏、键盘、鼠标,倍儿方便!


Catface Detection – Progress Report


终于可以通过pcDuino获取摄像头图像,并通过openCV来处理了。本来预想这是非常简单的一个步骤,没想到断断续续花了我接近20个小时的时间。

摄像头识别问题搞得死去活来,到今天中午终于找到一个work around,知道现在最终答案还没有完全水落石出。


稍微总结一下苦逼的历程:


【最初现象描述】


摄像头接入后,用pcDuino ubuntu自带的guvcview可以正常的打开视频。但是,用openCV整死打不开摄像头:

    VideoCapture cap(0); // open the default camera
if(!cap.isOpened())  // check if we succeeded
{
printf(“capture open failed!”);
return -1;
}

【探索解决 – Round 1 – 是openCV库编得有问题?】


最开始以为是openCV编译得有问题,是不是没有把一些视频操作相关的库支持打开。okay,一通安装:ffmpeg、unicap、xine、gstreamer、v4l2。还纠结了好一段时间为啥我的unicap安装了openCV的cmake就是识别不出来等等诸多菜鸟问题。

总之,最后这些都编进去了,满怀希望的把openCV又编译了一遍。。。两个多小时啊(没有建立交叉编译环境,后悔了)。

运行demo,还是识别不出来  T__T


【探索解决 – Round 2 — Linux驱动正确安装了么?】

我的这个摄像头到底是什么来头?

用lsusb,发现返回的数据都还有板有眼:

haomin@ubuntu:/mnt/sd/usr/bin$ lsusb
Bus 001 Device 002: ID 0c45:62f1 Microdia
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

再跟上-v 看详情

lsusb -d 0c45:62f1 -v

发现这个USB的芯片供应商是Sonix,venderid=0c45 / deviceid=62f1。这是个台湾厂家。拿着芯片型号去UVC的网站查了查,好像是支持的。


为了确定我的内核是不是安装了uvc驱动,去pcDuino的repository拉了最新的内核源代码,建立好交叉编译环境,呼:

make menuconfig

发现uvc的驱动在默认配置里面就已经装上了:


另外,通过dmesg也能够证实系统正确识别了摄像头,插上摄像头之后:

sudo dmesg | tail
[ 3445.710000] usb 1-1: new high-speed USB device number 3 using sw-ehci
[ 3445.900000] usb 1-1: New USB device found, idVendor=0c45, idProduct=62f1
[ 3445.900000] usb 1-1: New USB device strings: Mfr=2, Product=1, SerialNumber=0
[ 3445.900000] usb 1-1: Product: USB 2.0 Camera
[ 3445.900000] usb 1-1: Manufacturer: Sonix Technology Co., Ltd.
[ 3445.900000] uvcvideo: Found UVC 1.00 device USB 2.0 Camera (0c45:62f1)
[ 3445.910000] input: USB 2.0 Camera as /devices/platform/sw-ehci.1/usb1/1-1/1-1:1.0/input/input2

驱动安装了,识别也没问题,为啥不行呢?这一轮虽然又学习了很多诊断方法,不过还是无果。


【探索解决 – Round 3  – 跟代码】

实在是没头绪,直接上GDB跟代码看看究竟总可以吧。gdb进去之后发现openCV是release模式,好吧,再来两个小时。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

Debug模式把opencv再编译好后,再次架上gdb,跟进去一看,里面是一个大switch,把所有能够打开摄像头的方法都遍历一边。这样看来,前面装那么多库都是没用的,摄像头支持UVC的话,就用V4L就可以了。里面充斥这这样类似的代码:

229#if defined HAVE_LIBV4L || defined HAVE_CAMV4L || defined HAVE_CAMV4L2 || defined HAVE_VIDEOIO
230            capture = cvCreateCameraCapture_V4L (index);
231            if (capture)
232                return capture;
233#endif

288#ifdef HAVE_UNICAP
289        case CV_CAP_UNICAP:
290            capture = cvCreateCameraCapture_Unicap (index);
291            if (capture)
292                return capture;
293        break;
294#endif

Anyway,重点看了看V4L的打开函数:cvCreateCameraCapture_V4L (index) 为什么会失败。V4L在打开之前都会试探一下有多少可用的摄像头,它用的办法是用open系统调用尝试打开所有/dev/video%d,打开了就算可用。

378   while(CameraNumber < MAX_CAMERAS) {
379      /* Print the CameraNumber at the end of the string with a width of one character */
380      sprintf(deviceName, ”/dev/video%1d”, CameraNumber);
381      /* Test using an open to see if this new device name really does exists. */
382      deviceHandle = open(deviceName, O_RDONLY);
383      if (deviceHandle != -1) {
384         /* This device does indeed exist – add it to the total so far */
385    // add indexList
386    indexList|=(1 << CameraNumber);
387        numCameras++;
388    }

我心爱的deviceName=’/dev/video0′运行到382行时,居然发现打不开文件句柄! 哭了,爷彻底哭了。。。为啥啊,这是为啥?

这一轮探索不算失败,总算有了些进展,最直接的原因是/dev/video0打不开文件句柄


【问题探索 – Round 4 – 为啥guvcview/ luvcview能打开摄像头?】

为啥luvcview / guvcview 这些工具就能够打开摄像头、我自己写的程序就不行?一团迷糊,在上网闲逛了一阵子,突然想起可以用strace看看程序系统调用。

对比了一下我的程序与luvcview的系统调用,发现luvcview也调用了 open

open(“/dev/video0″, O_RDWR)             = 5

人家还很霸气,是RDWR的都成功了。离问题弄清又进了一步,为啥我连RDONLY都打不开?


【问题解决 – Round5 – 无语的解决】

念叨着念叨着,我随手一敲:

sudo ./opencvdemo

好了!窗口出来了!demo出来了!我胜利的手势出来了!


【解决后的疑惑】

为什么我的demo就要sudo,我在使用luvcview的时候没有sudo,为什么也可以?

不过这真心不是我需要关心的重点,我重点要做的事情还在后头。


猫脸识别! 我来了!

转自:X Projects  http://xprojects.lofter.com/


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多