Skip to content

Commit 6e1e1fd

Browse files
gmathy2104claude
andcommitted
docs: release v2.4.0 - FOV mode selection feature
Add comprehensive documentation for Field of View (FOV) mode selection feature: - Choose between 'scale' (constant FOV) and 'crop' (digital zoom) modes - New endpoints: GET/POST /v1/camera/fov_mode - Enhanced resolution endpoint with optional fov_mode parameter Updated files: - camera_service/api.py: Updated version to 2.4.0 - tests/test_api_integration.py: Updated expected version - CHANGELOG.md: Added v2.4.0 release notes with FOV mode details - README.md: Added FOV mode section and updated version references - docs/api-reference.md: Added FOV mode endpoints documentation FOV Modes: - scale (default): Full sensor readout + ISP downscaling = constant FOV - crop: Sensor crop for target resolution = digital zoom effect 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 665e64e commit 6e1e1fd

File tree

5 files changed

+243
-8
lines changed

5 files changed

+243
-8
lines changed

CHANGELOG.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,50 @@ All notable changes to Pi Camera Service will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [2.4.0] - 2025-11-22
9+
10+
### Added
11+
12+
#### Field of View (FOV) Mode Selection
13+
- **NEW FEATURE**: Choose between two FOV modes for different use cases
14+
- **"scale" mode** (default): Constant field of view at all resolutions
15+
- Reads full sensor area (4608x2592 for IMX708)
16+
- Hardware ISP downscales to target resolution
17+
- Better image quality (downsampling vs cropping)
18+
- Ideal for monitoring, surveillance, and consistent framing
19+
- **"crop" mode**: Digital zoom effect with sensor crop
20+
- Reads only required sensor area for target resolution
21+
- FOV reduces at lower resolutions (telephoto effect)
22+
- Lower processing load, faster sensor readout
23+
- Useful for zoom/telephoto applications
24+
25+
#### New API Endpoints
26+
- `GET /v1/camera/fov_mode` - Query current FOV mode
27+
- Returns: `{"mode": "scale", "description": "..."}`
28+
- `POST /v1/camera/fov_mode` - Change FOV mode
29+
- Request: `{"mode": "scale"}` or `{"mode": "crop"}`
30+
- Takes effect on next resolution/framerate change
31+
32+
#### Enhanced Resolution Endpoint
33+
- Added optional `fov_mode` parameter to `POST /v1/camera/resolution`
34+
- Can change FOV mode and resolution in single request
35+
- Example: `{"width": 1280, "height": 720, "fov_mode": "crop"}`
36+
37+
#### Enhanced Status Response
38+
- Added `fov_mode` field to `GET /v1/camera/status`
39+
- Shows current FOV mode ("scale" or "crop")
40+
41+
### Changed
42+
- Default FOV mode is now "scale" for constant field of view across all resolutions
43+
- All resolution/framerate changes now maintain configurable FOV behavior
44+
- Camera configuration uses conditional sensor parameters based on FOV mode
45+
46+
### Technical Details
47+
- New `CameraController` methods: `set_fov_mode()`, `get_fov_mode()`, `_get_sensor_config()`
48+
- FOV mode persists across camera reconfigurations
49+
- Thread-safe implementation with existing RLock protection
50+
- Zero breaking changes - fully backwards compatible
51+
852
## [2.3.1] - 2025-11-22
953

1054
### Fixed

README.md

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@
22

33
Production-ready **FastAPI** microservice for controlling Raspberry Pi Camera (libcamera/Picamera2) with **H.264 streaming** to **MediaMTX** via RTSP.
44

5-
**Version 2.3.1** - Critical race condition fix + Dynamic framerate control with intelligent clamping!
5+
**Version 2.4.0** - FOV mode selection (scale/crop) + Dynamic framerate control!
66

7-
[![Version](https://img.shields.io/badge/version-2.3.1-blue.svg)](https://github.com/gmathy2104/pi-camera-service/releases)
7+
[![Version](https://img.shields.io/badge/version-2.4.0-blue.svg)](https://github.com/gmathy2104/pi-camera-service/releases)
88
[![Python](https://img.shields.io/badge/python-3.9+-green.svg)](https://www.python.org/)
99
[![FastAPI](https://img.shields.io/badge/FastAPI-0.121+-teal.svg)](https://fastapi.tiangolo.com/)
1010
[![License](https://img.shields.io/badge/license-MIT-orange.svg)](LICENSE)
1111
[![Tests](https://github.com/gmathy2104/pi-camera-service/workflows/Tests/badge.svg)](https://github.com/gmathy2104/pi-camera-service/actions)
1212

13-
> 🆕 **New in v2.3**: Dynamic framerate control with intelligent clamping! Request any framerate and the API automatically applies the maximum for your resolution. Enhanced capabilities endpoint with complete framerate limits table.
13+
> 🆕 **New in v2.4**: **FOV mode selection** - Choose between constant field of view (scale) or digital zoom effect (crop) for all resolutions. Perfect control for surveillance or telephoto applications!
14+
>
15+
> ℹ️ **v2.3 features**: Dynamic framerate control with intelligent clamping. Fixed critical race condition in concurrent camera reconfiguration.
1416
>
1517
> ℹ️ **v2.2 features**: Camera capabilities discovery endpoint to query supported resolutions, exposure/gain limits, and available features.
1618
>
@@ -381,7 +383,7 @@ sudo journalctl -u pi-camera-service -f
381383
"status": "healthy",
382384
"camera_configured": true,
383385
"streaming_active": true,
384-
"version": "2.3.1"
386+
"version": "2.4.0"
385387
}
386388
```
387389

@@ -467,6 +469,53 @@ Discover camera hardware capabilities and supported features.
467469
}
468470
```
469471

472+
### Field of View (FOV) Mode (New in v2.4)
473+
474+
Choose between constant field of view or digital zoom effect across all resolutions.
475+
476+
**GET** `/v1/camera/fov_mode`
477+
478+
Query current FOV mode.
479+
480+
```json
481+
{
482+
"mode": "scale",
483+
"description": "Full sensor readout with downscaling → Constant field of view"
484+
}
485+
```
486+
487+
**POST** `/v1/camera/fov_mode`
488+
489+
Change FOV mode.
490+
491+
```json
492+
{"mode": "scale"} // or "crop"
493+
```
494+
495+
**Modes:**
496+
- **`scale`** (default): Constant field of view at all resolutions
497+
- Reads full sensor area (4608x2592 for IMX708)
498+
- Hardware ISP downscales to target resolution
499+
- Better image quality from downsampling
500+
- Perfect for surveillance, monitoring, consistent framing
501+
502+
- **`crop`**: Digital zoom effect (sensor crop)
503+
- Reads only required sensor area for target resolution
504+
- FOV reduces at lower resolutions (telephoto effect)
505+
- Lower processing load, faster readout
506+
- Useful for zoom/telephoto applications
507+
508+
**Example - Set FOV mode with resolution:**
509+
```json
510+
POST /v1/camera/resolution
511+
{
512+
"width": 1280,
513+
"height": 720,
514+
"fov_mode": "crop", // Optional: change mode simultaneously
515+
"restart_streaming": true
516+
}
517+
```
518+
470519
### Exposure Control
471520

472521
**POST** `/v1/camera/auto_exposure`

camera_service/api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
168168
app = FastAPI(
169169
title="Pi Camera Service",
170170
description="API for controlling Raspberry Pi camera and streaming to MediaMTX via RTSP",
171-
version="2.3.1",
171+
version="2.4.0",
172172
lifespan=lifespan,
173173
)
174174

@@ -491,7 +491,7 @@ def health_check() -> HealthResponse:
491491
status="healthy" if camera_controller is not None else "initializing",
492492
camera_configured=camera_controller._configured if camera_controller else False,
493493
streaming_active=streaming_manager.is_streaming() if streaming_manager else False,
494-
version="2.3.1",
494+
version="2.4.0",
495495
)
496496

497497

docs/api-reference.md

Lines changed: 143 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22

33
This document provides a complete reference for the Pi Camera Service HTTP API, including all available features, endpoints, and connection instructions.
44

5+
> **Note**: This document primarily covers v1.0 API endpoints. For comprehensive documentation of v2.0+ features (autofocus, snapshot, HDR, exposure value, noise reduction, capabilities, framerate control, FOV mode, etc.), see the main [README.md](../README.md).
6+
>
7+
> **New in v2.4**: Field of View (FOV) mode selection - documented below.
8+
59
## Overview
610

711
The Pi Camera Service is a REST API that controls a Raspberry Pi camera and streams H.264 video to MediaMTX via RTSP. It provides real-time control over camera settings including exposure, gain, white balance, and streaming.
812

913
**Base URL:** `http://<RASPBERRY_PI_IP>:8000`
1014

11-
**API Version:** v1.0
15+
**API Version:** v2.4.0 (this document covers v1.0 core features + v2.4 FOV mode)
1216

1317
**Protocol:** HTTP/REST
1418

@@ -371,6 +375,144 @@ curl -X POST http://<PI_IP>:8000/v1/camera/awb \
371375

372376
---
373377

378+
#### POST /v1/camera/fov_mode (v2.4)
379+
380+
Set the Field of View (FOV) mode to control sensor readout behavior across different resolutions.
381+
382+
**Authentication:** Required (if configured)
383+
384+
**Request Body:**
385+
```json
386+
{
387+
"mode": "scale"
388+
}
389+
```
390+
391+
**Request Fields:**
392+
- `mode` (string, required): FOV mode - either `"scale"` or `"crop"`
393+
394+
**Response:**
395+
```json
396+
{
397+
"status": "ok",
398+
"mode": "scale",
399+
"description": "Full sensor readout with downscaling → Constant field of view"
400+
}
401+
```
402+
403+
**FOV Modes:**
404+
405+
- **`scale`** (default): Constant field of view at all resolutions
406+
- Reads full sensor area (4608x2592 for IMX708)
407+
- Hardware ISP downscales to target resolution
408+
- Better image quality from downsampling vs cropping
409+
- Perfect for surveillance, monitoring, consistent framing
410+
- Use when you want the same field of view regardless of resolution
411+
412+
- **`crop`**: Digital zoom effect (sensor crop)
413+
- Reads only required sensor area for target resolution
414+
- FOV reduces at lower resolutions (telephoto effect)
415+
- Lower processing load, faster sensor readout
416+
- Useful for zoom/telephoto applications
417+
- Use when you want a "zoomed in" view at lower resolutions
418+
419+
**Example - Set to scale mode:**
420+
```bash
421+
curl -X POST http://<PI_IP>:8000/v1/camera/fov_mode \
422+
-H "Content-Type: application/json" \
423+
-H "X-API-Key: your-key" \
424+
-d '{"mode": "scale"}'
425+
```
426+
427+
**Example - Set to crop mode:**
428+
```bash
429+
curl -X POST http://<PI_IP>:8000/v1/camera/fov_mode \
430+
-H "Content-Type: application/json" \
431+
-H "X-API-Key: your-key" \
432+
-d '{"mode": "crop"}'
433+
```
434+
435+
**Python Example:**
436+
```python
437+
import requests
438+
439+
# Set to scale mode for constant FOV
440+
response = requests.post(
441+
"http://<PI_IP>:8000/v1/camera/fov_mode",
442+
headers={"X-API-Key": "your-key"},
443+
json={"mode": "scale"}
444+
)
445+
print(response.json())
446+
447+
# Set to crop mode for digital zoom effect
448+
response = requests.post(
449+
"http://<PI_IP>:8000/v1/camera/fov_mode",
450+
headers={"X-API-Key": "your-key"},
451+
json={"mode": "crop"}
452+
)
453+
print(response.json())
454+
```
455+
456+
**Combined with Resolution Change:**
457+
458+
You can also set FOV mode when changing resolution:
459+
460+
```bash
461+
curl -X POST http://<PI_IP>:8000/v1/camera/resolution \
462+
-H "Content-Type: application/json" \
463+
-H "X-API-Key: your-key" \
464+
-d '{
465+
"width": 1280,
466+
"height": 720,
467+
"fov_mode": "crop",
468+
"restart_streaming": true
469+
}'
470+
```
471+
472+
**When to Use:**
473+
- Use `scale` for surveillance cameras where consistent framing is essential
474+
- Use `crop` when you want different zoom levels at different resolutions
475+
- Change to `crop` before lowering resolution if you want a telephoto effect
476+
- Change to `scale` if lower resolutions appear too zoomed in
477+
478+
**Note:** Changes take effect on the next camera reconfiguration (resolution/framerate change).
479+
480+
---
481+
482+
#### GET /v1/camera/fov_mode (v2.4)
483+
484+
Query the current FOV mode.
485+
486+
**Authentication:** Required (if configured)
487+
488+
**Response:**
489+
```json
490+
{
491+
"mode": "scale",
492+
"description": "Full sensor readout with downscaling → Constant field of view"
493+
}
494+
```
495+
496+
**Example:**
497+
```bash
498+
curl -H "X-API-Key: your-key" http://<PI_IP>:8000/v1/camera/fov_mode
499+
```
500+
501+
**Python Example:**
502+
```python
503+
import requests
504+
505+
response = requests.get(
506+
"http://<PI_IP>:8000/v1/camera/fov_mode",
507+
headers={"X-API-Key": "your-key"}
508+
)
509+
mode_info = response.json()
510+
print(f"Current FOV mode: {mode_info['mode']}")
511+
print(f"Description: {mode_info['description']}")
512+
```
513+
514+
---
515+
374516
### Streaming Control Endpoints
375517

376518
#### POST /v1/streaming/start

tests/test_api_integration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def test_health_endpoint(self) -> None:
6262
assert data["status"] == "healthy"
6363
assert "camera_configured" in data
6464
assert "streaming_active" in data
65-
assert data["version"] == "2.3.1"
65+
assert data["version"] == "2.4.0"
6666

6767
print("✓ Health endpoint working")
6868

0 commit comments

Comments
 (0)