[关闭]
@XiangZhou 2015-06-27T08:24:49.000000Z 字数 2549 阅读 2908

基于tornado实现web camera

python tornado web_camera 服务器


最近在学习python,找了一个框架学习,我选择的是tornado,因为其不只是一个web开发框架,其还是一个服务器,异步事件库,一举多得。
我一直在完opencv,我想接合他们两个做一个web camera,这就开始。
在tornado中要实现对一个URL的响应,需要实现你自己的Handle,根据你对外提供的接口,实现相关的接口就好了。
下面为整个工程的文件内容:

  1. import tornado.ioloop
  2. import tornado.web
  3. import tornado.gen
  4. import cv2
  5. from tornado.options import define, options
  6. define("port", default = 5000, help = "run in tornado on xxxx port", type = int)
  7. define("id", default = 0, help = "camera id", type = int)
  8. def auth(func):
  9. def _auth(self):
  10. if not self.current_user:
  11. re = {"code" : 404, "message" : "login failed!"}
  12. self.write(re)
  13. else:
  14. func(self)
  15. return _auth;
  16. class BaseHandler(tornado.web.RequestHandler):
  17. def get_current_user(self):
  18. return self.get_secure_cookie("user")
  19. class LoginHandler(BaseHandler):
  20. def get(self):
  21. self.write('<html><body><form action="/login" method="post">'
  22. 'Name: <input type="text" name="name">'
  23. '<input type="submit" value="Sign in">'
  24. '</form></body></html>')
  25. def post(self):
  26. name = self.get_argument("name", "error")
  27. if name == "error":
  28. re = {"code" : 404, "message" : "login failed!"}
  29. else:
  30. self.set_secure_cookie("user", name)
  31. re = {"code" : 200, "message" : "login successfully!"}
  32. self.write(re)
  33. class CameraHandler(BaseHandler):
  34. @auth
  35. def get(self):
  36. ret, image = self.application.cap.read()
  37. if ret:
  38. self.set_header("Content-Type", "image/jpeg")
  39. self.set_header("Refresh", "1")
  40. self.set_header("content-transfer-encoding", "binary")
  41. r, i = cv2.imencode('.jpg', image)
  42. if r:
  43. self.write(bytes(i.data))
  44. else:
  45. selt.write('Sorry, encode faily!')
  46. else:
  47. self.write('Sorry, get camera data faily!')
  48. class Application(tornado.web.Application):
  49. def __init__(self, camera_id):
  50. handlers = [('/camera', CameraHandler), ('/login', LoginHandler)]
  51. self.cap = cv2.VideoCapture(camera_id)
  52. self.camera_id = camera_id;
  53. tornado.web.Application.__init__(self, handlers, debug = True ,cookie_secret = "61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o")
  54. def __del__(self):
  55. self.cap.release()
  56. if __name__ == '__main__':
  57. tornado.options.parse_command_line();
  58. app = Application(options.id)
  59. app.listen(options.port)
  60. tornado.ioloop.IOLoop.instance().start()

这其中还包括了一个login的例子,我学习tornado是为了使用其做app后台,所以我实现了自己的auth的修饰器,这样只是返回一串json字符,而不是重定向到login页面。
在Application构造时设置设备,在http://localhost:xxx/camera这个url上使用get方法就会返回一副图片。

  1. def get(self):
  2. ret, image = self.application.cap.read()
  3. if ret:
  4. self.set_header("Content-Type", "image/jpeg")
  5. self.set_header("Refresh", "1")
  6. self.set_header("content-transfer-encoding", "binary")
  7. r, i = cv2.imencode('.jpg', image)
  8. if r:
  9. self.write(bytes(i.data))
  10. else:
  11. selt.write('Sorry, encode faily!')
  12. else:
  13. self.write('Sorry, get camera data faily!')

这段代码就是这个功能,开始的时候我只是将数据拿出来就发送,没有进行imencode,导致浏览器不能正确的显示,使用Refresh实现自动的刷新。
项目地址:https://git.oschina.net/zhouX/web_camera.git

无图无真相:
此处输入图片的描述

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注