首页 > 代码库 > 基于tornado实现web camera

基于tornado实现web camera

基于tornado实现web camera


近期在学习python。找了一个框架学习,我选择的是tornado。由于其不仅仅是一个web开发框架,其还是一个server,异步事件库,一举多得。
我一直在完opencv,我想接合他们两个做一个web camera,这就開始。


在tornado中要实现对一个URL的响应,须要实现你自己的Handle。依据你对外提供的接口。实现相关的接口就好了。


以下为整个project的文件内容:

import tornado.ioloop
import tornado.web
import tornado.gen
import cv2

from tornado.options import define,  options

define("port", default = 5000, help = "run in tornado on xxxx port", type = int)
define("id", default = 0, help = "camera id", type = int)


def auth(func):
    def _auth(self):
        if not self.current_user:
            re = {"code" : 404, "message" : "login failed!"}
            self.write(re)
        else:
            func(self)
    return _auth;


class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self):
        return self.get_secure_cookie("user")



class LoginHandler(BaseHandler):
    def get(self):
        self.write(‘<html><body><form action="/login" method="post">‘
                   ‘Name: <input type="text" name="name">‘
                   ‘<input type="submit" value="http://www.mamicode.com/Sign in">‘
                   ‘</form></body></html>‘)

    def post(self):
        name = self.get_argument("name", "error")
        if name == "error":
            re = {"code" : 404, "message" : "login failed!"}
        else:
            self.set_secure_cookie("user", name)
            re = {"code" : 200, "message" : "login successfully!"}
        self.write(re)



class CameraHandler(BaseHandler):
    @auth
    def get(self):
        ret, image = self.application.cap.read()
    if ret:
            self.set_header("Content-Type", "image/jpeg")
            self.set_header("Refresh", "1") 
        self.set_header("content-transfer-encoding", "binary")
            r, i = cv2.imencode(‘.jpg‘, image)
        if r:
                self.write(bytes(i.data))
            else:
                selt.write(‘Sorry, encode faily!‘)
        else:
        self.write(‘Sorry, get camera data faily!‘)



class Application(tornado.web.Application):
    def __init__(self, camera_id):
        handlers = [(‘/camera‘, CameraHandler), (‘/login‘, LoginHandler)]
        self.cap = cv2.VideoCapture(camera_id)
        self.camera_id = camera_id;
        tornado.web.Application.__init__(self, handlers, debug = True ,cookie_secret = "61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o")

    def __del__(self):
        self.cap.release()


if __name__ == ‘__main__‘:
    tornado.options.parse_command_line();
    app = Application(options.id)
    app.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

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

    def get(self):
        ret, image = self.application.cap.read()
    if ret:
            self.set_header("Content-Type", "image/jpeg")
            self.set_header("Refresh", "1") 
        self.set_header("content-transfer-encoding", "binary")
            r, i = cv2.imencode(‘.jpg‘, image)
        if r:
                self.write(bytes(i.data))
            else:
                selt.write(‘Sorry, encode faily!‘)
        else:
        self.write(‘Sorry, get camera data faily!‘)

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

无图无真相:
技术分享

<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

基于tornado实现web camera