自动跟随机器人教程(五)软件部分 树莓派+电脑 摄像头图像回传
2018-02-18 19:50
190 查看
既然你熟悉了Socket编程,也可以另外再写一个类似的简易服务器客户端程序。树莓派仍然作为服务器,电脑仍然作为客户端。只不过现在是树莓派发送,电脑接收。这时的数据不再是控制指令,而是树莓派USB摄像头获得的图像数据。(通过Opencv和python-imaging库实现)这个程序可以与上一篇的程序同时运行,只需要用两个独立的端口就行。
程序的基本实现方式是通过opencv的库把摄像头获取到的每一幅图像转化为String,再利用python-imaging的压缩为jpeg格式,然后用socket发出去。电脑收到每一小段数据后再把每一段的String转为一桢图像,并显示在窗口中。(你所看到的视频,其实就是不停运动着的照片)。
如果熟悉Opencv的话,可以在这里对图像进行处理,比如用haarcascade做一下图像识别(人脸识别、人体识别),既可以在发送前,在树莓派上就处理图像,也可以发送后在电脑上进行处理。
由于本项目的最终要求是机器人要独立运行,因此建议大部分处理在树莓派上做,这样就要考虑性能问题。树莓派虽然能用haarcascade做人脸识别或者人体识别(上半身),但是性能还不够,能达到的帧率较低,所以最终还是采用了颜色识别。实际运行效果更流畅,这个后面会详细讲到。
运行在小车树莓派上的代码:#!/usr/bin/python
import socket, time
import cv
import cv2
import Image, StringIO
#capture = cv.CaptureFromCAM(0)
#cv.SetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_WIDTH, 320)
#cv.SetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_HEIGHT, 240)
cap=cv2.VideoCapture(0)
ret=cap.set(3,320)
ret=cap.set(4,240)
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind(("0.0.0.0", 9996))
sock.listen(2)
dst, dst_addr = sock.accept()
print "Destination Connected by", dst_addr
while True:
#img = cv.QueryFrame(capture)
ret, frame = cap.read()
img=cv.fromarray(frame)
pi = Image.fromstring("RGB", cv.GetSize(img), img.tostring())
buf = StringIO.StringIO()
pi.save(buf, format = "JPEG")
jpeg = buf.getvalue()
buf.close()
transfer = jpeg.replace("\n", "\-n")
#print len(transfer), transfer[-1]
try:
dst.sendall(transfer + "\n")
time.sleep(0.04)
except Exception as ex:
dst, dst_addr = sock.accept()
print "Destination Connected Again By", dst_addr
except KeyboardInterrupt:
print "Interrupted"
break
dst.close()
sock.close()运行在电脑上的代码:#!/usr/bin/python
import cv2.cv as cv
import cv2
import socket, time, Image, StringIO
import numpy as np
HOST, PORT = "10.0.1.13", 9996
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
f = sock.makefile()
cv.NamedWindow("camera_server")
while True:
msg = f.readline()
if not msg:
break
jpeg = msg.replace("\-n", "\n")
buf = StringIO.StringIO(jpeg[0:-1])
buf.seek(0)
pi = Image.open(buf)
img = cv.CreateImageHeader((320, 240), cv.IPL_DEPTH_8U, 3)
cv.SetData(img, pi.tostring())
buf.close()
frame_cvmat=cv.GetMat(img)
frame=np.asarray(frame_cvmat)
cv2.imshow('frame',frame)
if cv2.waitKey(1)&0xFF ==ord('q'):
break
#cv.ShowImage("camera_server", img)
#if cv.WaitKey(10) == 27:
# break
sock.close()
cv.DestroyAllWindows()
程序的基本实现方式是通过opencv的库把摄像头获取到的每一幅图像转化为String,再利用python-imaging的压缩为jpeg格式,然后用socket发出去。电脑收到每一小段数据后再把每一段的String转为一桢图像,并显示在窗口中。(你所看到的视频,其实就是不停运动着的照片)。
如果熟悉Opencv的话,可以在这里对图像进行处理,比如用haarcascade做一下图像识别(人脸识别、人体识别),既可以在发送前,在树莓派上就处理图像,也可以发送后在电脑上进行处理。
由于本项目的最终要求是机器人要独立运行,因此建议大部分处理在树莓派上做,这样就要考虑性能问题。树莓派虽然能用haarcascade做人脸识别或者人体识别(上半身),但是性能还不够,能达到的帧率较低,所以最终还是采用了颜色识别。实际运行效果更流畅,这个后面会详细讲到。
运行在小车树莓派上的代码:#!/usr/bin/python
import socket, time
import cv
import cv2
import Image, StringIO
#capture = cv.CaptureFromCAM(0)
#cv.SetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_WIDTH, 320)
#cv.SetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_HEIGHT, 240)
cap=cv2.VideoCapture(0)
ret=cap.set(3,320)
ret=cap.set(4,240)
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind(("0.0.0.0", 9996))
sock.listen(2)
dst, dst_addr = sock.accept()
print "Destination Connected by", dst_addr
while True:
#img = cv.QueryFrame(capture)
ret, frame = cap.read()
img=cv.fromarray(frame)
pi = Image.fromstring("RGB", cv.GetSize(img), img.tostring())
buf = StringIO.StringIO()
pi.save(buf, format = "JPEG")
jpeg = buf.getvalue()
buf.close()
transfer = jpeg.replace("\n", "\-n")
#print len(transfer), transfer[-1]
try:
dst.sendall(transfer + "\n")
time.sleep(0.04)
except Exception as ex:
dst, dst_addr = sock.accept()
print "Destination Connected Again By", dst_addr
except KeyboardInterrupt:
print "Interrupted"
break
dst.close()
sock.close()运行在电脑上的代码:#!/usr/bin/python
import cv2.cv as cv
import cv2
import socket, time, Image, StringIO
import numpy as np
HOST, PORT = "10.0.1.13", 9996
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
f = sock.makefile()
cv.NamedWindow("camera_server")
while True:
msg = f.readline()
if not msg:
break
jpeg = msg.replace("\-n", "\n")
buf = StringIO.StringIO(jpeg[0:-1])
buf.seek(0)
pi = Image.open(buf)
img = cv.CreateImageHeader((320, 240), cv.IPL_DEPTH_8U, 3)
cv.SetData(img, pi.tostring())
buf.close()
frame_cvmat=cv.GetMat(img)
frame=np.asarray(frame_cvmat)
cv2.imshow('frame',frame)
if cv2.waitKey(1)&0xFF ==ord('q'):
break
#cv.ShowImage("camera_server", img)
#if cv.WaitKey(10) == 27:
# break
sock.close()
cv.DestroyAllWindows()
相关文章推荐
- 自动跟随机器人教程(六)软件部分 树莓派 声源定位
- 自动跟随机器人教程(七)软件部分 树莓派程序 多传感器综合
- 自动跟随机器人教程(一)(树莓派、Arduino教程)
- 【树莓派】RTC时钟模块安装教程第三部分:启动自动时间矫正
- 自动跟随机器人教程(八)采购清单
- 电脑自动开机设置教程
- 【树莓派】RTC时钟模块安装教程第二部分:Rasbian(linux)下配置工作
- [教程] 在电脑上安装Android模拟器-部分更新详解
- ROS 教程之 vision : 用各种摄像头获取图像
- SNF软件开发机器人教程更新
- 电脑启动时,自动执行制定的软件
- 【工业串口和网络软件通讯平台(SuperIO)教程】二.架构和组成部分
- 轻松工作让电脑软件全自动操作正文分析错误
- 树莓派新版系统上使用mjpg-streamer获取USB摄像头和树莓派专用摄像头RaspiCamera图像
- 【工业串口和网络软件通讯平台(SuperIO)教程】二.架构和组成部分
- OpenCV与Socket实现树莓派获取摄像头视频至电脑
- [1]树莓派控制摄像头采集图像
- Python:通过摄像头抓取图像并自动上传至新浪微博
- 机器人仿真 软件 V-REP 入门教程 (一)简介
- [OpenCV Qt教程] 在Qt图形界面中显示OpenCV图像的OpenGL Widget(第二部分)