Add support for libcamera Autofocus parameters (#1417)

* [DEV #1416] Add support for libcamera Autofocus parameters

* [DEVMINOR] Fix Go formatting

* [DEV] Support AF window parameter for rpiCamera

* [DEV] Update default .yml file to add rpiCameraAfWindow parameter
This commit is contained in:
Azsde 2023-02-10 12:20:50 +01:00 committed by GitHub
parent 50a3d331d7
commit 4841189456
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 185 additions and 60 deletions

View File

@ -73,6 +73,11 @@ type PathConf struct {
RPICameraBitrate int `json:"rpiCameraBitrate"`
RPICameraProfile string `json:"rpiCameraProfile"`
RPICameraLevel string `json:"rpiCameraLevel"`
RPICameraAfMode string `json:"rpiCameraAfMode"`
RPICameraAfRange string `json:"rpiCameraAfRange"`
RPICameraAfSpeed string `json:"rpiCameraAfSpeed"`
RPICameraLensPosition float64 `json:"rpiCameraLensPosition"`
RPICameraAfWindow string `json:"rpiCameraAfWindow"`
// authentication
PublishUser Credential `json:"publishUser"`

View File

@ -86,30 +86,35 @@ func newSourceStatic(
case conf.Source == "rpiCamera":
s.impl = newRPICameraSource(
rpicamera.Params{
CameraID: conf.RPICameraCamID,
Width: conf.RPICameraWidth,
Height: conf.RPICameraHeight,
HFlip: conf.RPICameraHFlip,
VFlip: conf.RPICameraVFlip,
Brightness: conf.RPICameraBrightness,
Contrast: conf.RPICameraContrast,
Saturation: conf.RPICameraSaturation,
Sharpness: conf.RPICameraSharpness,
Exposure: conf.RPICameraExposure,
AWB: conf.RPICameraAWB,
Denoise: conf.RPICameraDenoise,
Shutter: conf.RPICameraShutter,
Metering: conf.RPICameraMetering,
Gain: conf.RPICameraGain,
EV: conf.RPICameraEV,
ROI: conf.RPICameraROI,
TuningFile: conf.RPICameraTuningFile,
Mode: conf.RPICameraMode,
FPS: conf.RPICameraFPS,
IDRPeriod: conf.RPICameraIDRPeriod,
Bitrate: conf.RPICameraBitrate,
Profile: conf.RPICameraProfile,
Level: conf.RPICameraLevel,
CameraID: conf.RPICameraCamID,
Width: conf.RPICameraWidth,
Height: conf.RPICameraHeight,
HFlip: conf.RPICameraHFlip,
VFlip: conf.RPICameraVFlip,
Brightness: conf.RPICameraBrightness,
Contrast: conf.RPICameraContrast,
Saturation: conf.RPICameraSaturation,
Sharpness: conf.RPICameraSharpness,
Exposure: conf.RPICameraExposure,
AWB: conf.RPICameraAWB,
Denoise: conf.RPICameraDenoise,
Shutter: conf.RPICameraShutter,
Metering: conf.RPICameraMetering,
Gain: conf.RPICameraGain,
EV: conf.RPICameraEV,
ROI: conf.RPICameraROI,
TuningFile: conf.RPICameraTuningFile,
Mode: conf.RPICameraMode,
FPS: conf.RPICameraFPS,
IDRPeriod: conf.RPICameraIDRPeriod,
Bitrate: conf.RPICameraBitrate,
Profile: conf.RPICameraProfile,
Level: conf.RPICameraLevel,
AfMode: conf.RPICameraAfMode,
AfRange: conf.RPICameraAfRange,
AfSpeed: conf.RPICameraAfSpeed,
LensPosition: conf.RPICameraLensPosition,
AfWindow: conf.RPICameraAfWindow,
},
s)
}

View File

@ -3,7 +3,8 @@ CFLAGS = \
-Werror \
-Wall \
-Wextra \
-Wno-unused-parameter
-Wno-unused-parameter \
-Wno-unused-result
CXXFLAGS = \
-Ofast \
@ -11,6 +12,7 @@ CXXFLAGS = \
-Wall \
-Wextra \
-Wno-unused-parameter \
-Wno-unused-result \
-std=c++17 \
$$(pkg-config --cflags libcamera)
@ -24,7 +26,7 @@ OBJS = \
encoder.o \
main.o \
parameters.o \
roi.o \
window.o \
sensor_mode.o
all: exe

View File

@ -334,6 +334,71 @@ bool camera_start(camera_t *cam) {
int64_t frame_time = 1000000 / camp->params->fps;
ctrls.set(controls::FrameDurationLimits, Span<const int64_t, 2>({ frame_time, frame_time }));
int af_mode;
if (strcmp(camp->params->af_mode, "manual") == 0) {
af_mode = controls::AfModeManual;
} else if (strcmp(camp->params->af_mode, "auto") == 0) {
af_mode = controls::AfModeAuto;
} else if (strcmp(camp->params->af_mode, "continuous") == 0) {
af_mode = controls::AfModeContinuous;
} else {
af_mode = controls::AfModeManual;
}
ctrls.set(controls::AfMode, af_mode);
int af_range;
if (strcmp(camp->params->af_range, "normal") == 0) {
af_range = controls::AfRangeNormal;
} else if (strcmp(camp->params->af_range, "macro") == 0) {
af_range = controls::AfRangeMacro;
} else if (strcmp(camp->params->af_range, "full") == 0) {
af_range = controls::AfRangeFull;
} else {
af_range = controls::AfRangeNormal;
}
ctrls.set(controls::AfRange, af_range);
int af_speed;
if (strcmp(camp->params->af_range, "normal") == 0) {
af_speed = controls::AfSpeedNormal;
} else if (strcmp(camp->params->af_range, "fast") == 0) {
af_speed = controls::AfSpeedFast;
} else {
af_speed = controls::AfSpeedNormal;
}
ctrls.set(controls::AfSpeed, af_speed);
// Lens Position
ctrls.set(controls::LensPosition, camp->params->lens_position);
// Af Window
if (camp->params->af_window != NULL) {
std::optional<Rectangle> opt = camp->camera->properties().get(properties::ScalerCropMaximum);
Rectangle sensor_area;
try {
sensor_area = opt.value();
} catch(const std::bad_optional_access& exc) {
set_error("get(ScalerCropMaximum) failed");
return false;
}
Rectangle afwindows_rectangle[1];
afwindows_rectangle[0] = Rectangle (
camp->params->af_window->x * sensor_area.width,
camp->params->af_window->y * sensor_area.height,
camp->params->af_window->width * sensor_area.width,
camp->params->af_window->height * sensor_area.height);
afwindows_rectangle[0].translateBy(sensor_area.topLeft());
//activate the AfMeteringWindows
ctrls.set(controls::AfMetering, controls::AfMeteringWindows);
//set window
ctrls.set(controls::AfWindows, afwindows_rectangle);
}
int res = camp->camera->start(&ctrls);
if (res != 0) {
set_error("Camera.start() failed");

View File

@ -39,7 +39,7 @@ bool parameters_load(parameters_t *params) {
params->ev = atof(getenv("EV"));
if (strlen(getenv("ROI")) != 0) {
bool ok = roi_load(getenv("ROI"), &params->roi);
bool ok = window_load(getenv("ROI"), &params->roi);
if (!ok) {
set_error("invalid ROI");
return false;
@ -85,5 +85,20 @@ bool parameters_load(parameters_t *params) {
params->buffer_count = 6;
params->capture_buffer_count = params->buffer_count * 2;
params->af_mode = getenv("AF_MODE");
params->af_range = getenv("AF_RANGE");
params->af_speed = getenv("AF_SPEED");
params->lens_position = atof(getenv("LENS_POSITION"));
if (strlen(getenv("AF_WINDOW")) != 0) {
bool ok = window_load(getenv("AF_WINDOW"), &params->af_window);
if (!ok) {
set_error("invalid AF_WINDOW");
return false;
}
} else {
params->af_window = NULL;
}
return true;
}

View File

@ -3,7 +3,7 @@
#include <stdbool.h>
#include "roi.h"
#include "window.h"
#include "sensor_mode.h"
typedef struct {
@ -23,7 +23,7 @@ typedef struct {
const char *metering;
float gain;
float ev;
roi_t *roi;
window_t *roi;
const char *tuning_file;
sensor_mode_t *mode;
unsigned int fps;
@ -31,6 +31,11 @@ typedef struct {
unsigned int bitrate;
unsigned int profile;
unsigned int level;
const char *af_mode;
const char *af_range;
const char *af_speed;
float lens_position;
window_t *af_window;
// private
unsigned int buffer_count;

View File

@ -1,9 +1,9 @@
#include <stdlib.h>
#include <string.h>
#include "roi.h"
#include "window.h"
bool roi_load(const char *encoded, roi_t **mode) {
bool window_load(const char *encoded, window_t **mode) {
float vals[4];
int i = 0;
char *token = strtok((char *)encoded, ",");
@ -21,7 +21,7 @@ bool roi_load(const char *encoded, roi_t **mode) {
return false;
}
*mode = malloc(sizeof(roi_t));
*mode = malloc(sizeof(window_t));
(*mode)->x = vals[0];
(*mode)->y = vals[1];
(*mode)->width = vals[2];

View File

@ -1,5 +1,5 @@
#ifndef __ROI_H__
#define __ROI_H__
#ifndef __WINDOW_H__
#define __WINDOW_H__
#include <stdbool.h>
@ -8,8 +8,8 @@ typedef struct {
float y;
float width;
float height;
} roi_t;
} window_t;
bool roi_load(const char *encoded, roi_t **mode);
bool window_load(const char *encoded, window_t **mode);
#endif

View File

@ -2,28 +2,33 @@ package rpicamera
// Params is a set of camera parameters.
type Params struct {
CameraID int
Width int
Height int
HFlip bool
VFlip bool
Brightness float64
Contrast float64
Saturation float64
Sharpness float64
Exposure string
AWB string
Denoise string
Shutter int
Metering string
Gain float64
EV float64
ROI string
TuningFile string
Mode string
FPS int
IDRPeriod int
Bitrate int
Profile string
Level string
CameraID int
Width int
Height int
HFlip bool
VFlip bool
Brightness float64
Contrast float64
Saturation float64
Sharpness float64
Exposure string
AWB string
Denoise string
Shutter int
Metering string
Gain float64
EV float64
ROI string
TuningFile string
Mode string
FPS int
IDRPeriod int
Bitrate int
Profile string
Level string
AfMode string
AfRange string
AfSpeed string
LensPosition float64
AfWindow string
}

View File

@ -145,6 +145,11 @@ func New(
"BITRATE=" + strconv.FormatInt(int64(params.Bitrate), 10),
"PROFILE=" + params.Profile,
"LEVEL=" + params.Level,
"AF_MODE=" + params.AfMode,
"AF_RANGE=" + params.AfRange,
"AF_SPEED=" + params.AfSpeed,
"LENS_POSITION=" + strconv.FormatFloat(params.LensPosition, 'f', -1, 64),
"AF_WINDOW=" + params.AfWindow,
}
exe, err := newEmbeddedExe(exeContent, env)

View File

@ -327,6 +327,24 @@ paths:
rpiCameraProfile: main
# H264 level
rpiCameraLevel: '4.1'
# Autofocus mode
# values: manual, auto, continuous
rpiCameraAfMode: continuous
# Autofocus range
# values: normal, macro, full
rpiCameraAfRange: normal
# Autofocus speed
# values: normal, fast
rpiCameraAfSpeed: normal
# Lens position (for manual autofocus only), will be set to focus to a specific distance
# calculated by the following formula: d = 1 / value
# Examples: 0 moves the lens to infinity.
# 0.5 moves the lens to focus on objects 2m away.
# 2 moves the lens to focus on objects 50cm away.
rpiCameraLensPosition: 0.0
# Specifies the autofocus window, in the form x,y,width,height where the coordinates
# are given as a proportion of the entire image.
rpiCameraAfWindow:
# Username required to publish.
# SHA256-hashed values can be inserted with the "sha256:" prefix.