Skip to content
Snippets Groups Projects
Commit 642beec2 authored by Nicolas Pope's avatar Nicolas Pope
Browse files

Add colour correction to net sources

parent db689c78
No related branches found
No related tags found
1 merge request!46Implements #41 colour correction
Pipeline #11772 passed
...@@ -6,6 +6,7 @@ set(RGBDSRC ...@@ -6,6 +6,7 @@ set(RGBDSRC
src/stereovideo.cpp src/stereovideo.cpp
src/net.cpp src/net.cpp
src/streamer.cpp src/streamer.cpp
src/colour.cpp
# src/algorithms/rtcensus.cpp # src/algorithms/rtcensus.cpp
# src/algorithms/rtcensus_sgm.cpp # src/algorithms/rtcensus_sgm.cpp
# src/algorithms/opencv_sgbm.cpp # src/algorithms/opencv_sgbm.cpp
......
#include "colour.hpp"
#include <vector>
#include <tuple>
using std::vector;
static void gammaCorrection(const cv::Mat &img, const double gamma_){
using namespace cv;
Mat lookUpTable(1, 256, CV_8U);
uchar* p = lookUpTable.ptr();
for( int i = 0; i < 256; ++i)
p[i] = saturate_cast<uchar>(pow(i / 255.0, gamma_) * 255.0);
Mat res = img.clone();
LUT(img, lookUpTable, img);
}
static const std::vector<std::tuple<uchar,uchar,uchar>> kelvin_table = {
{255,56,0}, // 1000
{255,109,0}, // 1500
{255,137,18}, // 2000
{255,161,72}, // 2500
{255,180,107}, // 3000
{255,196,137}, // 3500
{255,209,163}, // 4000
{255,219,186}, // 4500
{255,228,206}, // 5000
{255,236,224}, // 5500
{255,243,239}, // 6000
{255,249,253}, // 6500
{245,243,255}, // 7000
{235,238,255}, // 7500
{227,233,255}, // 8000
{220,229,255}, // 8500
{214,225,255}, // 9000
{208,222,255}, // 9500
{204,219,255}}; // 10000
template <int C>
inline float kelvinFactor(int temp) {
int index = (temp / 500) - 2;
if (index >= kelvin_table.size()) index = kelvin_table.size();
else if (index < 0) index = 0;
return (float)std::get<C>(kelvin_table[index]) / 255.0f;
}
void ftl::rgbd::colourCorrection(cv::Mat &img, float gamma, int temp) {
using namespace cv;
Mat lutRed(1, 256, CV_8U);
Mat lutGreen(1, 256, CV_8U);
Mat lutBlue(1, 256, CV_8U);
// TODO(Nick): Cache these lookup tables if used every frame...
uchar* pr = lutRed.ptr();
uchar* pg = lutGreen.ptr();
uchar* pb = lutBlue.ptr();
for( int i = 0; i < 256; ++i) {
float g = pow(i / 255.0f, gamma) * 255.0f;
pr[i] = saturate_cast<uchar>(g * kelvinFactor<2>(temp));
pg[i] = saturate_cast<uchar>(g * kelvinFactor<1>(temp));
pb[i] = saturate_cast<uchar>(g * kelvinFactor<0>(temp));
}
vector<Mat> channels(3);
split(img, channels);
LUT(channels[0], lutBlue, channels[0]);
LUT(channels[1], lutGreen, channels[1]);
LUT(channels[2], lutRed, channels[2]);
merge(channels, img);
}
#ifndef _FTL_RGBD_COLOUR_HPP_
#define _FTL_RGBD_COLOUR_HPP_
#include <opencv2/opencv.hpp>
namespace ftl {
namespace rgbd {
void colourCorrection(cv::Mat &img, float gamma, int temp);
// void colourCorrection(cv::GpuMat &img, float gamma, int temp);
}
}
#endif // _FTL_RGBD_COLOUR_HPP_
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include <chrono> #include <chrono>
#include <shared_mutex> #include <shared_mutex>
#include "colour.hpp"
#include <ftl/rgbd/streamer.hpp> #include <ftl/rgbd/streamer.hpp>
using ftl::rgbd::detail::NetSource; using ftl::rgbd::detail::NetSource;
...@@ -46,6 +48,9 @@ bool NetSource::_getCalibration(Universe &net, const UUID &peer, const string &s ...@@ -46,6 +48,9 @@ bool NetSource::_getCalibration(Universe &net, const UUID &peer, const string &s
NetSource::NetSource(ftl::rgbd::Source *host) NetSource::NetSource(ftl::rgbd::Source *host)
: ftl::rgbd::detail::Source(host), active_(false) { : ftl::rgbd::detail::Source(host), active_(false) {
gamma_ = host->value("gamma", 1.0f);
temperature_ = host->value("temperature", 6500);
_updateURI(); _updateURI();
h_ = host_->getNet()->onConnect([this](ftl::net::Peer *p) { h_ = host_->getNet()->onConnect([this](ftl::net::Peer *p) {
...@@ -90,6 +95,9 @@ void NetSource::_recvChunk(int frame, int chunk, bool delta, const vector<unsign ...@@ -90,6 +95,9 @@ void NetSource::_recvChunk(int frame, int chunk, bool delta, const vector<unsign
cv::imdecode(jpg, cv::IMREAD_COLOR, &tmp_rgb); cv::imdecode(jpg, cv::IMREAD_COLOR, &tmp_rgb);
cv::imdecode(d, cv::IMREAD_UNCHANGED, &tmp_depth); cv::imdecode(d, cv::IMREAD_UNCHANGED, &tmp_depth);
// Apply colour correction to chunk
ftl::rgbd::colourCorrection(tmp_rgb, gamma_, temperature_);
// Build chunk head // Build chunk head
int cx = (chunk % chunks_dim_) * chunk_width_; int cx = (chunk % chunks_dim_) * chunk_width_;
int cy = (chunk / chunks_dim_) * chunk_height_; int cy = (chunk / chunks_dim_) * chunk_height_;
......
...@@ -41,6 +41,8 @@ class NetSource : public detail::Source { ...@@ -41,6 +41,8 @@ class NetSource : public detail::Source {
int chunk_width_; int chunk_width_;
int chunk_height_; int chunk_height_;
cv::Mat idepth_; cv::Mat idepth_;
float gamma_;
int temperature_;
bool _getCalibration(ftl::net::Universe &net, const ftl::UUID &peer, const std::string &src, ftl::rgbd::Camera &p); bool _getCalibration(ftl::net::Universe &net, const ftl::UUID &peer, const std::string &src, ftl::rgbd::Camera &p);
void _recv(const std::vector<unsigned char> &jpg, const std::vector<unsigned char> &d); void _recv(const std::vector<unsigned char> &jpg, const std::vector<unsigned char> &d);
......
#include "snapshot_source.hpp" #include "snapshot_source.hpp"
#include "colour.hpp"
#include <loguru.hpp> #include <loguru.hpp>
#include <opencv2/opencv.hpp> #include <opencv2/opencv.hpp>
...@@ -12,78 +13,11 @@ using ftl::rgbd::detail::SnapshotSource; ...@@ -12,78 +13,11 @@ using ftl::rgbd::detail::SnapshotSource;
using std::string; using std::string;
using std::vector; using std::vector;
static void gammaCorrection(const cv::Mat &img, const double gamma_){
using namespace cv;
Mat lookUpTable(1, 256, CV_8U);
uchar* p = lookUpTable.ptr();
for( int i = 0; i < 256; ++i)
p[i] = saturate_cast<uchar>(pow(i / 255.0, gamma_) * 255.0);
Mat res = img.clone();
LUT(img, lookUpTable, img);
}
static const std::vector<std::tuple<uchar,uchar,uchar>> kelvin_table = {
{255,56,0}, // 1000
{255,109,0}, // 1500
{255,137,18}, // 2000
{255,161,72}, // 2500
{255,180,107}, // 3000
{255,196,137}, // 3500
{255,209,163}, // 4000
{255,219,186}, // 4500
{255,228,206}, // 5000
{255,236,224}, // 5500
{255,243,239}, // 6000
{255,249,253}, // 6500
{245,243,255}, // 7000
{235,238,255}, // 7500
{227,233,255}, // 8000
{220,229,255}, // 8500
{214,225,255}, // 9000
{208,222,255}, // 9500
{204,219,255}}; // 10000
template <int C>
inline float kelvinFactor(int temp) {
int index = (temp / 500) - 2;
if (index >= kelvin_table.size()) index = kelvin_table.size();
else if (index < 0) index = 0;
return (float)std::get<C>(kelvin_table[index]) / 255.0f;
}
static void colourCorrection(cv::Mat &img, float gamma, int temp) {
using namespace cv;
Mat lutRed(1, 256, CV_8U);
Mat lutGreen(1, 256, CV_8U);
Mat lutBlue(1, 256, CV_8U);
// TODO(Nick): Cache these lookup tables if used every frame...
uchar* pr = lutRed.ptr();
uchar* pg = lutGreen.ptr();
uchar* pb = lutBlue.ptr();
for( int i = 0; i < 256; ++i) {
float g = pow(i / 255.0f, gamma) * 255.0f;
pr[i] = saturate_cast<uchar>(g * kelvinFactor<2>(temp));
pg[i] = saturate_cast<uchar>(g * kelvinFactor<1>(temp));
pb[i] = saturate_cast<uchar>(g * kelvinFactor<0>(temp));
}
vector<Mat> channels(3);
split(img, channels);
LUT(channels[0], lutBlue, channels[0]);
LUT(channels[1], lutGreen, channels[1]);
LUT(channels[2], lutRed, channels[2]);
merge(channels, img);
}
SnapshotSource::SnapshotSource(ftl::rgbd::Source *host, SnapshotReader &reader, const string &id) : detail::Source(host) { SnapshotSource::SnapshotSource(ftl::rgbd::Source *host, SnapshotReader &reader, const string &id) : detail::Source(host) {
Eigen::Matrix4d pose; Eigen::Matrix4d pose;
reader.getCameraRGBD(id, rgb_, depth_, pose, params_); reader.getCameraRGBD(id, rgb_, depth_, pose, params_);
colourCorrection(rgb_, host->value("gamma", 2.2f), host->value("temperature", 6500)); ftl::rgbd::colourCorrection(rgb_, host->value("gamma", 1.0f), host->value("temperature", 6500));
setPose(pose); setPose(pose);
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment