Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: automatic camera resolution configuration #6810

Merged
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
535f710
Add auto configuration for height, width and fps in detect role
skrashevich Jun 14, 2023
63cd8e5
Add auto-configuration for detect width, height, and fps for input ro…
skrashevich Jun 14, 2023
a53fc32
Refactor code to retrieve video properties from input stream in Camer…
skrashevich Jun 15, 2023
5ca3035
format
skrashevich Jun 15, 2023
a1aed04
Set default detect dimensions to 1280x720 and update DetectConfig to …
skrashevich Jun 15, 2023
838f246
Revert "Set default detect dimensions to 1280x720 and update DetectCo…
skrashevich Jun 15, 2023
2fff932
Add default detect dimensions if autoconfiguration failed and log a w…
skrashevich Jun 15, 2023
cbb3911
fix warn message spelling on frigate/config.py
skrashevich Jun 15, 2023
747006c
Ensure detect height and width are not None before using them in came…
skrashevich Jun 15, 2023
6d202c6
docs: initial commit
skrashevich Jun 15, 2023
31ead3e
rename streamInfo to stream_info
skrashevich Jun 15, 2023
4681e1f
Apply suggestions from code review
skrashevich Jun 15, 2023
b90eba9
Update docs
skrashevich Jun 15, 2023
990b6dd
Merge branch 'dev' into 230615-feature-camera-autoconf
skrashevich Jun 19, 2023
745a6d1
handle case then get_video_properties returns 0x0 dimension
skrashevich Jun 22, 2023
76886ec
Set detect resolution based on stream properties if available, else a…
skrashevich Jun 22, 2023
2682aa9
Update FrigateConfig to set default values for stream_info if resolut…
skrashevich Jun 26, 2023
59e7ec1
Update camera detection dimensions based on stream information if ava…
skrashevich Jun 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/docs/configuration/camera_specific.md
Expand Up @@ -80,8 +80,8 @@ cameras:
rtmp:
enabled: False # <-- RTMP should be disabled if your stream is not H264
detect:
width: # <---- update for your camera's resolution
height: # <---- update for your camera's resolution
width: # <- optional, by default Frigate try to automatically detect resolution
height: # <- optional, by default Frigate try to automatically detect resolution
skrashevich marked this conversation as resolved.
Show resolved Hide resolved
```

### Blue Iris RTSP Cameras
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/configuration/cameras.md
Expand Up @@ -33,8 +33,8 @@ cameras:
roles:
- record
detect:
width: 1280
height: 720
width: 1280 # <- optional, by default Frigate try to automatically detect resolution
height: 720 # <- optional, by default Frigate try to automatically detect resolution
skrashevich marked this conversation as resolved.
Show resolved Hide resolved
```

Additional cameras are simply added to the config under the `cameras` entry.
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/configuration/index.md
Copy link
Sponsor Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think the top level "minimal config" should just have the detect config removed.

and regardless, the specific detect config needs to e updated.

detect:
# Optional: width of the frame for the input with the detect role (default: shown below)
width: 1280
# Optional: height of the frame for the input with the detect role (default: shown below)
height: 720

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but this lines in the 'Full configuration reference' part

Copy link
Sponsor Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first part is specifically in the Minimal Configuration part and the width / height is not part of a minimal configuration

Screen Shot 2023-06-19 at 13 45 44 PM

The second part needs to be updated. The defaults are no longer 1280 x 720 the default is to auto detect with a fallback of 1280x720.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. on your screenshot lines 3-24. But in this thread we are talking about lines 195-199 (see first message)

Copy link
Sponsor Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha, but for lines 195-199 they need to be updated because

The defaults are no longer 1280 x 720, the default is now to auto detect with a fallback of 1280x720.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha, but for lines 195-199 they need to be updated because

I think, here only needs to change the wording of the comment, about autoconfiguration and fallback. And I'm definitely not the best man for that :)

Expand Up @@ -20,8 +20,8 @@ cameras:
roles:
- detect
detect:
width: 1280
height: 720
width: # <- optional, by default Frigate try to automatically detect resolution
skrashevich marked this conversation as resolved.
Show resolved Hide resolved
height: # <- optional, by default Frigate try to automatically detect resolution
```

### VSCode Configuration Schema
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/development/contributing.md
Expand Up @@ -69,8 +69,8 @@ cameras:
roles:
- detect
detect:
height: 1080
width: 1920
height: 1080 # <- optional, by default Frigate try to automatically detect resolution
skrashevich marked this conversation as resolved.
Show resolved Hide resolved
width: 1920 # <- optional, by default Frigate try to automatically detect resolution
fps: 5
```

Expand Down
5 changes: 1 addition & 4 deletions docs/docs/guides/getting_started.md
Expand Up @@ -22,8 +22,6 @@ cameras:
- detect
detect:
enabled: False # <---- disable detection until you have a working camera feed
width: 1280 # <---- update for your camera's resolution
height: 720 # <---- update for your camera's resolution
```

### Step 2: Start Frigate
Expand Down Expand Up @@ -106,8 +104,7 @@ cameras:
roles:
- detect
detect:
width: 1280
height: 720
fps: 5
skrashevich marked this conversation as resolved.
Show resolved Hide resolved
motion:
mask:
- 0,461,3,0,1919,0,1919,843,1699,492,1344,458,1346,336,973,317,869,375,866,432
Expand Down
29 changes: 27 additions & 2 deletions frigate/config.py
Expand Up @@ -29,6 +29,7 @@
deep_merge,
escape_special_characters,
get_ffmpeg_arg_list,
get_video_properties,
load_config_with_no_duplicates,
)

Expand All @@ -43,6 +44,7 @@

DEFAULT_TRACKED_OBJECTS = ["person"]
DEFAULT_DETECTORS = {"cpu": {"type": "cpu"}}
DEFAULT_DETECT_DIMENSIONS = {"width": 1280, "height": 720}


class FrigateBaseModel(BaseModel):
Expand Down Expand Up @@ -266,8 +268,8 @@ class StationaryConfig(FrigateBaseModel):


class DetectConfig(FrigateBaseModel):
height: int = Field(default=720, title="Height of the stream for the detect role.")
width: int = Field(default=1280, title="Width of the stream for the detect role.")
height: Optional[int] = Field(title="Height of the stream for the detect role.")
width: Optional[int] = Field(title="Width of the stream for the detect role.")
fps: int = Field(
default=5, title="Number of frames per second to process through detection."
)
Expand Down Expand Up @@ -954,6 +956,29 @@ def runtime_config(self, plus_api: PlusApi = None) -> FrigateConfig:
{"name": name, **merged_config}
)

if (
camera_config.detect.height is None
or camera_config.detect.width is None
):
for input in camera_config.ffmpeg.inputs:
if "detect" in input.roles:
try:
streamInfo = get_video_properties(input.path)
camera_config.detect.width = streamInfo["width"]
camera_config.detect.height = streamInfo["height"]
skrashevich marked this conversation as resolved.
Show resolved Hide resolved
break
except Exception:
camera_config.detect.width = DEFAULT_DETECT_DIMENSIONS[
"width"
]
camera_config.detect.height = DEFAULT_DETECT_DIMENSIONS[
"height"
]
logger.warn(
f"Error detecting stream resolution automatically for {input.path} Applying default values."
)
continue

# Default max_disappeared configuration
max_disappeared = camera_config.detect.fps * 5
if camera_config.detect.max_disappeared is None:
Expand Down
31 changes: 31 additions & 0 deletions frigate/util.py
Expand Up @@ -1144,3 +1144,34 @@ def to_relative_box(
(box[2] - box[0]) / width, # w
(box[3] - box[1]) / height, # h
)


def get_video_properties(url, get_duration=False):
width = height = 0
# Open the video stream
video = cv2.VideoCapture(url)

# Check if the video stream was opened successfully
if not video.isOpened():
logger.debug(f"Error opening video stream {url}.")
return None

# Get the width of frames in the video stream
width = video.get(cv2.CAP_PROP_FRAME_WIDTH)

# Get the height of frames in the video stream
height = video.get(cv2.CAP_PROP_FRAME_HEIGHT)

# Release the video stream
video.release()

result = {"width": round(width), "height": round(height)}
if get_duration:
# Get the frames per second (fps) of the video stream
fps = video.get(cv2.CAP_PROP_FPS)
total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
duration = total_frames / fps

result["duration"] = duration

return result