使用 Python 和 OpenCV 远程访问手机摄像头
手机端准备
这里以安卓手机作为演示,iOS 系统操作逻辑类似。你需要先在手机上安装一款支持将摄像头画面推流到局域网的 App。
注意: 要想在电脑上查看手机摄像头拍摄的内容,电脑和手机必须处于同一个局域网内(没有 WiFi 可以使用热点)。
启动手机摄像头服务
安装完成后打开 App,进入 IP 摄像头服务器界面。点击分享或查看 IP 按钮,获取当前局域网下的 IP 地址和端口号。通常格式为 http://IP:端口。
PC 端环境搭建
我们需要使用 Python 的 OpenCV 库来连接这个网络视频流。
首先安装依赖库:
pip install opencv-python
如果下载速度较慢,建议使用国内镜像源加速,例如清华源:
pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple/
代码实现与说明
下面是一个完整的脚本示例。它负责连接手机 IP、读取视频流、处理按键事件以及保存截图。
import cv2
import os
from datetime import datetime
# 创建窗口,设置为允许调整大小
cv2.namedWindow('camera', cv2.WINDOW_NORMAL)
# 摄像头设置,这里使用的是网络摄像头的 URL
# 请将 IP 地址替换为你在手机端看到的实际地址
video = 'http://admin:[email protected]:8081'
capture = cv2.VideoCapture(video)
# 开始无限循环,直到用户中断
while True:
success, img = capture.read()
# 从摄像头读取一帧图像
if not success:
print("无法抓取帧")
break
# 将图像旋转 90 度以竖直显示
# 实际场景中,手机横屏时画面可能也是横着的,需要旋转修正
img = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
# 显示图像
cv2.imshow("camera", img)
# 等待用户按键,10 毫秒响应一次
key = cv2.waitKey(10)
# 按键处理逻辑
if key == 27: # ESC 键退出
break
elif key == ord(' '): # 空格键保存图片
# 保存图片到当前目录下的 img 文件夹中
img_folder = 'img'
if not os.path.exists(img_folder):
os.makedirs(img_folder)
# 使用时间戳作为文件名
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
img_filename = f"{img_folder}/{timestamp}.jpg"
cv2.imwrite(img_filename, img)
print(f"Saved image {timestamp}.jpg")
# 释放摄像头资源
capture.release()
# 关闭所有 OpenCV 创建的窗口
cv2.destroyAllWindows()
关键点解析
- 导入必要的库:
cv2用于图像处理,os用于路径管理,datetime用于生成文件名。 - 创建窗口:
WINDOW_NORMAL允许你手动调整显示窗口的大小,方便观察细节。 - 摄像头设置:
VideoCapture接收的是 HTTP 流地址。务必确保 IP 和端口正确,且防火墙未拦截相关端口。 - 主循环与帧读取:
capture.read()会返回一个布尔值表示是否成功读取。如果失败(比如手机断网),直接跳出循环避免卡死。 - 图像旋转:很多手机摄像头默认输出是横向的,而我们在 PC 上竖屏看比较习惯,所以加了 90 度旋转。如果方向不对,可以改成
ROTATE_90_COUNTERCLOCKWISE。 - 按键处理:
waitKey(10)是关键,它让程序每 10 毫秒检查一次键盘输入。ESC 键(ASCII 27)退出,空格键触发保存逻辑。 - 资源释放:程序结束前一定要调用
release()和destroyAllWindows(),否则可能导致摄像头被占用无法再次打开。
运行效果
在电脑端运行脚本后,会弹出一个名为 camera 的窗口,实时显示手机摄像头画面。按空格键会在同级目录的 img 文件夹下保存带时间戳的图片。如果分辨率较低导致画面模糊,这通常是手机 App 推流压缩导致的,属于正常现象。


