如何通过Javascript在PythonAnywhere上访问OpenCV中的网络摄像头?

18 浏览
0 Comments

如何通过Javascript在PythonAnywhere上访问OpenCV中的网络摄像头?

我在Django中开发了一个Web应用程序,其中包含一个视图方法,其中包含打开用户摄像头并检测其面部的OpenCV代码。这个应用在我的本地服务器上运行良好,但是当我将它托管到PythonAnywhere上时,它会显示找不到摄像头,因为我的PA托管没有提供摄像头功能。所以有人建议我通过JavaScript打开摄像头,因为它与客户端机器进行交互,然后将其视频流传递给我的服务器主机。但是作为Python的新手,我不知道如何执行上述任务。我找到了这段JavaScript代码,但是我不知道在我的Django应用中如何添加和使用它。

JavaScript代码获取视频流:

var video = document.querySelector("#videoElement");
if (navigator.mediaDevices.getUserMedia) {
    navigator.mediaDevices.getUserMedia({video: true}).then(function(stream) {
      video.srcObject = stream;
  }).catch(function(err0r) {
      console.log("Something went wrong!");
  });
}

我的Python代码用于打开摄像头并检测人脸(在本地服务器上运行正常):

import cv2
cascade = cv2.CascadeClassifier('./haarcascade_frontalface_default.xml')
cam = cv2.VideoCapture(0)
while True:
    ret, frame = cam.read()
    frame = cv2.flip(frame, 1)
    if ret:
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        faces = cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=3)
        for (x, y, w, h) in faces:
            cropped = cv2.resize(frame[y:y+h, x:x+w], (198,198))
            cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
            cv2.destroyAllWindows()
        cv2.imshow('Stream', frame)

非常感谢您的帮助。提前致谢。

0
0 Comments

问题出现的原因是用户想要通过PythonAnywhere上的OpenCV访问网络摄像头,但不知道如何实现。解决方法是使用JavaScript获取用户的摄像头图像并通过websocket发送给Django服务器,然后通过OpenCV对图像进行处理。

以前我做过类似的事情,我使用的方案如下:

![数据流](https://i.stack.imgur.com/6QbLP.png)

正如你已经知道的,我们需要使用JavaScript从摄像头获取用户的图像。我找到了一篇文章,展示了如何实现这一点,如果你想使用Django,你只需要使用前端部分(HTML文件)。它的代码用于获取图像并将其编码为base64字符串,然后通过websocket发送。

之后,我们希望Django来提供websocket服务。过去,我使用的是Flask,而不是Django,但你可以看到如何使用django-channel创建websocket服务器。

最后一步,你需要一个包含OpenCV代码的函数。你需要解码base64并将其转换为OpenCV图像。

def modify_picture(img_data):
    # 解码图像
    img = from_b64(img_data)
    # OpenCV处理
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 将图像编码为base64
    return to_b64(gray)

当然,你不需要`while True`和`cv2.imshow`,只需返回新图片的base64版本即可。希望能对你有所帮助。

更新:我在我的github上写了一个示例代码。虽然不是Django,但仍然是Python。希望它能给你更多的灵感。

嗨,试验这个解决方案可能需要一些时间,但是由于时间有限,我接受你的努力并感谢你的帮助。

嗨,我在实现这个解决方案时遇到了一些困难。如果有人成功了,我很乐意听听经验!

嗨,我只是在概念上提供了一个示例实现。你可以查看更新后的答案。

我尝试使用你的git代码,但是当服务器触发后,出现一个空数组,上面写着`{ details: not found }`。

你能够实现这个解决方案吗?

0
0 Comments

问题出现的原因是作者想要通过JavaScript获取webcam的实时视频流,并将该流传递给OpenCV2进行处理。然而作者尝试使用的解决方法中,提供的代码只能从文件中获取视频流,无法获取实时webcam视频流。

为了解决这个问题,可以使用以下方法:

1. 首先,需要通过JavaScript获取实时webcam视频流。可以使用这个项目来实现这一点。该项目提供了一个可以在Node.js中获取实时webcam视频流的示例代码。通过按照该项目的说明来设置和启动服务器,可以获取到一个URL,如"http://localhost:3000"

2. 在PythonAnywhere中,可以使用以下代码来访问webcam视频流并进行处理:

import cv2
# 设置人脸识别器
cascade = cv2.CascadeClassifier('./haarcascade_frontalface_default.xml')
# 通过url访问webcam视频流
cam = cv2.VideoCapture('http://localhost:3000')
while True:
    # 读取视频帧
    ret, frame = cam.read()
    frame = cv2.flip(frame, 1)
    if ret:
        # 将视频帧转为灰度图像
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        
        # 在灰度图像中检测人脸
        faces = cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=3)
        
        for (x, y, w, h) in faces:
            # 对检测到的人脸进行裁剪和缩放
            cropped = cv2.resize(frame[y:y+h, x:x+w], (198,198))
            cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
        # 显示视频流
        cv2.imshow('Stream', frame)
        
        # 按下"q"键退出循环
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
# 释放资源并销毁窗口
cv2.destroyAllWindows()

通过以上方法,我们可以在PythonAnywhere中通过JavaScript访问webcam并使用OpenCV2对视频流进行处理。

0