# aitoolkit_cam
简单易用的摄像头库,专为ARM设备和Jupyter环境设计。
## 🚀 特性
- **零配置使用** - 自动检测后端服务,智能选择运行模式
- **用户代码不变** - Jupyter中的代码保持完全不变
- **一行FastAPI集成** - 轻松集成到现有FastAPI应用
- **多种架构支持** - 简单模式、后端集成、Producer/Hub分布式
- **完整向后兼容** - 支持所有原有使用方式
- **高级图像处理** - 内置多种图像滤镜和文本叠加功能
- **设备管理** - 智能检测和选择最佳摄像头设备
- **配置管理** - 灵活的配置系统,支持自定义设置
## 📦 安装
```bash
# 基本安装
pip install aitoolkit-cam
# 安装带FastAPI支持的版本
pip install aitoolkit-cam[fastapi]
# 安装开发版本(包含测试工具)
pip install aitoolkit-cam[dev]
# 安装所有功能
pip install aitoolkit-cam[all]
```
## 🎯 快速开始
### 基本使用(Jupyter/独立)
```python
from aitoolkit_cam import Camera
import cv2
# 用户代码保持不变,自动适配运行环境
with Camera(source=0, max_frames=100) as cam:
url = cam.start() # 自动检测后端或启动内置服务
print(f"视频流: {url}")
for frame in cam:
# OpenCV处理
edges = cv2.Canny(frame, 80, 160)
display_frame = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)
# 显示处理后的帧
cam.show(display_frame)
```
### FastAPI集成(一行集成)
```python
from fastapi import FastAPI
from aitoolkit_cam import add_camera_routes
app = FastAPI()
# 只需一行代码即可集成摄像头功能!
add_camera_routes(app, prefix="/camera")
# 现在你的FastAPI应用有了完整的摄像头功能:
# - GET /camera/ - 控制页面
# - GET /camera/stream - MJPEG视频流
# - GET /camera/start - 启动摄像头
# - GET /camera/stop - 停止摄像头
# - GET /camera/status - 获取状态
# - POST /camera/upload - 接收处理后的帧
```
### 使用内置滤镜
```python
from aitoolkit_cam import Camera, ImageFilters, TextOverlay
with Camera(source=0) as cam:
cam.start()
for frame in cam:
# 应用边缘检测滤镜
edges = ImageFilters.edge_detection(frame, 80, 160)
# 添加时间戳
result = TextOverlay.add_timestamp(edges)
# 显示处理后的帧
cam.show(result)
```
### 使用滤镜链
```python
from aitoolkit_cam import Camera, FilterChain, ImageFilters
# 创建滤镜链
filter_chain = FilterChain()
filter_chain.add_filter(ImageFilters.blur_effect, kernel_size=5)
filter_chain.add_filter(ImageFilters.edge_detection, low_threshold=50, high_threshold=150)
filter_chain.add_filter(ImageFilters.brightness_contrast, brightness=10, contrast=1.2)
with Camera(source=0) as cam:
cam.start()
for frame in cam:
# 应用滤镜链
result = filter_chain.apply(frame)
# 显示处理后的帧
cam.show(result)
```
### 设备管理
```python
from aitoolkit_cam import list_available_cameras, get_optimal_camera, Camera
# 列出所有可用摄像头
devices = list_available_cameras()
for device in devices:
print(f"设备 {device.device_id}: {device.width}x{device.height} @ {device.fps}fps")
# 获取最佳摄像头设备
optimal_device = get_optimal_camera()
# 使用最佳设备
with Camera(source=optimal_device) as cam:
cam.start()
# ...处理逻辑...
```
### 配置管理
```python
from aitoolkit_cam import get_config, set_config, save_config, load_config
# 获取配置
width = get_config("camera.default_width") # 默认640
fps = get_config("camera.default_fps") # 默认20
# 修改配置
set_config("camera.default_width", 1280)
set_config("camera.default_height", 720)
# 保存配置到文件
save_config("my_config.json")
# 加载配置
load_config("my_config.json")
```
## 🏗️ 架构模式
### 1. 智能自适应模式(推荐)
Camera类自动检测运行环境:
- **有后端服务** → 自动连接到FastAPI后端
- **无后端服务** → 启动内置Flask服务器
```python
# 用户代码完全相同,系统自动适配
with Camera() as cam:
url = cam.start() # 智能选择模式
# ... 处理逻辑 ...
```
### 2. FastAPI集成模式
将摄像头功能集成到现有FastAPI应用:
```python
# 后端服务(管理员启动)
from fastapi import FastAPI
from aitoolkit_cam import add_camera_routes
app = FastAPI()
add_camera_routes(app)
if __name__ == "__main__":
import uvicorn
# 支持多个端口:18001, 5000, 6000, 7000, 8000, 9000
uvicorn.run(app, host="0.0.0.0", port=8000)
```
```python
# 用户代码(Jupyter中)
with Camera() as cam: # 自动检测多个端口的后端服务
url = cam.start() # 连接到第一个可用的后端服务
# ... 处理逻辑 ...
```
**🔍 多端口自动检测**
aitoolkit_cam 支持自动检测多个端口的后端服务:
- **默认检测端口**:18001, 5000, 6000, 7000, 8000, 9000
- **检测顺序**:按配置文件中的顺序依次检测
- **自动连接**:连接到第一个响应的服务
- **灵活配置**:可通过配置文件自定义端口列表
```python
# 启动不同端口的后端服务
python examples/multi_port_backend_demo.py --port 6000
python examples/multi_port_backend_demo.py --port 7000
# 用户代码自动检测并连接
with Camera() as cam:
url = cam.start() # 自动连接到可用服务
```
### 3. Producer/Hub分布式模式
支持传统的分布式架构:
```python
# Hub服务器
from aitoolkit_cam import Hub
hub = Hub(port=5000)
hub.run()
```
```python
# Producer客户端
from aitoolkit_cam import Camera
with Camera(hub_url="http://hub-server:5000") as cam:
# ... 分布式处理 ...
```
## 📝 API参考
### Camera类
```python
Camera(
source=0, # 摄像头设备ID
width=640, # 视频宽度
height=480, # 视频高度
fps=20, # 帧率
max_frames=None, # 最大帧数(None=无限)
port=9000 # 简单模式使用的端口
)
```
**方法:**
- `start()` - 启动摄像头,返回视频流URL
- `stop()` - 停止摄像头
- `read(timeout=1.0)` - 读取原始帧
- `show(frame)` - 显示处理后的帧
- `frame_count` - 当前帧计数
**支持的语法:**
- `with Camera() as cam:` - 上下文管理器
- `for frame in cam:` - 迭代器模式
### 图像处理
```python
# 滤镜
ImageFilters.edge_detection(frame, low_threshold=50, high_threshold=150)
ImageFilters.blur_effect(frame, kernel_size=15)
ImageFilters.cartoon_effect(frame)
ImageFilters.sepia_effect(frame)
ImageFilters.negative_effect(frame)
ImageFilters.brightness_contrast(frame, brightness=0, contrast=1.0)
ImageFilters.color_filter(frame, color_mask=(255, 255, 255))
ImageFilters.emboss_effect(frame)
ImageFilters.motion_blur(frame, size=15, angle=0)
# 文本叠加
TextOverlay.add_text(frame, text, position=(10, 30), font_scale=1.0)
TextOverlay.add_timestamp(frame)
TextOverlay.add_frame_info(frame, frame_count, fps=30.0)
# 滤镜链
chain = FilterChain()
chain.add_filter(ImageFilters.blur_effect, kernel_size=5)
chain.add_filter(ImageFilters.edge_detection)
result = chain.apply(frame)
# 预定义滤镜
vintage_filter = create_vintage_filter()
artistic_filter = create_artistic_filter()
dramatic_filter = create_dramatic_filter()
```
### 设备管理
```python
# 列出可用摄像头
devices = list_available_cameras()
# 获取最佳摄像头
device_id = get_optimal_camera()
# 验证摄像头设备
is_valid = validate_camera(device_id)
# 获取设备信息
info = get_camera_info(device_id)
# 获取设备能力
capabilities = get_camera_capabilities(device_id)
```
### 配置管理
```python
# 获取配置
value = get_config("section.key", default_value)
# 设置配置
set_config("section.key", new_value)
# 加载配置文件
load_config("config.json")
# 保存配置到文件
save_config("config.json")
# 重置为默认配置
reset_config()
```
### FastAPI集成函数
```python
add_camera_routes(app, prefix="/camera")
setup_background_processing(app, frame_processor=None, fps=20)
```
## 🔧 使用场景
### 场景1:Jupyter实验环境
```python
# 研究人员在Jupyter中使用
with Camera(max_frames=100) as cam:
cam.start()
for frame in cam:
# 实时图像处理实验
result = my_algorithm(frame)
cam.show(result)
```
### 场景2:Web应用集成
```python
# 集成到现有Web应用
app = FastAPI()
add_camera_routes(app)
# 用户通过Web界面控制摄像头
# 访问 /camera/ 查看控制页面
# 访问 /camera/stream 查看视频流
```
### 场景3:分布式处理
```python
# 多个摄像头节点连接到中央Hub
# 适合监控、多点采集等场景
```
## 🚦 测试
项目包含完整的测试套件:
```bash
# 单元测试
python -m unittest tests/test_unit.py
# 功能调试测试
python tests/test_debug.py
# 用户模式测试
python tests/test_simple_mode.py
# 后端服务测试
python tests/test_backend_service.py
```
## 🐳 Docker支持
项目提供了Docker支持,可以轻松部署:
```bash
# 构建Docker镜像
docker build -t aitoolkit-cam .
# 运行Docker容器
docker run -p 8000:8000 aitoolkit-cam
# 使用docker-compose
docker-compose up
```
## 📋 开发指南
### 测试步骤
1. **单元测试**:
```bash
python -m unittest tests/test_unit.py
```
2. **独立测试**:
```bash
python tests/test_simple_mode.py
```
3. **集成测试**:
```bash
# 终端1:启动后端
python tests/test_backend_service.py
# 终端2:运行用户代码
python tests/test_simple_mode.py
```
### 故障排除
如果遇到问题:
1. 运行调试测试:`python tests/test_debug.py`
2. 检查摄像头设备是否可用
3. 确认网络端口未被占用
4. 查看日志输出
## 📖 更多示例
查看 `examples/` 目录中的完整示例:
- `basic_usage.py` - 基本使用示例
- `advanced_features.py` - 高级功能示例
- `fastapi_integration.py` - FastAPI集成示例
- `config_management.py` - 配置管理示例
## 🤝 贡献
欢迎提交Issue和Pull Request!
## 📄 许可证
MIT License
Raw data
{
"_id": null,
"home_page": "https://github.com/bosscoder-ai/aitoolkit_cam",
"name": "aitoolkit-cam",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": "camera, opencv, video, streaming, web, cv2, jupyter, notebook, education, arm64, raspberry-pi, real-time, smart-stop",
"author": "aitoolkit",
"author_email": "aitoolkit <your.email@example.com>",
"download_url": "https://files.pythonhosted.org/packages/84/bb/1fc8aa3ed8e66ccc60d92258dabe84c15b7decad950cd687c1e218dd4db5/aitoolkit_cam-1.1.0.tar.gz",
"platform": null,
"description": "# aitoolkit_cam\r\n\r\n\u7b80\u5355\u6613\u7528\u7684\u6444\u50cf\u5934\u5e93\uff0c\u4e13\u4e3aARM\u8bbe\u5907\u548cJupyter\u73af\u5883\u8bbe\u8ba1\u3002\r\n\r\n## \ud83d\ude80 \u7279\u6027\r\n\r\n- **\u96f6\u914d\u7f6e\u4f7f\u7528** - \u81ea\u52a8\u68c0\u6d4b\u540e\u7aef\u670d\u52a1\uff0c\u667a\u80fd\u9009\u62e9\u8fd0\u884c\u6a21\u5f0f\r\n- **\u7528\u6237\u4ee3\u7801\u4e0d\u53d8** - Jupyter\u4e2d\u7684\u4ee3\u7801\u4fdd\u6301\u5b8c\u5168\u4e0d\u53d8\r\n- **\u4e00\u884cFastAPI\u96c6\u6210** - \u8f7b\u677e\u96c6\u6210\u5230\u73b0\u6709FastAPI\u5e94\u7528\r\n- **\u591a\u79cd\u67b6\u6784\u652f\u6301** - \u7b80\u5355\u6a21\u5f0f\u3001\u540e\u7aef\u96c6\u6210\u3001Producer/Hub\u5206\u5e03\u5f0f\r\n- **\u5b8c\u6574\u5411\u540e\u517c\u5bb9** - \u652f\u6301\u6240\u6709\u539f\u6709\u4f7f\u7528\u65b9\u5f0f\r\n- **\u9ad8\u7ea7\u56fe\u50cf\u5904\u7406** - \u5185\u7f6e\u591a\u79cd\u56fe\u50cf\u6ee4\u955c\u548c\u6587\u672c\u53e0\u52a0\u529f\u80fd\r\n- **\u8bbe\u5907\u7ba1\u7406** - \u667a\u80fd\u68c0\u6d4b\u548c\u9009\u62e9\u6700\u4f73\u6444\u50cf\u5934\u8bbe\u5907\r\n- **\u914d\u7f6e\u7ba1\u7406** - \u7075\u6d3b\u7684\u914d\u7f6e\u7cfb\u7edf\uff0c\u652f\u6301\u81ea\u5b9a\u4e49\u8bbe\u7f6e\r\n\r\n## \ud83d\udce6 \u5b89\u88c5\r\n\r\n```bash\r\n# \u57fa\u672c\u5b89\u88c5\r\npip install aitoolkit-cam\r\n\r\n# \u5b89\u88c5\u5e26FastAPI\u652f\u6301\u7684\u7248\u672c\r\npip install aitoolkit-cam[fastapi]\r\n\r\n# \u5b89\u88c5\u5f00\u53d1\u7248\u672c\uff08\u5305\u542b\u6d4b\u8bd5\u5de5\u5177\uff09\r\npip install aitoolkit-cam[dev]\r\n\r\n# \u5b89\u88c5\u6240\u6709\u529f\u80fd\r\npip install aitoolkit-cam[all]\r\n```\r\n\r\n## \ud83c\udfaf \u5feb\u901f\u5f00\u59cb\r\n\r\n### \u57fa\u672c\u4f7f\u7528\uff08Jupyter/\u72ec\u7acb\uff09\r\n\r\n```python\r\nfrom aitoolkit_cam import Camera\r\nimport cv2\r\n\r\n# \u7528\u6237\u4ee3\u7801\u4fdd\u6301\u4e0d\u53d8\uff0c\u81ea\u52a8\u9002\u914d\u8fd0\u884c\u73af\u5883\r\nwith Camera(source=0, max_frames=100) as cam:\r\n url = cam.start() # \u81ea\u52a8\u68c0\u6d4b\u540e\u7aef\u6216\u542f\u52a8\u5185\u7f6e\u670d\u52a1\r\n print(f\"\u89c6\u9891\u6d41: {url}\")\r\n \r\n for frame in cam:\r\n # OpenCV\u5904\u7406\r\n edges = cv2.Canny(frame, 80, 160)\r\n display_frame = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)\r\n \r\n # \u663e\u793a\u5904\u7406\u540e\u7684\u5e27\r\n cam.show(display_frame)\r\n```\r\n\r\n### FastAPI\u96c6\u6210\uff08\u4e00\u884c\u96c6\u6210\uff09\r\n\r\n```python\r\nfrom fastapi import FastAPI\r\nfrom aitoolkit_cam import add_camera_routes\r\n\r\napp = FastAPI()\r\n\r\n# \u53ea\u9700\u4e00\u884c\u4ee3\u7801\u5373\u53ef\u96c6\u6210\u6444\u50cf\u5934\u529f\u80fd\uff01\r\nadd_camera_routes(app, prefix=\"/camera\")\r\n\r\n# \u73b0\u5728\u4f60\u7684FastAPI\u5e94\u7528\u6709\u4e86\u5b8c\u6574\u7684\u6444\u50cf\u5934\u529f\u80fd\uff1a\r\n# - GET /camera/ - \u63a7\u5236\u9875\u9762\r\n# - GET /camera/stream - MJPEG\u89c6\u9891\u6d41 \r\n# - GET /camera/start - \u542f\u52a8\u6444\u50cf\u5934\r\n# - GET /camera/stop - \u505c\u6b62\u6444\u50cf\u5934\r\n# - GET /camera/status - \u83b7\u53d6\u72b6\u6001\r\n# - POST /camera/upload - \u63a5\u6536\u5904\u7406\u540e\u7684\u5e27\r\n```\r\n\r\n### \u4f7f\u7528\u5185\u7f6e\u6ee4\u955c\r\n\r\n```python\r\nfrom aitoolkit_cam import Camera, ImageFilters, TextOverlay\r\n\r\nwith Camera(source=0) as cam:\r\n cam.start()\r\n \r\n for frame in cam:\r\n # \u5e94\u7528\u8fb9\u7f18\u68c0\u6d4b\u6ee4\u955c\r\n edges = ImageFilters.edge_detection(frame, 80, 160)\r\n \r\n # \u6dfb\u52a0\u65f6\u95f4\u6233\r\n result = TextOverlay.add_timestamp(edges)\r\n \r\n # \u663e\u793a\u5904\u7406\u540e\u7684\u5e27\r\n cam.show(result)\r\n```\r\n\r\n### \u4f7f\u7528\u6ee4\u955c\u94fe\r\n\r\n```python\r\nfrom aitoolkit_cam import Camera, FilterChain, ImageFilters\r\n\r\n# \u521b\u5efa\u6ee4\u955c\u94fe\r\nfilter_chain = FilterChain()\r\nfilter_chain.add_filter(ImageFilters.blur_effect, kernel_size=5)\r\nfilter_chain.add_filter(ImageFilters.edge_detection, low_threshold=50, high_threshold=150)\r\nfilter_chain.add_filter(ImageFilters.brightness_contrast, brightness=10, contrast=1.2)\r\n\r\nwith Camera(source=0) as cam:\r\n cam.start()\r\n \r\n for frame in cam:\r\n # \u5e94\u7528\u6ee4\u955c\u94fe\r\n result = filter_chain.apply(frame)\r\n \r\n # \u663e\u793a\u5904\u7406\u540e\u7684\u5e27\r\n cam.show(result)\r\n```\r\n\r\n### \u8bbe\u5907\u7ba1\u7406\r\n\r\n```python\r\nfrom aitoolkit_cam import list_available_cameras, get_optimal_camera, Camera\r\n\r\n# \u5217\u51fa\u6240\u6709\u53ef\u7528\u6444\u50cf\u5934\r\ndevices = list_available_cameras()\r\nfor device in devices:\r\n print(f\"\u8bbe\u5907 {device.device_id}: {device.width}x{device.height} @ {device.fps}fps\")\r\n\r\n# \u83b7\u53d6\u6700\u4f73\u6444\u50cf\u5934\u8bbe\u5907\r\noptimal_device = get_optimal_camera()\r\n\r\n# \u4f7f\u7528\u6700\u4f73\u8bbe\u5907\r\nwith Camera(source=optimal_device) as cam:\r\n cam.start()\r\n # ...\u5904\u7406\u903b\u8f91...\r\n```\r\n\r\n### \u914d\u7f6e\u7ba1\u7406\r\n\r\n```python\r\nfrom aitoolkit_cam import get_config, set_config, save_config, load_config\r\n\r\n# \u83b7\u53d6\u914d\u7f6e\r\nwidth = get_config(\"camera.default_width\") # \u9ed8\u8ba4640\r\nfps = get_config(\"camera.default_fps\") # \u9ed8\u8ba420\r\n\r\n# \u4fee\u6539\u914d\u7f6e\r\nset_config(\"camera.default_width\", 1280)\r\nset_config(\"camera.default_height\", 720)\r\n\r\n# \u4fdd\u5b58\u914d\u7f6e\u5230\u6587\u4ef6\r\nsave_config(\"my_config.json\")\r\n\r\n# \u52a0\u8f7d\u914d\u7f6e\r\nload_config(\"my_config.json\")\r\n```\r\n\r\n## \ud83c\udfd7\ufe0f \u67b6\u6784\u6a21\u5f0f\r\n\r\n### 1. \u667a\u80fd\u81ea\u9002\u5e94\u6a21\u5f0f\uff08\u63a8\u8350\uff09\r\n\r\nCamera\u7c7b\u81ea\u52a8\u68c0\u6d4b\u8fd0\u884c\u73af\u5883\uff1a\r\n\r\n- **\u6709\u540e\u7aef\u670d\u52a1** \u2192 \u81ea\u52a8\u8fde\u63a5\u5230FastAPI\u540e\u7aef\r\n- **\u65e0\u540e\u7aef\u670d\u52a1** \u2192 \u542f\u52a8\u5185\u7f6eFlask\u670d\u52a1\u5668\r\n\r\n```python\r\n# \u7528\u6237\u4ee3\u7801\u5b8c\u5168\u76f8\u540c\uff0c\u7cfb\u7edf\u81ea\u52a8\u9002\u914d\r\nwith Camera() as cam:\r\n url = cam.start() # \u667a\u80fd\u9009\u62e9\u6a21\u5f0f\r\n # ... \u5904\u7406\u903b\u8f91 ...\r\n```\r\n\r\n### 2. FastAPI\u96c6\u6210\u6a21\u5f0f\r\n\r\n\u5c06\u6444\u50cf\u5934\u529f\u80fd\u96c6\u6210\u5230\u73b0\u6709FastAPI\u5e94\u7528\uff1a\r\n\r\n```python\r\n# \u540e\u7aef\u670d\u52a1\uff08\u7ba1\u7406\u5458\u542f\u52a8\uff09\r\nfrom fastapi import FastAPI\r\nfrom aitoolkit_cam import add_camera_routes\r\n\r\napp = FastAPI()\r\nadd_camera_routes(app)\r\n\r\nif __name__ == \"__main__\":\r\n import uvicorn\r\n # \u652f\u6301\u591a\u4e2a\u7aef\u53e3\uff1a18001, 5000, 6000, 7000, 8000, 9000\r\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\r\n```\r\n\r\n```python\r\n# \u7528\u6237\u4ee3\u7801\uff08Jupyter\u4e2d\uff09\r\nwith Camera() as cam: # \u81ea\u52a8\u68c0\u6d4b\u591a\u4e2a\u7aef\u53e3\u7684\u540e\u7aef\u670d\u52a1\r\n url = cam.start() # \u8fde\u63a5\u5230\u7b2c\u4e00\u4e2a\u53ef\u7528\u7684\u540e\u7aef\u670d\u52a1\r\n # ... \u5904\u7406\u903b\u8f91 ...\r\n```\r\n\r\n**\ud83d\udd0d \u591a\u7aef\u53e3\u81ea\u52a8\u68c0\u6d4b**\r\n\r\naitoolkit_cam \u652f\u6301\u81ea\u52a8\u68c0\u6d4b\u591a\u4e2a\u7aef\u53e3\u7684\u540e\u7aef\u670d\u52a1\uff1a\r\n\r\n- **\u9ed8\u8ba4\u68c0\u6d4b\u7aef\u53e3**\uff1a18001, 5000, 6000, 7000, 8000, 9000\r\n- **\u68c0\u6d4b\u987a\u5e8f**\uff1a\u6309\u914d\u7f6e\u6587\u4ef6\u4e2d\u7684\u987a\u5e8f\u4f9d\u6b21\u68c0\u6d4b\r\n- **\u81ea\u52a8\u8fde\u63a5**\uff1a\u8fde\u63a5\u5230\u7b2c\u4e00\u4e2a\u54cd\u5e94\u7684\u670d\u52a1\r\n- **\u7075\u6d3b\u914d\u7f6e**\uff1a\u53ef\u901a\u8fc7\u914d\u7f6e\u6587\u4ef6\u81ea\u5b9a\u4e49\u7aef\u53e3\u5217\u8868\r\n\r\n```python\r\n# \u542f\u52a8\u4e0d\u540c\u7aef\u53e3\u7684\u540e\u7aef\u670d\u52a1\r\npython examples/multi_port_backend_demo.py --port 6000\r\npython examples/multi_port_backend_demo.py --port 7000\r\n\r\n# \u7528\u6237\u4ee3\u7801\u81ea\u52a8\u68c0\u6d4b\u5e76\u8fde\u63a5\r\nwith Camera() as cam:\r\n url = cam.start() # \u81ea\u52a8\u8fde\u63a5\u5230\u53ef\u7528\u670d\u52a1\r\n```\r\n\r\n### 3. Producer/Hub\u5206\u5e03\u5f0f\u6a21\u5f0f\r\n\r\n\u652f\u6301\u4f20\u7edf\u7684\u5206\u5e03\u5f0f\u67b6\u6784\uff1a\r\n\r\n```python\r\n# Hub\u670d\u52a1\u5668\r\nfrom aitoolkit_cam import Hub\r\nhub = Hub(port=5000)\r\nhub.run()\r\n```\r\n\r\n```python\r\n# Producer\u5ba2\u6237\u7aef\r\nfrom aitoolkit_cam import Camera\r\nwith Camera(hub_url=\"http://hub-server:5000\") as cam:\r\n # ... \u5206\u5e03\u5f0f\u5904\u7406 ...\r\n```\r\n\r\n## \ud83d\udcdd API\u53c2\u8003\r\n\r\n### Camera\u7c7b\r\n\r\n```python\r\nCamera(\r\n source=0, # \u6444\u50cf\u5934\u8bbe\u5907ID\r\n width=640, # \u89c6\u9891\u5bbd\u5ea6\r\n height=480, # \u89c6\u9891\u9ad8\u5ea6\r\n fps=20, # \u5e27\u7387\r\n max_frames=None, # \u6700\u5927\u5e27\u6570\uff08None=\u65e0\u9650\uff09\r\n port=9000 # \u7b80\u5355\u6a21\u5f0f\u4f7f\u7528\u7684\u7aef\u53e3\r\n)\r\n```\r\n\r\n**\u65b9\u6cd5\uff1a**\r\n- `start()` - \u542f\u52a8\u6444\u50cf\u5934\uff0c\u8fd4\u56de\u89c6\u9891\u6d41URL\r\n- `stop()` - \u505c\u6b62\u6444\u50cf\u5934\r\n- `read(timeout=1.0)` - \u8bfb\u53d6\u539f\u59cb\u5e27\r\n- `show(frame)` - \u663e\u793a\u5904\u7406\u540e\u7684\u5e27\r\n- `frame_count` - \u5f53\u524d\u5e27\u8ba1\u6570\r\n\r\n**\u652f\u6301\u7684\u8bed\u6cd5\uff1a**\r\n- `with Camera() as cam:` - \u4e0a\u4e0b\u6587\u7ba1\u7406\u5668\r\n- `for frame in cam:` - \u8fed\u4ee3\u5668\u6a21\u5f0f\r\n\r\n### \u56fe\u50cf\u5904\u7406\r\n\r\n```python\r\n# \u6ee4\u955c\r\nImageFilters.edge_detection(frame, low_threshold=50, high_threshold=150)\r\nImageFilters.blur_effect(frame, kernel_size=15)\r\nImageFilters.cartoon_effect(frame)\r\nImageFilters.sepia_effect(frame)\r\nImageFilters.negative_effect(frame)\r\nImageFilters.brightness_contrast(frame, brightness=0, contrast=1.0)\r\nImageFilters.color_filter(frame, color_mask=(255, 255, 255))\r\nImageFilters.emboss_effect(frame)\r\nImageFilters.motion_blur(frame, size=15, angle=0)\r\n\r\n# \u6587\u672c\u53e0\u52a0\r\nTextOverlay.add_text(frame, text, position=(10, 30), font_scale=1.0)\r\nTextOverlay.add_timestamp(frame)\r\nTextOverlay.add_frame_info(frame, frame_count, fps=30.0)\r\n\r\n# \u6ee4\u955c\u94fe\r\nchain = FilterChain()\r\nchain.add_filter(ImageFilters.blur_effect, kernel_size=5)\r\nchain.add_filter(ImageFilters.edge_detection)\r\nresult = chain.apply(frame)\r\n\r\n# \u9884\u5b9a\u4e49\u6ee4\u955c\r\nvintage_filter = create_vintage_filter()\r\nartistic_filter = create_artistic_filter()\r\ndramatic_filter = create_dramatic_filter()\r\n```\r\n\r\n### \u8bbe\u5907\u7ba1\u7406\r\n\r\n```python\r\n# \u5217\u51fa\u53ef\u7528\u6444\u50cf\u5934\r\ndevices = list_available_cameras()\r\n\r\n# \u83b7\u53d6\u6700\u4f73\u6444\u50cf\u5934\r\ndevice_id = get_optimal_camera()\r\n\r\n# \u9a8c\u8bc1\u6444\u50cf\u5934\u8bbe\u5907\r\nis_valid = validate_camera(device_id)\r\n\r\n# \u83b7\u53d6\u8bbe\u5907\u4fe1\u606f\r\ninfo = get_camera_info(device_id)\r\n\r\n# \u83b7\u53d6\u8bbe\u5907\u80fd\u529b\r\ncapabilities = get_camera_capabilities(device_id)\r\n```\r\n\r\n### \u914d\u7f6e\u7ba1\u7406\r\n\r\n```python\r\n# \u83b7\u53d6\u914d\u7f6e\r\nvalue = get_config(\"section.key\", default_value)\r\n\r\n# \u8bbe\u7f6e\u914d\u7f6e\r\nset_config(\"section.key\", new_value)\r\n\r\n# \u52a0\u8f7d\u914d\u7f6e\u6587\u4ef6\r\nload_config(\"config.json\")\r\n\r\n# \u4fdd\u5b58\u914d\u7f6e\u5230\u6587\u4ef6\r\nsave_config(\"config.json\")\r\n\r\n# \u91cd\u7f6e\u4e3a\u9ed8\u8ba4\u914d\u7f6e\r\nreset_config()\r\n```\r\n\r\n### FastAPI\u96c6\u6210\u51fd\u6570\r\n\r\n```python\r\nadd_camera_routes(app, prefix=\"/camera\")\r\nsetup_background_processing(app, frame_processor=None, fps=20)\r\n```\r\n\r\n## \ud83d\udd27 \u4f7f\u7528\u573a\u666f\r\n\r\n### \u573a\u666f1\uff1aJupyter\u5b9e\u9a8c\u73af\u5883\r\n\r\n```python\r\n# \u7814\u7a76\u4eba\u5458\u5728Jupyter\u4e2d\u4f7f\u7528\r\nwith Camera(max_frames=100) as cam:\r\n cam.start()\r\n for frame in cam:\r\n # \u5b9e\u65f6\u56fe\u50cf\u5904\u7406\u5b9e\u9a8c\r\n result = my_algorithm(frame)\r\n cam.show(result)\r\n```\r\n\r\n### \u573a\u666f2\uff1aWeb\u5e94\u7528\u96c6\u6210\r\n\r\n```python\r\n# \u96c6\u6210\u5230\u73b0\u6709Web\u5e94\u7528\r\napp = FastAPI()\r\nadd_camera_routes(app)\r\n\r\n# \u7528\u6237\u901a\u8fc7Web\u754c\u9762\u63a7\u5236\u6444\u50cf\u5934\r\n# \u8bbf\u95ee /camera/ \u67e5\u770b\u63a7\u5236\u9875\u9762\r\n# \u8bbf\u95ee /camera/stream \u67e5\u770b\u89c6\u9891\u6d41\r\n```\r\n\r\n### \u573a\u666f3\uff1a\u5206\u5e03\u5f0f\u5904\u7406\r\n\r\n```python\r\n# \u591a\u4e2a\u6444\u50cf\u5934\u8282\u70b9\u8fde\u63a5\u5230\u4e2d\u592eHub\r\n# \u9002\u5408\u76d1\u63a7\u3001\u591a\u70b9\u91c7\u96c6\u7b49\u573a\u666f\r\n```\r\n\r\n## \ud83d\udea6 \u6d4b\u8bd5\r\n\r\n\u9879\u76ee\u5305\u542b\u5b8c\u6574\u7684\u6d4b\u8bd5\u5957\u4ef6\uff1a\r\n\r\n```bash\r\n# \u5355\u5143\u6d4b\u8bd5\r\npython -m unittest tests/test_unit.py\r\n\r\n# \u529f\u80fd\u8c03\u8bd5\u6d4b\u8bd5\r\npython tests/test_debug.py\r\n\r\n# \u7528\u6237\u6a21\u5f0f\u6d4b\u8bd5\r\npython tests/test_simple_mode.py\r\n\r\n# \u540e\u7aef\u670d\u52a1\u6d4b\u8bd5 \r\npython tests/test_backend_service.py\r\n```\r\n\r\n## \ud83d\udc33 Docker\u652f\u6301\r\n\r\n\u9879\u76ee\u63d0\u4f9b\u4e86Docker\u652f\u6301\uff0c\u53ef\u4ee5\u8f7b\u677e\u90e8\u7f72\uff1a\r\n\r\n```bash\r\n# \u6784\u5efaDocker\u955c\u50cf\r\ndocker build -t aitoolkit-cam .\r\n\r\n# \u8fd0\u884cDocker\u5bb9\u5668\r\ndocker run -p 8000:8000 aitoolkit-cam\r\n\r\n# \u4f7f\u7528docker-compose\r\ndocker-compose up\r\n```\r\n\r\n## \ud83d\udccb \u5f00\u53d1\u6307\u5357\r\n\r\n### \u6d4b\u8bd5\u6b65\u9aa4\r\n\r\n1. **\u5355\u5143\u6d4b\u8bd5**\uff1a\r\n ```bash\r\n python -m unittest tests/test_unit.py\r\n ```\r\n\r\n2. **\u72ec\u7acb\u6d4b\u8bd5**\uff1a\r\n ```bash\r\n python tests/test_simple_mode.py\r\n ```\r\n\r\n3. **\u96c6\u6210\u6d4b\u8bd5**\uff1a\r\n ```bash\r\n # \u7ec8\u7aef1\uff1a\u542f\u52a8\u540e\u7aef\r\n python tests/test_backend_service.py\r\n \r\n # \u7ec8\u7aef2\uff1a\u8fd0\u884c\u7528\u6237\u4ee3\u7801\r\n python tests/test_simple_mode.py\r\n ```\r\n\r\n### \u6545\u969c\u6392\u9664\r\n\r\n\u5982\u679c\u9047\u5230\u95ee\u9898\uff1a\r\n\r\n1. \u8fd0\u884c\u8c03\u8bd5\u6d4b\u8bd5\uff1a`python tests/test_debug.py`\r\n2. \u68c0\u67e5\u6444\u50cf\u5934\u8bbe\u5907\u662f\u5426\u53ef\u7528\r\n3. \u786e\u8ba4\u7f51\u7edc\u7aef\u53e3\u672a\u88ab\u5360\u7528\r\n4. \u67e5\u770b\u65e5\u5fd7\u8f93\u51fa\r\n\r\n## \ud83d\udcd6 \u66f4\u591a\u793a\u4f8b\r\n\r\n\u67e5\u770b `examples/` \u76ee\u5f55\u4e2d\u7684\u5b8c\u6574\u793a\u4f8b\uff1a\r\n\r\n- `basic_usage.py` - \u57fa\u672c\u4f7f\u7528\u793a\u4f8b\r\n- `advanced_features.py` - \u9ad8\u7ea7\u529f\u80fd\u793a\u4f8b\r\n- `fastapi_integration.py` - FastAPI\u96c6\u6210\u793a\u4f8b\r\n- `config_management.py` - \u914d\u7f6e\u7ba1\u7406\u793a\u4f8b\r\n\r\n## \ud83e\udd1d \u8d21\u732e\r\n\r\n\u6b22\u8fce\u63d0\u4ea4Issue\u548cPull Request\uff01\r\n\r\n## \ud83d\udcc4 \u8bb8\u53ef\u8bc1\r\n\r\nMIT License\r\n",
"bugtrack_url": null,
"license": null,
"summary": "\u6781\u7b80Python\u6444\u50cf\u5934\u5e93 - \u4e3a\u4e2d\u5b66\u751f\u548cARM64\u8bbe\u5907\u7279\u522b\u4f18\u5316",
"version": "1.1.0",
"project_urls": {
"Bug Reports": "https://github.com/bosscoder-ai/aitoolkit_cam/issues",
"Homepage": "https://github.com/bosscoder-ai/aitoolkit_cam",
"Source": "https://github.com/bosscoder-ai/aitoolkit_cam"
},
"split_keywords": [
"camera",
" opencv",
" video",
" streaming",
" web",
" cv2",
" jupyter",
" notebook",
" education",
" arm64",
" raspberry-pi",
" real-time",
" smart-stop"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "cdcf47c96355878aeefdba17ec6bfa670f29b16b9c439c66dbe06f5bcec62cbd",
"md5": "625cb1aca8d1bdbbedffb518693ff75b",
"sha256": "67ca224ace6ef6edee2c16ccc4c57bd101578a2591b1b28686ec501a4a87334e"
},
"downloads": -1,
"filename": "aitoolkit_cam-1.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "625cb1aca8d1bdbbedffb518693ff75b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 31054,
"upload_time": "2025-08-06T09:13:11",
"upload_time_iso_8601": "2025-08-06T09:13:11.126508Z",
"url": "https://files.pythonhosted.org/packages/cd/cf/47c96355878aeefdba17ec6bfa670f29b16b9c439c66dbe06f5bcec62cbd/aitoolkit_cam-1.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "84bb1fc8aa3ed8e66ccc60d92258dabe84c15b7decad950cd687c1e218dd4db5",
"md5": "8bb49a276eb0a45acd06f33a46a2950d",
"sha256": "db3d108bd1479b299fa319391accccb8f24ce35b6883888b31e60a512638304a"
},
"downloads": -1,
"filename": "aitoolkit_cam-1.1.0.tar.gz",
"has_sig": false,
"md5_digest": "8bb49a276eb0a45acd06f33a46a2950d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 39848,
"upload_time": "2025-08-06T09:13:12",
"upload_time_iso_8601": "2025-08-06T09:13:12.861886Z",
"url": "https://files.pythonhosted.org/packages/84/bb/1fc8aa3ed8e66ccc60d92258dabe84c15b7decad950cd687c1e218dd4db5/aitoolkit_cam-1.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-06 09:13:12",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "bosscoder-ai",
"github_project": "aitoolkit_cam",
"github_not_found": true,
"lcname": "aitoolkit-cam"
}