summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/py/libcamera/meson.build1
-rw-r--r--src/py/libcamera/pygeometry.cpp119
-rw-r--r--src/py/libcamera/pymain.cpp2
3 files changed, 122 insertions, 0 deletions
diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build
index 427716d7..de66bb48 100644
--- a/src/py/libcamera/meson.build
+++ b/src/py/libcamera/meson.build
@@ -14,6 +14,7 @@ pybind11_dep = pybind11_proj.get_variable('pybind11_dep')
pycamera_sources = files([
'pyenums.cpp',
+ 'pygeometry.cpp',
'pymain.cpp',
])
diff --git a/src/py/libcamera/pygeometry.cpp b/src/py/libcamera/pygeometry.cpp
new file mode 100644
index 00000000..d77de144
--- /dev/null
+++ b/src/py/libcamera/pygeometry.cpp
@@ -0,0 +1,119 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
+ *
+ * Python bindings - Geometry classes
+ */
+
+#include <array>
+
+#include <libcamera/geometry.h>
+#include <libcamera/libcamera.h>
+
+#include <pybind11/operators.h>
+#include <pybind11/smart_holder.h>
+#include <pybind11/stl.h>
+
+namespace py = pybind11;
+
+using namespace libcamera;
+
+void init_pygeometry(py::module &m)
+{
+ auto pyPoint = py::class_<Point>(m, "Point");
+ auto pySize = py::class_<Size>(m, "Size");
+ auto pySizeRange = py::class_<SizeRange>(m, "SizeRange");
+ auto pyRectangle = py::class_<Rectangle>(m, "Rectangle");
+
+ pyPoint
+ .def(py::init<>())
+ .def(py::init<int, int>())
+ .def_readwrite("x", &Point::x)
+ .def_readwrite("y", &Point::y)
+ .def(py::self == py::self)
+ .def(-py::self)
+ .def("__str__", &Point::toString)
+ .def("__repr__", [](const Point &self) {
+ return py::str("libcamera.Point({}, {})")
+ .format(self.x, self.y);
+ });
+
+ pySize
+ .def(py::init<>())
+ .def(py::init<unsigned int, unsigned int>())
+ .def_readwrite("width", &Size::width)
+ .def_readwrite("height", &Size::height)
+ .def_property_readonly("is_null", &Size::isNull)
+ .def("align_down_to", &Size::alignDownTo)
+ .def("align_up_to", &Size::alignUpTo)
+ .def("bound_to", &Size::boundTo)
+ .def("expand_to", &Size::expandTo)
+ .def("grow_by", &Size::growBy)
+ .def("shrink_by", &Size::shrinkBy)
+ .def("aligned_up_to", &Size::alignedUpTo)
+ .def("aligned_up_to", &Size::alignedUpTo)
+ .def("bounded_to", &Size::boundedTo)
+ .def("expanded_to", &Size::expandedTo)
+ .def("grown_by", &Size::grownBy)
+ .def("shrunk_by", &Size::shrunkBy)
+ .def("bounded_to_aspect_ratio", &Size::boundedToAspectRatio)
+ .def("expanded_to_aspect_ratio", &Size::expandedToAspectRatio)
+ .def("centered_to", &Size::centeredTo)
+ .def(py::self == py::self)
+ .def(py::self < py::self)
+ .def(py::self <= py::self)
+ .def(py::self * float())
+ .def(py::self / float())
+ .def(py::self *= float())
+ .def(py::self /= float())
+ .def("__str__", &Size::toString)
+ .def("__repr__", [](const Size &self) {
+ return py::str("libcamera.Size({}, {})")
+ .format(self.width, self.height);
+ });
+
+ pySizeRange
+ .def(py::init<>())
+ .def(py::init<Size>())
+ .def(py::init<Size, Size>())
+ .def(py::init<Size, Size, unsigned int, unsigned int>())
+ .def_readwrite("min", &SizeRange::min)
+ .def_readwrite("max", &SizeRange::max)
+ .def_readwrite("hStep", &SizeRange::hStep)
+ .def_readwrite("vStep", &SizeRange::vStep)
+ .def("contains", &SizeRange::contains)
+ .def(py::self == py::self)
+ .def("__str__", &SizeRange::toString)
+ .def("__repr__", [](const SizeRange &self) {
+ return py::str("libcamera.SizeRange(({}, {}), ({}, {}), {}, {})")
+ .format(self.min.width, self.min.height,
+ self.max.width, self.max.height,
+ self.hStep, self.vStep);
+ });
+
+ pyRectangle
+ .def(py::init<>())
+ .def(py::init<int, int, Size>())
+ .def(py::init<int, int, unsigned int, unsigned int>())
+ .def(py::init<Size>())
+ .def_readwrite("x", &Rectangle::x)
+ .def_readwrite("y", &Rectangle::y)
+ .def_readwrite("width", &Rectangle::width)
+ .def_readwrite("height", &Rectangle::height)
+ .def_property_readonly("is_null", &Rectangle::isNull)
+ .def_property_readonly("center", &Rectangle::center)
+ .def_property_readonly("size", &Rectangle::size)
+ .def_property_readonly("topLeft", &Rectangle::topLeft)
+ .def("scale_by", &Rectangle::scaleBy)
+ .def("translate_by", &Rectangle::translateBy)
+ .def("bounded_to", &Rectangle::boundedTo)
+ .def("enclosed_in", &Rectangle::enclosedIn)
+ .def("scaled_by", &Rectangle::scaledBy)
+ .def("translated_by", &Rectangle::translatedBy)
+ .def(py::self == py::self)
+ .def("__str__", &Rectangle::toString)
+ .def("__repr__", [](const Rectangle &self) {
+ return py::str("libcamera.Rectangle({}, {}, {}, {})")
+ .format(self.x, self.y, self.width, self.height);
+ });
+}
diff --git a/src/py/libcamera/pymain.cpp b/src/py/libcamera/pymain.cpp
index 97b05903..96333ebc 100644
--- a/src/py/libcamera/pymain.cpp
+++ b/src/py/libcamera/pymain.cpp
@@ -137,11 +137,13 @@ static void handleRequestCompleted(Request *req)
void init_pyenums(py::module &m);
void init_pyenums_generated(py::module &m);
+void init_pygeometry(py::module &m);
PYBIND11_MODULE(_libcamera, m)
{
init_pyenums(m);
init_pyenums_generated(m);
+ init_pygeometry(m);
/* Forward declarations */
hl kwb">double coarse_step; // how far to wander off CT curve towards "more purple" double transverse_pos; // how far to wander off CT curve towards "more green" double transverse_neg; // red sensitivity ratio (set to canonical sensor's R/G divided by this // sensor's R/G) double sensitivity_r; // blue sensitivity ratio (set to canonical sensor's B/G divided by this // sensor's B/G) double sensitivity_b; // The whitepoint (which we normally "aim" for) can be moved. double whitepoint_r; double whitepoint_b; bool bayes; // use Bayesian algorithm }; class Awb : public AwbAlgorithm { public: Awb(Controller *controller = NULL); ~Awb(); char const *Name() const override; void Initialise() override; void Read(boost::property_tree::ptree const &params) override; void SetMode(std::string const &name) override; void SetManualGains(double manual_r, double manual_b) override; void Prepare(Metadata *image_metadata) override; void Process(StatisticsPtr &stats, Metadata *image_metadata) override; struct RGB { RGB(double _R = INVALID, double _G = INVALID, double _B = INVALID) : R(_R), G(_G), B(_B) { } double R, G, B; static const double INVALID; bool Valid() const { return G != INVALID; } bool Invalid() const { return G == INVALID; } RGB &operator+=(RGB const &other) { R += other.R, G += other.G, B += other.B; return *this; } RGB Square() const { return RGB(R * R, G * G, B * B); } }; private: // configuration is read-only, and available to both threads AwbConfig config_; std::thread async_thread_; void asyncFunc(); // asynchronous thread function std::mutex mutex_; // condvar for async thread to wait on std::condition_variable async_signal_; // condvar for synchronous thread to wait on std::condition_variable sync_signal_; // for sync thread to check if async thread finished (requires mutex) bool async_finished_; // for async thread to check if it's been told to run (requires mutex) bool async_start_; // for async thread to check if it's been told to quit (requires mutex) bool async_abort_; // The following are only for the synchronous thread to use: // for sync thread to note its has asked async thread to run bool async_started_; // counts up to frame_period before restarting the async thread int frame_phase_; int frame_count_; // counts up to startup_frames int frame_count2_; // counts up to startup_frames for Process method AwbStatus sync_results_; AwbStatus prev_sync_results_; std::string mode_name_; std::mutex settings_mutex_; // The following are for the asynchronous thread to use, though the main // thread can set/reset them if the async thread is known to be idle: void restartAsync(StatisticsPtr &stats, std::string const &mode_name, double lux); // copy out the results from the async thread so that it can be restarted void fetchAsyncResults(); StatisticsPtr statistics_; AwbMode *mode_; double lux_; AwbStatus async_results_; void doAwb(); void awbBayes(); void awbGrey(); void prepareStats(); double computeDelta2Sum(double gain_r, double gain_b); Pwl interpolatePrior(); double coarseSearch(Pwl const &prior); void fineSearch(double &t, double &r, double &b, Pwl const &prior); std::vector<RGB> zones_; std::vector<Pwl::Point> points_; // manual r setting double manual_r_; // manual b setting double manual_b_; }; static inline Awb::RGB operator+(Awb::RGB const &a, Awb::RGB const &b) { return Awb::RGB(a.R + b.R, a.G + b.G, a.B + b.B); } static inline Awb::RGB operator-(Awb::RGB const &a, Awb::RGB const &b) { return Awb::RGB(a.R - b.R, a.G - b.G, a.B - b.B); } static inline Awb::RGB operator*(double d, Awb::RGB const &rgb) { return Awb::RGB(d * rgb.R, d * rgb.G, d * rgb.B); } static inline Awb::RGB operator*(Awb::RGB const &rgb, double d) { return d * rgb; } } // namespace RPi