文中需要安装pygame和PIL
调用摄像头的方式
在windows中,python 可以使用VideoCapture库来调用摄像头,使用非常简单,主页是这个页面
安装whl文件可以在这个页面中找到。
pip install <your whl file>
在Mac中你可以使用openCV来使用摄像头, 我们是使用其中的VideoCapture类来调用摄像头的。它的使用我会在后面的代码中加上。
初次使用
VideoCapture 版本:
1 2 3 4
| from VideoCapture import Device cam = Device() cam.setResolution(320, 240) cam.saveSnapshot('demo.jpg')
|
- 会有提示can’t set resolution。因为你的摄像头可能不支持该分辨率。直接注释掉其中的第三句即可。
- 会可能提示你VideoCapture中的一个tostring函数已经被取代了,你需要把其中一个文件的这个函数换成tobytes
openCV版本:
1 2 3 4 5
| import cv2 cam = cv2.VideoCapture(0) ret, im = cam.read() im.imwrite('demo.jpg', im) cap.release()
|
正确运行这个程序之后,会出现一个demo.jpg。那就是你的摄像头的一个截图。我电脑上花费的时间是一秒左右。然而摄像头获取的时间其实并没有多少,但是将它作为一个文件存到电脑中才是占的时间比较多的步骤。
使用pygame作播放器
之后使用pygame作为一个播放器,持续播放我们从摄像头获取的图片,就相当于连续的影像了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| from VideoCapture import Device import sys import pygame
pygame.init() size = width, height = 640, 480 pygame.display.set_caption('视频窗口') screen = pygame.display.set_mode(size) pygame.display.flip()
cam = Device()
while True: im = cam.getImage().tobytes() camshot = pygame.image.frombuffer(im, size, "RGB") for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() screen.blit(camshot, (0, 0)) pygame.display.update()
|
用socket传输摄像头的影像
没有设置socket的缓冲区大小,只能传递160, 120大小的图片。
服务器端:获取摄像头的图片并传给客户端
1 2 3 4 5 6 7 8 9 10 11 12
| import socket from VideoCapture import Device cam = Device()
clisocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) PORT = 2333
while True: im = cam.getImage() im = im.resize((160, 120)) data = im.tobytes() clisocket.sendto(data, ('127.0.0.1', PORT))
|
客户端:接受服务器的图片并用pygame将其显示出来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import socket import sys import pygame
pygame.init() screen = pygame.display.set_mode((160, 120)) pygame.display.set_caption("视频窗口") pygame.display.flip()
svrsocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) PORT = 2333 svrsocket.bind(("127.0.0.1", PORT))
while True: data, address = svrsocket.recvfrom(80000) camshot = pygame.image.frombuffer(data, (160, 120), "RGB") for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() screen.blit(camshot, (0, 0)) pygame.display.update()
|
==================================================
附加: js调用摄像头
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>video test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head>
<body> <video id="video" width="640" height="480" autoplay></video> </body> <script type="text/javascript"> var constraints = { video: { width: 1280, height: 720 } };
navigator.mediaDevices.getUserMedia(constraints) .then(function(stream) { var video = document.querySelector('video'); video.src = window.URL.createObjectURL(stream); video.onloadedmetadata = function(e) { video.play(); }; }).catch(function(err) { console.log(err.name + ": " + err.message); }); </script> </html>
|
在Firefox上是可以正常使用的。但是为了更好的兼容性,我们可能需要更多的限制:
比如,需要注意的是:
navigator.getUserMedia已经被弃用,API改名为MediaDevices.getUserMedia ^1
兼容性更好的版本参见:这里
里面还漏了一个window.URL的兼容性:
window.URL = (window.URL || window.webkitURL || window.mozURL || window.msURL);