summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--facetracknoir/gain-control.hpp198
1 files changed, 0 insertions, 198 deletions
diff --git a/facetracknoir/gain-control.hpp b/facetracknoir/gain-control.hpp
deleted file mode 100644
index 081d4b6f..00000000
--- a/facetracknoir/gain-control.hpp
+++ /dev/null
@@ -1,198 +0,0 @@
-#pragma once
-
-/* still WIP, not usable yet! -sh 20141012 */
-
-#include <algorithm>
-#undef NDEBUG
-#include <cassert>
-#include <iterator>
-#include <tuple>
-#include <deque>
-#include <vector>
-
-#include <cstdio>
-
-#include "timer.hpp"
-
-#include <opencv2/core/core.hpp>
-#include <opencv2/highgui/highgui.hpp>
-#include <opencv2/imgproc/imgproc.hpp>
-
-#include <QDebug>
-
-namespace detail {
- template<typename t1, typename t2, typename t, typename m = t>
- class zip_iterator : public std::iterator<std::forward_iterator_tag, t>
- {
- private:
- using self = zip_iterator<t1, t2, t, m>;
- t1 x1, z1;
- t2 x2, z2;
- void maybe_end() { if (x1 == z1 || x2 == z2) *this = end(); }
- public:
- zip_iterator(const t1& it1, const t1& end1, const t2& it2, const t2& end2)
- : x1(it1), z1(end1), x2(it2), z2(end2) { maybe_end(); }
- constexpr zip_iterator() {}
-
- static constexpr self end() { return self(); }
-
- self operator++() { x1++; x2++; self tmp = *this; maybe_end(); return tmp; }
- self operator++(int) { self tmp(*this); x1++; x2++; maybe_end(); return tmp; }
- bool operator==(const self& rhs) const { return x1 == rhs.x1 && x2 == rhs.x2; }
- bool operator!=(const self& rhs) const { return !this->operator ==(rhs); }
- t operator*() { return m(*x1, *x2); }
- };
-}
-
-class Gain {
-private:
- static constexpr bool use_box_filter = true;
- static constexpr int box_size = 16 / 640.;
- static constexpr double control_upper_bound = 1.0; // XXX FIXME implement for logitech crapola
- static constexpr int GAIN_HISTORY_COUNT = 50, GAIN_HISTORY_EVERY_MS = 998;
-
- using t_frame = cv::Mat_<unsigned char>;
-
- int control;
- double step, eps;
-
- t_frame last_frame;
- std::deque<double> means_history;
- Timer debug_timer, history_timer;
-
- typedef unsigned char px;
- template<typename t1, typename t2, typename t, typename m = t>
- using zip_iterator = detail::zip_iterator<t1, t2, t, m>;
-
- static double mean(const cv::Mat& frame)
- {
- // grayscale only
- assert(frame.channels() == 1);
- assert(frame.elemSize() == 1);
- assert(!frame.empty());
-
- return std::accumulate(frame.begin<px>(), frame.end<px>(), 0.) / (frame.rows * frame.cols);
- }
-
- static double get_variance(const cv::Mat& frame, double mean)
- {
- struct variance {
- private:
- double mu;
- public:
- variance(double mu) : mu(mu) {}
- double operator()(double seed, px p)
- {
- double tmp = p - mu;
- return seed + tmp * tmp;
- }
- } logic(mean);
-
- return std::accumulate(frame.begin<unsigned char>(), frame.end<unsigned char>(), 0., logic) / (frame.rows * frame.cols);
- }
-
- static double get_covariance(const cv::Mat& frame, const cv::Mat& old_frame)
- {
- double mean_0 = mean(frame), mean_1 = mean(old_frame);
-
- struct covariance {
- public:
- using pair = std::tuple<px, px>;
- private:
- double mu_0, mu_1;
-
- inline double Cov(double seed, const pair& t)
- {
- px p0 = std::get<0>(t);
- px p1 = std::get<1>(t);
- return seed + (p0 - mu_0) * (p1 - mu_1);
- }
- public:
- covariance(double mu_0, double mu_1) : mu_0(mu_0), mu_1(mu_1) {}
-
- double operator()(double seed, const pair& t)
- {
- return Cov(seed, t);
- }
- } logic(mean_0, mean_1);
-
- const double N = frame.rows * frame.cols;
-
- using zipper = zip_iterator<cv::MatConstIterator_<px>,
- cv::MatConstIterator_<px>,
- std::tuple<px, px>>;
-
- zipper zip(frame.begin<px>(),
- frame.end<px>(),
- old_frame.begin<px>(),
- old_frame.end<px>());
- std::vector<covariance::pair> values(zip, zipper::end());
-
- return std::accumulate(values.begin(), values.end(), 0., logic) / N;
- }
-
-#pragma GCC diagnostic ignored "-Wsign-compare"
-
-public:
- Gain(int control = CV_CAP_PROP_GAIN, double step = 0.3, double eps = 0.02) :
- control(control), step(step), eps(eps)
- {
- }
-
- void tick(cv::VideoCapture&, const cv::Mat& frame_)
- {
- cv::Mat frame;
-
- if (use_box_filter)
- {
- cv::Mat tmp(frame_);
- static constexpr int min_box = 3;
- static constexpr int box = 2 * box_size;
- cv::blur(frame_, tmp, cv::Size(min_box + box * frame_.cols, min_box + box * frame_.rows));
- frame = tmp;
- }
- else
- frame = frame_;
-
- if (last_frame.rows != frame.rows || last_frame.cols != frame.cols)
- last_frame = t_frame();
-
- if (last_frame.empty())
- {
- last_frame = frame.clone();
- //return;
- }
-
- if (history_timer.elapsed_ms() > GAIN_HISTORY_EVERY_MS)
- {
- //const double cov = get_covariance(frame, last_frame);
- history_timer.start();
- last_frame = frame.clone();
-
- if (means_history.size() == GAIN_HISTORY_COUNT)
- means_history.pop_back();
- }
-
- if (debug_timer.elapsed_ms() > 1000)
- {
- const double mu = mean(frame);
- // XXX move to HSL/HSV color space for it to work! -sh 20141012
- const double var = get_variance(frame, mu);
-
- debug_timer.start();
- qDebug() << "---- gain:" << "mean" << mu << "variance" << var;
-
- const int sz = means_history.size();
-
- if (sz)
- {
- fprintf(stderr, "covs{%d}: ", sz);
-
- for (int i = 0; i < sz; i++)
- fprintf(stderr, "%f ", means_history[i]);
-
- fprintf(stderr, "\n");
- }
- }
- }
-};