如何在树莓派上用OpenCV来操纵摄像头拍照

如何在树莓派上用OpenCV来操纵摄像头拍照
 

1,安装OpenCV / Install OpenCV 
命令:
命令:
  1. pacman -S opencv opencv样本
复制代码

上面的命令连OpenCV的示例一起装上了,这样我们在安装好之后就可以编译几个示例来测试。
此命令也将安装OpenCV的样本。因此,我们可以编译运行及多个样品有installa经过测试 TI 上。

2,带动摄像头/驱动摄像头
在驱动已经可用的情况下,把一个USB摄像头接在USB口上也不一定能让它工作,因为Pi的USB口的电流供应可能不足。请看这个链接的玩家自制的一根增强供电的USB线,如果你想简单安全,那么你可以把摄像头接在一个有外部供电的USB HUB上,再把Pi的USB接到USB HUB上,这样摄像头的供电就充足了。
将USB网络摄像头插入到Pi的USB接口可能无法使其工作,即使驱动程序已经可用,因为Pi的USB接口提供的当前可能不足以驱动相机。您可以通过此链接学习DIY当前增强型USB电缆,但更简单的方法可能是购买有源USB HUB,并使用它连接网络摄像头和Pi。

3,让opencv的示例跑起来/运行OpenCV的样本
为了验证在Pi上安装的OpenCV是可用的,所以至少要让一个示例可以跑起来。
为了不把安装目录弄得一团乱,首先把安装好的OpenCV的示例目录拷贝到其他地方:
为了确保安装的OpenCV相关软件包是“正确的”,我决定运行至少一个OpenCV示例。
将安装的OpenCV示例目录复制到其他位置是为了不弄乱安装目录:
  1. mkdir / root / opencv
  2. cp -r / usr / share / OpenCV / samples / / root / opencv /
复制代码

我们看到里面有“c”,“cpp”和“gpu”三种样本,选最简单的,我们进入“c”,先为所有文件加上写权限:
有3种样本, c“,”cpp“&”gpu“,所以选择最简单的”c“,并输入”c“目录,向所有文件添加写入权限:
  1. chmod + w *
复制代码

然后我们看到“c”目录里有编译脚本build_all.sh,执行它,看到出了一堆相似的错误,没有一个程序可以成功编译,例如以下错误:
执行build_all.sh脚本来编译一个示例,然后我有很多类似的错误,例如:

[root @ alarmpi c]#. build_all.sh contours.c 
编译轮廓
/ usr / bin / ld:/tmp/cch4zRSn.o:未定义的引用符号'lrint @@ GLIBC_2.4' 
/ usr / bin / ld:note:'lrint @@ GLIBC_2.4'在DSO /usr/lib/libm.so.6中定义,所以尝试将其添加到链接器命令行
/ usr / lib / libm .so.6:无法读取符号:无效操作
collect2:错误:ld返回1退出状态
由libm可见,这是因为数学库没有被包含在编译命令中,于是我们编译build_all.sh,为所有编译命令添加上-lm编译参数:
“libm”告诉我,数学库没有包含在编译命令中,所以我编辑了build_all.sh并将-lm添加到所有的编译命令:
01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
#!/ bin / sh                            

if [$#-gt 0]; 然后
        base =`basename $ 1 .c` 
        echo“编译$ base” 
        gcc -ggdb`pkg-config opencv --cflags --libs` $ base.c -o $ base -lm 
else 
        for i in * .c; 
            回声“编译$ i” 
            gcc -ggdb`pkg-config --cflags opencv` -o`basename $ i .c` $ i`pkg-config --libs opencv` -lm;         为我在* .cpp中
        完成 

            回声“编译$ i” 
            g ++ -ggdb`pkg-config --cflags opencv` -o`basename $ i .cpp` $ i`pkg-config --libs opencv` -lm; 
        完成
fi 
文章来源: http  : //www.codelast.com/
还忘了说一句,由于上面的脚本在编译时使用了pkg-config,所以在编译前,我们还需要先安装pkg-config:
对不起,我忘了提到,因为使用pkg-config,我们需要在编译示例之前安装pkg-config:


pacman -S pkg-config 
然后再编译,成功,然后编译
将成功。
那么下面,我们再接着尝试把编译出的示例运行起来:
然后运行我们刚刚编译的可执行程序:

01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 

很明显,运行不起来。
看样子是跟gtk相关,并且我在网上搜到这跟X服务器什么的可能有关系,于是安装gtk和X服务器:
它失败了,不幸的是。
而Google告诉我,这个错误与X服务器有关,所以我安装了gtk&X服务器:


pacman -Sgtk xorg-server 
再修改配置文件/ etc / ssh / sshd_config:
修改配置文件/ etc / ssh / sshd_config:
  1. [root @ alarmpi c]#./contours 

  2. 该程序创建一个图像来演示使用“c”轮廓
  3. 函数:cvFindContours()和cvApproxPoly()以及存储
  4. 函数cvCreateMemStorage()和cvDrawContours()。
  5. 它还显示了使用轨迹条控制轮廓检索。
  6.   
  7. 用法:
  8. ./contours
  9.   
  10. (图像:460):Gtk-WARNING **:无法打开显示:
复制代码

  1. #AllowTcpForwarding yes
  2. AllowTcpForwarding yes
  3. #GatewayPorts no
  4. #X11推进号
  5. X11转发是的
  6. #X11DisplayOffset 10
  7. #X11UseLocalhost是的
  8. X11UseLocalhost是的
复制代码

注意,没有注释的那三行是我添加的。
请注意,我添加了3条未注释的行。
文章来源: http  : //www.codelast.com/
重启Pi的系统,运行X server:
Reboot Pi&run X服务器:
  1. X
复制代码

没错,命令就是这么简单。然后又出错了:
是的,命令只是这么简单,但是没有启动:
  1. [root @ alarmpi c]#X       

  2. X.Org X Server 1.13.0
  3. 发行日期:2012-09-05
  4. X协议版本11,修订版0
  5. 构建操作系统:Linux 3.0.15-1-ARCH + armv6l 
  6. 当前操作系统:Linux alarmpi 3.2.27-11-ARCH +#1 PREEMPT Sat Oct 13 22:46:16 UTC 2012 armv6l
  7. 内核命令行:dma.dmachans = 0x7f35 bcm2708_fb.fbwidth = 1920 bcm2708_fb.fbheight = 1080 bcm2708.boardrev = 0x3 bcm2708.serial = 0x398ca41f smsc95xx.macaddr = B8:27:EB:8C:A4:1F vc_mem.mem_base = 0xc000000 vc_mem .mem_size = 0x10000000 sdhci-bcm2708.enable_llm = 1 sdhci-bcm2708.sync_after_dma = 0 smsc95xx.turbo_mode = N dwc_otg.lpm_enable = 0 console = ttyAMA0,115200 kgdboc = ttyAMA0,115200 console = tty1 loglevel = 2 root = / dev / mmcblk0p2 init = / bin / systemd rootfstype = ext4 rootwait
  8. 建立日期:2012年10月14日10:05:22 PM
  9.   
  10. 当前版本的pixman:0.26.2
  11.   在报告问题之前,请查阅http://wiki.x.org
  12.   以确保您具有最新版本。
  13. 标记:( - )探测,(**)从配置文件,(==)默认设置,
  14.   (++)从命令行,(!!)通知,(II)信息,
  15.   (WW)警告,(EE)错误,(NI)未实现,(??)未知。
  16. (==)日志文件:“/var/log/Xorg.0.log”,时间:星期一10月15日14:30:03 2012
  17. (==)使用config目录:“/etc/X11/xorg.conf.d”
  18. 初始化内置扩展Generic Event Extension
  19. 初始化内置扩展SHAPE
  20. 初始化内置扩展MIT-SHM
  21. 初始化内置扩展XInputExtension
  22. 初始化内置扩展XTEST
  23. 初始化内置扩展BIG-REQUESTS
  24. 初始化内置扩展SYNC
  25. 初始化内置扩展XKEYBOARD
  26. 初始化内置扩展XC-MISC
  27. 初始化内置扩展安全
  28. 初始化内置扩展XINERAMA
  29. 初始化内置扩展XFIXES
  30. 初始化内置扩展RENDER
  31. 初始化内置扩展RANDR
  32. 初始化内置扩展COMPOSITE
  33. 初始化内置扩展名为DAMAGE
  34. 初始化内置扩展MIT-SCREEN-SAVER
  35. 初始化内置扩展DOUBLE-BUFFER
  36. 初始化内置扩展名RECORD
  37. 初始化内置扩展DPMS
  38. 初始化内置扩展X资源
  39. 初始化内置扩展XVideo
  40. 初始化内置扩展XVideo-MotionCompensation
  41. 初始化内置扩展XFree86-VidModeExtension
  42. 初始化内置扩展XFree86-DGA
  43. 初始化内置扩展XFree86-DRI
  44. 初始化内置扩展DRI2
  45. 加载扩展GLX

  46. 致命的服务器错误:
  47. 没有找到任何屏幕
  48. (EE) 
  49. 请参阅X.Org Foundation支持 
  50.    在http://wiki.x.org
  51.   求助。 
  52. (EE)另请参阅“/var/log/Xorg.0.log”中的日志文件。
  53. (EE) 
  54. 服务器终止错误(1)。关闭日志文件。
复制代码

既然它让我看日志文件/var/log/Xorg.0.log,那我就看。在日志文件的最后,发现提示找不到fbdev模块/库,于是翻遍谷歌,找到一个答案:应该安装xf86-video-fbdev包:
因为它告诉我检查日志文件/var/log/Xorg.0.log,那我就做了。在日志文件的最后几行,我发现一个错误消息,指出fbdev模块/ lib丢失,所以我再问一次Google,我意识到我应该安装包xf86-video-fbdev:
  1. pacman -S xf86-video-fbdev
复制代码


再用“X”命令启动X服务器,成功了:
  1. 然后再次运行“X”,成功了:

  2. [root @ alarmpi〜]#X

  3. X.Org X Server 1.13.0
  4. 发行日期:2012-09-05
  5. X协议版本11,修订版0
  6. 构建操作系统:Linux 3.0.15-1-ARCH + armv6l 
  7. 当前操作系统:Linux alarmpi 3.2.27-11-ARCH +#1 PREEMPT Sat Oct 13 22:46:16 UTC 2012 armv6l
  8. 内核命令行:dma.dmachans = 0x7f35 bcm2708_fb.fbwidth = 1920 bcm2708_fb.fbheight = 1080 bcm2708.boardrev = 0x3 bcm2708.serial = 0x398ca41f smsc95xx.macaddr = B8:27:EB:8C:A4:1F vc_mem.mem_base = 0xc000000 vc_mem .mem_size = 0x10000000 sdhci-bcm2708.enable_llm = 1 sdhci-bcm2708.sync_after_dma = 0 smsc95xx.turbo_mode = N dwc_otg.lpm_enable = 0 console = ttyAMA0,115200 kgdboc = ttyAMA0,115200 console = tty1 loglevel = 2 root = / dev / mmcblk0p2 init = / bin / systemd rootfstype = ext4 rootwait
  9. 建立日期:2012年10月14日10:05:22 PM
  10.   
  11. 当前版本的pixman:0.26.2
  12.   在报告问题之前,请查阅http://wiki.x.org
  13.   以确保您具有最新版本。
  14. 标记:( - )探测,(**)从配置文件,(==)默认设置,
  15.   (++)从命令行,(!!)通知,(II)信息,
  16.   (WW)警告,(EE)错误,(NI)未实现,(??)未知。
  17. (==)日志文件:“/var/log/Xorg.0.log”,时间:Mon Oct 15 14:32:34 2012
  18. (==)使用config目录:“/etc/X11/xorg.conf.d”
  19. 初始化内置扩展Generic Event Extension
  20. 初始化内置扩展SHAPE
  21. 初始化内置扩展MIT-SHM
  22. 初始化内置扩展XInputExtension
  23. 初始化内置扩展XTEST
  24. 初始化内置扩展BIG-REQUESTS
  25. 初始化内置扩展SYNC
  26. 初始化内置扩展XKEYBOARD
  27. 初始化内置扩展XC-MISC
  28. 初始化内置扩展安全
  29. 初始化内置扩展XINERAMA
  30. 初始化内置扩展XFIXES
  31. 初始化内置扩展RENDER
  32. 初始化内置扩展RANDR
  33. 初始化内置扩展COMPOSITE
  34. 初始化内置扩展名为DAMAGE
  35. 初始化内置扩展MIT-SCREEN-SAVER
  36. 初始化内置扩展DOUBLE-BUFFER
  37. 初始化内置扩展名RECORD
  38. 初始化内置扩展DPMS
  39. 初始化内置扩展X资源
  40. 初始化内置扩展XVideo
  41. 初始化内置扩展XVideo-MotionCompensation
  42. 初始化内置扩展XFree86-VidModeExtension
  43. 初始化内置扩展XFree86-DGA
  44. 初始化内置扩展XFree86-DRI
  45. 初始化内置扩展DRI2
  46. 加载扩展GLX
复制代码

再试着运行OpenCV的示例,依然不行,Google搜索到一篇在Pi上运行OpenCV的文章,作者做了这样一件事情:
然后我试图再次运行OpenCV样本,仍然是同样的错误(“不能打开显示“),所以我Googled关于在Pi上使用OpenCV的另一篇文章,发现作者做了一件事:
  1. 导出DISPLAY = 192.168.3.65:0.0
复制代码

其中,192.168.3.65是Pi的IP地址。这样设置之后,再运行,程序不再报错了!再一看相同的目录下,生成了一个contours.xml文件,说明程序执行成功了
,其中“ 192.168.3.65“是您的Pi的IP地址。设置完毕后,样本可以运行而没有发生任何错误,并且在同一目录下生成了一个contours.xml文件,这表明我们成功了。

【4】写一个简单的OpenCV C程序/写一个简单的OpenCV C程序
现在该写一个简单的OpenCV C程序来控制摄像头了
现在我们应该使用OpenCV编写一个简单的C程序来控制网络摄像头

直接看程序:
让我们来看看C代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include“highgui.h”
  4. #include“opencv.hpp”

  5. int main(int argc,char ** argv){
  6.   / *初始化摄像头* /
  7.   CvCapture * pCapture = cvCreateCameraCapture(0);
  8.   cvSetCaptureProperty(pCapture,CV_CAP_PROP_FRAME_WIDTH,320); 
  9.   cvSetCaptureProperty(pCapture,CV_CAP_PROP_FRAME_HEIGHT,240);
  10.   // cvSetCaptureProperty(pCapture,CV_CAP_PROP_FPS,5);

  11.   IplImage * pFrame = 0;

  12.   if(NULL == pCapture){
  13.     fprintf(stderr,“can not initialize webcam!\ n”);
  14.     return 1;
  15.   }

  16.   pFrame = cvQueryFrame(pCapture); //查询一个框架

  17.   if(NULL == pFrame){
  18.     fprintf(stderr,“can not get a frame!\ n”);
  19.     return 1;
  20.   }

  21.   const char * pImageFileName =“webcam.jpg”;
  22.   cvSaveImage(pImageFileName,pFrame);

  23.   cvReleaseCapture(&pCapture); //空闲内存

  24.   return 0;
  25. }
复制代码

此程序做的事情非常简单:初始化摄像头,抓取一帧,然后保存为名为“webcam.jpg”的图片。
该程序做一个非常简单的工作:初始化相机,捕获帧并将其保存到图像文件名为“webcam.jpg”。

编译自己的webcam程序:
然后编译网络摄像头程序:
  1. g ++ -I / usr / include / opencv / -I / usr / include / opencv2 /`pkg-config --cflags opencv --libs opencv` webcam.c -o webcam
复制代码

会生成一个可执行程序“webcam”,运行它:
这将生成一个可执行文件“webcam”,只需运行它:
  1. 。/摄像头
复制代码



然后在相同目录下,会看到生成了一个“webcam.jpg”图片,正是摄像头拍的照,
然后我们将在同一目录下找到一个“webcam.jpg”图像文件,这只是照片相机。

这样,本文的主要目的就达成了。可以在此基础上继续开发其他的程序,来实现更为有用的功能,例如像摄像头娘一样的运动检测功能
因此,本文的主要目的已经到达 我们可以开发更有用的程序,例如类似于Camera Girl的程序,它实现运动检测功能。

【5】遗留问题/未解决的问题
在上述过程中,其实我还遇到了一些未解决的问题,暂时没有时间深究,在此先记录如下。在上述过程中,遇到一些未解决的问题,没有时间
探索他们还在,所以我只是把它们写下来进一步学习。

使用稍高的分辨率就导致程序崩溃/使用一点高分辨率会导致程序崩溃
在上面的程序中,如下两句是用于设置分辨率的(宽*高):
在上面的代码下面的两行用于设置分辨率:



  1. cvSetCaptureProperty(pCapture,CV_CAP_PROP_FRAME_WIDTH,320); 
  2. cvSetCaptureProperty(pCapture,CV_CAP_PROP_FRAME_HEIGHT,240);
复制代码

cvSetCaptureProperty(pCapture,CV_CAP_PROP_FRAME_WIDTH,320); 
cvSetCaptureProperty(pCapture,CV_CAP_PROP_FRAME_HEIGHT,240); 
根据我的试验,160 * 120的低分辨率比较少出问题,尽管320 * 240的分辨率对摄像头来说也根本不算高的,但是就算是使用320 * 240的分辨率,程序还是偶尔会崩溃的,报错如下:
根据我的实验,160 * 120的低分辨率比较高的分辨率导致更少的崩溃。即使320 * 240对于网络摄像头来说也不是一个高分辨率,它仍然使程序崩溃了一些,错误信息是:
  1. [root @ alarmpi c]#./webcam 
  2. VIDIOC_QUERYMENU:参数无效
  3. VIDIOC_QUERYMENU:参数无效
  4. VIDIOC_QUERYMENU:参数无效
  5. VIDIOC_REQBUFS:无法分配内存
  6. munmap:参数无效
  7. munmap:参数无效
  8. munmap:参数无效
  9. munmap:参数无效
  10. 无法停止流:不良文件描述符
  11. munmap:参数无效
  12. munmap:参数无效
  13. munmap:参数无效
  14. munmap:参数无效
  15. HIGHGUI ERROR:V4L:初始捕获错误:无法加载初始内存缓冲区。
  16. 不能得到一个框架!
复制代码
  1. [root @ alarmpi c]#./webcam 
  2. VIDIOC_QUERYMENU:参数无效
  3. VIDIOC_QUERYMENU:参数无效
  4. VIDIOC_QUERYMENU:参数无效
  5. VIDIOC_REQBUFS:无法分配内存
  6. munmap:参数无效
  7. munmap:参数无效
  8. munmap:参数无效
  9. munmap:参数无效
  10. 无法停止流:不良文件描述符
  11. munmap:参数无效
  12. munmap:参数无效
  13. munmap:参数无效
  14. munmap:参数无效
  15. HIGHGUI ERROR:V4L:初始捕获错误:无法加载初始内存缓冲区。
  16. 不能得到一个框架!
复制代码


或者:
或者:
  1. VIDIOC_REQBUFS:无法分配内存
  2. HIGHGUI ERROR:V4L / V4L2:无法获取捕获窗口的详细信息。

  3. 无法停止流:不良文件描述符
  4. VIDIOC_QBUF:错误的文件描述符
  5. 不能得到一个框架!
复制代码

我不知道这个问题是由于Pi的CPU的计算能力弱,Pi还是太小的RAM,还是网络摄像机的电流供应不足(我没有使用电源的USB HUB来连接摄像头到Pi)或网络摄像头的Linux驱动程序... 
如果你知道某事,请告诉我,并提前感谢你
我不确定这是跟Pi的CPU计算能力较弱有关呢,还是跟Pi的RAM太小有关还是跟摄摄像头的供电不足有关呢(我没有使用带 电源 的USB HUB来接摄像头),或者是跟摄摄像头的驱动有关呢?
如果你知道解决办法,请赐教,非常感谢。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值