如何使用OpenCV为桌面和Web构建简单的Webcam应用程序(二)

Dynamic Web TWAIN是一个专为Web应用程序设计的TWAIN扫描识别控件。你只需在TWAIN接口写几行代码,就可以用兼容TWAIN的扫描仪扫描文档或从数码相机/采集卡中获取图像。然后用户可以编辑图像并将图像保存为多种格式,用户可保存图像到远程数据库或者SharePoint。这个TWAIN控件还支持上传和处理本地图像。

从任何Web浏览器访问远程网络摄像头

要实现远程网络摄像头访问,我只需要创建一个带有图像元素的简单HTML页面并启动一个简单的HTTP服务器,即可通过HTTP GET请求连续发送网络摄像头帧。为了使代码尽可能简单,我只使用了四种编程语言的内置HTTP API和OpenCV视频捕获API。

Node.js

创建一个简单的HTML页面:

使用setTimeout()从Web服务器连续获取新图像并刷新图像元素。

Webcam
<img id="image"/>

<script type="text/javascript">
    var image = document.getElementById('image');
    function refresh() {
        image.src = "/image?" + new Date().getTime();
        image.onload= function(){
            setTimeout(refresh, 30);
        }
    }
     
    refresh();
</script>

在服务器端,使用HTTP模块创建一个简单的Web服务器:

const http = require(‘http’);
var server = http.createServer(function (req, res) {
if (req.url === ‘/’ || req.url === ‘/index.htm’) {

    res.writeHead(200, { 'Content-Type': 'text/html' });   
    res.write(html);
    res.end();
 
}
else if (req.url.startsWith("/image")) {
     
    res.writeHead(200, { 'Content-Type': 'image/jpeg' });
    res.write(img);
    res.end();
 
}
else
    res.end('Invalid Request!');

});
server.listen(2020);
分析请求URL,然后发送相应的响应。同时,创建一个计时器以捕获网络摄像头帧并将其编码为JPEG格式:
var img = null;
function capture() {
var frame = wCap.read()
if (frame.empty) {
wCap.reset();
frame = wCap.read();
}

img = cv.imencode('.jpg', frame);
setTimeout(capture, 30);

}

capture();
要通过双击打开HTML文件,请将相对图像路径更改为绝对图像路径:
image.src = “http://localhost:2020/image?” + new Date().getTime();
C#
受本杰明·萨默顿(Benjamin Summerton)的要旨启发,我创建了HTTP服务器,如下所示:
using System;
using System.IO;
using System.Text;
using System.Net;
using System.Threading.Tasks;
using OpenCvSharp;

namespace Web
{
class Program
{
public static HttpListener listener;
public static string url = “http://localhost:2020/”;
public static string pageData =
“” +
“” +
“” +
"

" +
“” +
“” +
“”+
"
"+
“” +
“”;

    public static VideoCapture capture = new VideoCapture(0);


    public static async Task HandleIncomingConnections()
    {
        while (true)
        {
            HttpListenerContext ctx = await listener.GetContextAsync();

            HttpListenerRequest req = ctx.Request;
            HttpListenerResponse resp = ctx.Response;

            if ((req.HttpMethod == "GET") && (req.Url.AbsolutePath.StartsWith("/image"))) {

                resp.ContentType = "image/jpeg";
                using (Mat image = new Mat()) 
                {
                    capture.Read(image); 
                    Cv2.ImEncode(".jpg", image, out var imageData);
                    await resp.OutputStream.WriteAsync(imageData, 0, imageData.Length);
                    resp.Close();
                }
            }
            else {

                // Write the response info
                byte[] data = Encoding.UTF8.GetBytes(pageData);
                resp.ContentType = "text/html";
                resp.ContentEncoding = Encoding.UTF8;
                resp.ContentLength64 = data.LongLength;

                // Write out to the response stream (asynchronously), then close it
                await resp.OutputStream.WriteAsync(data, 0, data.Length);
                resp.Close();
            }
        }
    }

    static void Main(string[] args)
    {
        // Create a Http server and start listening for incoming connections
        listener = new HttpListener();
        listener.Prefixes.Add(url);
        listener.Start();
        Console.WriteLine("Listening for connections on {0}", url);

        // Handle requests
        Task listenTask = HandleIncomingConnections();
        listenTask.GetAwaiter().GetResult();

        // Close the listener
        listener.Close();
    }
}

}
蟒蛇
使用Python的内置HTTP服务器类非常方便。我们需要做的是定义一个用于处理HTTP请求的自定义处理程序:

import http.server
import socketserver

class MyHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):

    if self.path == '/':
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
        self.wfile.write(bytes(pageData, "utf8"))
    elif self.path.startswith('/image'):
        self.send_response(200)
        self.send_header("Content-type", "image/jpeg")
        self.end_headers()

        ret, frame = cap.read()
        _, jpg = cv2.imencode(".jpg", frame)

        self.wfile.write(jpg)
    else:
        self.send_response(404)

with socketserver.TCPServer(("", PORT), MyHandler) as httpd:
print("Serving at port ", PORT)
try:
httpd.serve_forever()
except:
pass
高朗

像Python一样,很容易在30秒内设置HTTP Web服务器:
func handler(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == “/” {
pageData := “” +
“” +
“” +
"

" +
“” +
“” +
“” +
"
" +
“” +
“”

    w.Header().Set("Content-Type", "text/html")
    w.Write([]byte(pageData))
} else if strings.HasPrefix(r.URL.Path, "/image") {
    webcam.Read(&img)
    jpg, _ := gocv.IMEncode(".jpg", img)
    w.Write(jpg)
} else {
    fmt.Fprintf(w, "Page Not Found")
}

}

func main() {
fmt.Println(“Running at port 2020…”)
webcam, _ = gocv.OpenVideoCapture(0)
img = gocv.NewMat()
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(":2020", nil))
webcam.Close()
}
完成所有操作后,我可以运行Web服务器并访问localhost:2020以从任何桌面Web浏览器查看网络摄像头视频流。

如何使用OpenCV为桌面和Web构建简单的Webcam应用程序(二)

也可以从我的移动网络浏览器访问该页面。

如何使用OpenCV为桌面和Web构建简单的Webcam应用程序(二)

最后,使用ngrok将本地开发服务器公开到Internet。
在这里插入图片描述

现在,无论身在何处,我都可以通过远程网络摄像头观看实时视频。

想要购买Dynamic Web TWAIN正版授权,或了解更多产品信息请点击【慧都

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值