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

High resolution colour

parent 0fef6ae3
No related branches found
No related tags found
No related merge requests found
Showing
with 269 additions and 188 deletions
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
using ftl::cuda::Mask; using ftl::cuda::Mask;
template <int RADIUS> template <int RADIUS>
__global__ void discontinuity_kernel(ftl::cuda::TextureObject<int> mask_out, ftl::cuda::TextureObject<float> depth, ftl::rgbd::Camera params) { __global__ void discontinuity_kernel(ftl::cuda::TextureObject<int> mask_out, ftl::cuda::TextureObject<float> depth,
const cv::Size size, const double minDepth, const double maxDepth) {
const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x; const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y; const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
if (x < params.width && y < params.height) { if (x < size.width && y < size.height) {
Mask mask(0); Mask mask(0);
const float d = depth.tex2D((int)x, (int)y); const float d = depth.tex2D((int)x, (int)y);
...@@ -17,7 +18,7 @@ __global__ void discontinuity_kernel(ftl::cuda::TextureObject<int> mask_out, ftl ...@@ -17,7 +18,7 @@ __global__ void discontinuity_kernel(ftl::cuda::TextureObject<int> mask_out, ftl
// Calculate depth between 0.0 and 1.0 // Calculate depth between 0.0 and 1.0
//float p = (d - params.minDepth) / (params.maxDepth - params.minDepth); //float p = (d - params.minDepth) / (params.maxDepth - params.minDepth);
if (d >= params.minDepth && d <= params.maxDepth) { if (d >= minDepth && d <= maxDepth) {
/* Orts-Escolano S. et al. 2016. Holoportation: Virtual 3D teleportation in real-time. */ /* Orts-Escolano S. et al. 2016. Holoportation: Virtual 3D teleportation in real-time. */
// Is there a discontinuity nearby? // Is there a discontinuity nearby?
for (int u=-RADIUS; u<=RADIUS; ++u) { for (int u=-RADIUS; u<=RADIUS; ++u) {
...@@ -26,22 +27,25 @@ __global__ void discontinuity_kernel(ftl::cuda::TextureObject<int> mask_out, ftl ...@@ -26,22 +27,25 @@ __global__ void discontinuity_kernel(ftl::cuda::TextureObject<int> mask_out, ftl
if (fabs(depth.tex2D((int)x+u, (int)y+v) - d) > 0.1f) mask.isDiscontinuity(true); if (fabs(depth.tex2D((int)x+u, (int)y+v) - d) > 0.1f) mask.isDiscontinuity(true);
} }
} }
} }
mask_out(x,y) = (int)mask; mask_out(x,y) = (int)mask;
} }
} }
void ftl::cuda::discontinuity(ftl::cuda::TextureObject<int> &mask_out, ftl::cuda::TextureObject<float> &depth, const ftl::rgbd::Camera &params, uint discon, cudaStream_t stream) { void ftl::cuda::discontinuity(ftl::cuda::TextureObject<int> &mask_out, ftl::cuda::TextureObject<float> &depth,
const dim3 gridSize((params.width + T_PER_BLOCK - 1)/T_PER_BLOCK, (params.height + T_PER_BLOCK - 1)/T_PER_BLOCK); const cv::Size size, const double minDepth, const double maxDepth,
uint discon, cudaStream_t stream) {
const dim3 gridSize((size.width + T_PER_BLOCK - 1)/T_PER_BLOCK, (size.height + T_PER_BLOCK - 1)/T_PER_BLOCK);
const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
switch (discon) { switch (discon) {
case 5 : discontinuity_kernel<5><<<gridSize, blockSize, 0, stream>>>(mask_out, depth, params); break; case 5 : discontinuity_kernel<5><<<gridSize, blockSize, 0, stream>>>(mask_out, depth, size, minDepth, maxDepth); break;
case 4 : discontinuity_kernel<4><<<gridSize, blockSize, 0, stream>>>(mask_out, depth, params); break; case 4 : discontinuity_kernel<4><<<gridSize, blockSize, 0, stream>>>(mask_out, depth, size, minDepth, maxDepth); break;
case 3 : discontinuity_kernel<3><<<gridSize, blockSize, 0, stream>>>(mask_out, depth, params); break; case 3 : discontinuity_kernel<3><<<gridSize, blockSize, 0, stream>>>(mask_out, depth, size, minDepth, maxDepth); break;
case 2 : discontinuity_kernel<2><<<gridSize, blockSize, 0, stream>>>(mask_out, depth, params); break; case 2 : discontinuity_kernel<2><<<gridSize, blockSize, 0, stream>>>(mask_out, depth, size, minDepth, maxDepth); break;
case 1 : discontinuity_kernel<1><<<gridSize, blockSize, 0, stream>>>(mask_out, depth, params); break; case 1 : discontinuity_kernel<1><<<gridSize, blockSize, 0, stream>>>(mask_out, depth, size, minDepth, maxDepth); break;
default: break; default: break;
} }
cudaSafeCall( cudaGetLastError() ); cudaSafeCall( cudaGetLastError() );
......
...@@ -10,15 +10,15 @@ namespace ftl { ...@@ -10,15 +10,15 @@ namespace ftl {
namespace cuda { namespace cuda {
struct ILWParams { struct ILWParams {
float spatial_smooth; float spatial_smooth;
float colour_smooth; float colour_smooth;
float fill_match; float fill_match;
float fill_threshold; float fill_threshold;
float match_threshold; float match_threshold;
float cost_ratio; float cost_ratio;
float cost_threshold; float cost_threshold;
float range; float range;
uint flags; uint flags;
}; };
static const uint kILWFlag_IgnoreBad = 0x0001; static const uint kILWFlag_IgnoreBad = 0x0001;
...@@ -29,7 +29,9 @@ static const uint kILWFlag_ColourConfidenceOnly = 0x0008; ...@@ -29,7 +29,9 @@ static const uint kILWFlag_ColourConfidenceOnly = 0x0008;
void discontinuity( void discontinuity(
ftl::cuda::TextureObject<int> &mask_out, ftl::cuda::TextureObject<int> &mask_out,
ftl::cuda::TextureObject<float> &depth, ftl::cuda::TextureObject<float> &depth,
const ftl::rgbd::Camera &params, const cv::Size size,
const double minDepth,
const double maxDepth,
uint discon, cudaStream_t stream uint discon, cudaStream_t stream
); );
...@@ -49,32 +51,32 @@ void preprocess_depth( ...@@ -49,32 +51,32 @@ void preprocess_depth(
); );
void correspondence( void correspondence(
ftl::cuda::TextureObject<float> &d1, ftl::cuda::TextureObject<float> &d1,
ftl::cuda::TextureObject<float> &d2, ftl::cuda::TextureObject<float> &d2,
ftl::cuda::TextureObject<uchar4> &c1, ftl::cuda::TextureObject<uchar4> &c1,
ftl::cuda::TextureObject<uchar4> &c2, ftl::cuda::TextureObject<uchar4> &c2,
ftl::cuda::TextureObject<float> &dout, ftl::cuda::TextureObject<float> &dout,
ftl::cuda::TextureObject<float> &conf, ftl::cuda::TextureObject<float> &conf,
ftl::cuda::TextureObject<int> &mask, ftl::cuda::TextureObject<int> &mask,
float4x4 &pose1, float4x4 &pose1,
float4x4 &pose1_inv, float4x4 &pose1_inv,
float4x4 &pose2, float4x4 &pose2,
const ftl::rgbd::Camera &cam1, const ftl::rgbd::Camera &cam1,
const ftl::rgbd::Camera &cam2, const ftl::rgbd::Camera &cam2,
const ILWParams &params, int win, const ILWParams &params, int win,
cudaStream_t stream cudaStream_t stream
); );
void move_points( void move_points(
ftl::cuda::TextureObject<float> &d_old, ftl::cuda::TextureObject<float> &d_old,
ftl::cuda::TextureObject<float> &d_new, ftl::cuda::TextureObject<float> &d_new,
ftl::cuda::TextureObject<float> &conf, ftl::cuda::TextureObject<float> &conf,
const ftl::rgbd::Camera &camera, const ftl::rgbd::Camera &camera,
const float4x4 &pose, const float4x4 &pose,
const ILWParams &params, const ILWParams &params,
float rate, float rate,
int radius, int radius,
cudaStream_t stream cudaStream_t stream
); );
} }
......
...@@ -82,8 +82,8 @@ static Eigen::Affine3d create_rotation_matrix(float ax, float ay, float az) { ...@@ -82,8 +82,8 @@ static Eigen::Affine3d create_rotation_matrix(float ax, float ay, float az) {
return rz * rx * ry; return rz * rx * ry;
} }
// TODO: * Remove this class (requires more general solution). Also does not // TODO: * Remove this class (requires more general solution). Also does
// process disconnections/reconnections/types etc. correctly. // not process disconnections/reconnections/types etc. correctly.
// * Update when new options become available. // * Update when new options become available.
class ConfigProxy { class ConfigProxy {
...@@ -216,6 +216,7 @@ static void run(ftl::Configurable *root) { ...@@ -216,6 +216,7 @@ static void run(ftl::Configurable *root) {
for (auto &input : sources) { for (auto &input : sources) {
string uri = input->getURI(); string uri = input->getURI();
auto T = transformations.find(uri); auto T = transformations.find(uri);
if (T == transformations.end()) { if (T == transformations.end()) {
LOG(WARNING) << "Camera pose for " + uri + " not found in transformations"; LOG(WARNING) << "Camera pose for " + uri + " not found in transformations";
......
...@@ -60,10 +60,36 @@ Reconstruction::Reconstruction(nlohmann::json &config, const std::string name) : ...@@ -60,10 +60,36 @@ Reconstruction::Reconstruction(nlohmann::json &config, const std::string name) :
ftl::pool.push([this](int id) { ftl::pool.push([this](int id) {
UNIQUE_LOCK(fs_align_.mtx, lk); UNIQUE_LOCK(fs_align_.mtx, lk);
/*rgb_.resize(fs_align_.frames.size());
for (size_t i = 0; i < rgb_.size(); i++) {
auto &depth = fs_align_.frames[i].get<cv::cuda::GpuMat>(ftl::codecs::Channel::Depth);
auto &color = fs_align_.frames[i].get<cv::cuda::GpuMat>(ftl::codecs::Channel::Colour);
if (depth.size() != color.size()) {
std::swap(rgb_[i], color);
cv::cuda::resize(rgb_[i], color, depth.size(), 0.0, 0.0, cv::INTER_LINEAR);
}
}*/
pipeline_->apply(fs_align_, fs_align_, 0); pipeline_->apply(fs_align_, fs_align_, 0);
// TODO: To use second GPU, could do a download, swap, device change, // TODO: To use second GPU, could do a download, swap, device change,
// then upload to other device. Or some direct device-2-device copy. // then upload to other device. Or some direct device-2-device copy.
/*
for (size_t i = 0; i < rgb_.size(); i++) {
auto &depth = fs_align_.frames[i].get<cv::cuda::GpuMat>(ftl::codecs::Channel::Depth);
auto &color = fs_align_.frames[i].get<cv::cuda::GpuMat>(ftl::codecs::Channel::Colour);
auto &tmp = rgb_[i];
// TODO doesn't always work correctly if resolution changes
if (!tmp.empty() && (depth.size() != tmp.size())) {
std::swap(tmp, color);
fs_align_.frames[i].resetTexture(ftl::codecs::Channel::Colour);
fs_align_.frames[i].createTexture<uchar4>(ftl::codecs::Channel::Colour, true);
}
}*/
fs_align_.swapTo(fs_render_); fs_align_.swapTo(fs_render_);
LOG(INFO) << "Align complete... " << fs_align_.timestamp; LOG(INFO) << "Align complete... " << fs_align_.timestamp;
......
...@@ -27,11 +27,14 @@ class Reconstruction : public ftl::Configurable { ...@@ -27,11 +27,14 @@ class Reconstruction : public ftl::Configurable {
private: private:
bool busy_; bool busy_;
ftl::rgbd::FrameSet fs_render_; ftl::rgbd::FrameSet fs_render_;
ftl::rgbd::FrameSet fs_align_; ftl::rgbd::FrameSet fs_align_;
ftl::rgbd::Group *group_; ftl::rgbd::Group *group_;
ftl::operators::Graph *pipeline_; ftl::operators::Graph *pipeline_;
ftl::render::Triangular *renderer_; ftl::render::Triangular *renderer_;
std::vector<cv::cuda::GpuMat> rgb_;
}; };
} }
......
...@@ -49,6 +49,8 @@ enum struct definition_t : uint8_t { ...@@ -49,6 +49,8 @@ enum struct definition_t : uint8_t {
Invalid Invalid
}; };
definition_t findDefinition(int width, int height);
/** /**
* Get width in pixels of definition. * Get width in pixels of definition.
*/ */
...@@ -97,10 +99,8 @@ static const preset_t kPresetMinimum = -1; ...@@ -97,10 +99,8 @@ static const preset_t kPresetMinimum = -1;
* Represents the details of each preset codec configuration. * Represents the details of each preset codec configuration.
*/ */
struct CodecPreset { struct CodecPreset {
definition_t colour_res; definition_t res;
definition_t depth_res; bitrate_t qual;
bitrate_t colour_qual;
bitrate_t depth_qual;
}; };
/** /**
......
...@@ -8,30 +8,31 @@ namespace ftl { ...@@ -8,30 +8,31 @@ namespace ftl {
namespace codecs { namespace codecs {
enum struct Channel : int { enum struct Channel : int {
None = -1, None = -1,
Colour = 0, // 8UC3 or 8UC4 Colour = 0, // 8UC3 or 8UC4
Left = 0, Left = 0,
Depth = 1, // 32S or 32F Depth = 1, // 32S or 32F
Right = 2, // 8UC3 or 8UC4 Right = 2, // 8UC3 or 8UC4
Colour2 = 2, Colour2 = 2,
Disparity = 3, Disparity = 3,
Depth2 = 3, Depth2 = 3,
Deviation = 4, Deviation = 4,
Screen = 4, Screen = 4,
Normals = 5, // 32FC4 Normals = 5, // 32FC4
Points = 6, // 32FC4 (should be deprecated) Points = 6, // 32FC4 (should be deprecated)
Confidence = 7, // 32F Confidence = 7, // 32F
Contribution = 7, // 32F Contribution = 7, // 32F
EnergyVector = 8, // 32FC4 EnergyVector = 8, // 32FC4
Flow = 9, // 32F Flow = 9, // 32F
Smoothing = 9, // 32F Smoothing = 9, // 32F
Energy = 10, // 32F Energy = 10, // 32F
Mask = 11, // 32U Mask = 11, // 32U
Density = 12, // 32F Density = 12, // 32F
Support1 = 13, // 8UC4 (currently) Support1 = 13, // 8UC4 (currently)
Support2 = 14, // 8UC4 (currently) Support2 = 14, // 8UC4 (currently)
Segmentation = 15, // 32S? Segmentation = 15, // 32S?
ColourNormals = 16, // 8UC4 ColourNormals = 16, // 8UC4
ColourHighRes = 20, // 8UC3 or 8UC4
AudioLeft = 32, AudioLeft = 32,
AudioRight = 33, AudioRight = 33,
...@@ -39,7 +40,7 @@ enum struct Channel : int { ...@@ -39,7 +40,7 @@ enum struct Channel : int {
Configuration = 64, // JSON Data Configuration = 64, // JSON Data
Calibration = 65, // Camera Parameters Object Calibration = 65, // Camera Parameters Object
Pose = 66, // Eigen::Matrix4d Pose = 66, // Eigen::Matrix4d
Index = 67, Index = 67,
Data = 2048 // Custom data, any codec. Data = 2048 // Custom data, any codec.
}; };
...@@ -51,7 +52,7 @@ std::string name(Channel c); ...@@ -51,7 +52,7 @@ std::string name(Channel c);
int type(Channel c); int type(Channel c);
class Channels { class Channels {
public: public:
class iterator { class iterator {
public: public:
...@@ -67,48 +68,48 @@ class Channels { ...@@ -67,48 +68,48 @@ class Channels {
unsigned int ix_; unsigned int ix_;
}; };
inline Channels() { mask = 0; } inline Channels() { mask = 0; }
inline explicit Channels(unsigned int m) { mask = m; } inline explicit Channels(unsigned int m) { mask = m; }
inline explicit Channels(Channel c) { mask = (c == Channel::None) ? 0 : 0x1 << static_cast<unsigned int>(c); } inline explicit Channels(Channel c) { mask = (c == Channel::None) ? 0 : 0x1 << static_cast<unsigned int>(c); }
inline Channels &operator=(Channel c) { mask = (c == Channel::None) ? 0 : 0x1 << static_cast<unsigned int>(c); return *this; } inline Channels &operator=(Channel c) { mask = (c == Channel::None) ? 0 : 0x1 << static_cast<unsigned int>(c); return *this; }
inline Channels operator|(Channel c) const { return (c == Channel::None) ? Channels(mask) : Channels(mask | (0x1 << static_cast<unsigned int>(c))); } inline Channels operator|(Channel c) const { return (c == Channel::None) ? Channels(mask) : Channels(mask | (0x1 << static_cast<unsigned int>(c))); }
inline Channels operator+(Channel c) const { return (c == Channel::None) ? Channels(mask) : Channels(mask | (0x1 << static_cast<unsigned int>(c))); } inline Channels operator+(Channel c) const { return (c == Channel::None) ? Channels(mask) : Channels(mask | (0x1 << static_cast<unsigned int>(c))); }
inline Channels &operator|=(Channel c) { mask |= (c == Channel::None) ? 0 : (0x1 << static_cast<unsigned int>(c)); return *this; } inline Channels &operator|=(Channel c) { mask |= (c == Channel::None) ? 0 : (0x1 << static_cast<unsigned int>(c)); return *this; }
inline Channels &operator+=(Channel c) { mask |= (c == Channel::None) ? 0 : (0x1 << static_cast<unsigned int>(c)); return *this; } inline Channels &operator+=(Channel c) { mask |= (c == Channel::None) ? 0 : (0x1 << static_cast<unsigned int>(c)); return *this; }
inline Channels &operator-=(Channel c) { mask &= ~((c == Channel::None) ? 0 : (0x1 << static_cast<unsigned int>(c))); return *this; } inline Channels &operator-=(Channel c) { mask &= ~((c == Channel::None) ? 0 : (0x1 << static_cast<unsigned int>(c))); return *this; }
inline Channels &operator+=(unsigned int c) { mask |= (0x1 << c); return *this; } inline Channels &operator+=(unsigned int c) { mask |= (0x1 << c); return *this; }
inline Channels &operator-=(unsigned int c) { mask &= ~(0x1 << c); return *this; } inline Channels &operator-=(unsigned int c) { mask &= ~(0x1 << c); return *this; }
inline bool has(Channel c) const { inline bool has(Channel c) const {
return (c == Channel::None) ? true : mask & (0x1 << static_cast<unsigned int>(c)); return (c == Channel::None) ? true : mask & (0x1 << static_cast<unsigned int>(c));
} }
inline bool has(unsigned int c) const { inline bool has(unsigned int c) const {
return mask & (0x1 << c); return mask & (0x1 << c);
} }
inline iterator begin() { return iterator(*this, 0); } inline iterator begin() { return iterator(*this, 0); }
inline iterator end() { return iterator(*this, 32); } inline iterator end() { return iterator(*this, 32); }
inline operator unsigned int() { return mask; } inline operator unsigned int() { return mask; }
inline operator bool() { return mask > 0; } inline operator bool() { return mask > 0; }
inline operator Channel() { inline operator Channel() {
if (mask == 0) return Channel::None; if (mask == 0) return Channel::None;
int ix = 0; int ix = 0;
int tmask = mask; int tmask = mask;
while (!(tmask & 0x1) && ++ix < 32) tmask >>= 1; while (!(tmask & 0x1) && ++ix < 32) tmask >>= 1;
return static_cast<Channel>(ix); return static_cast<Channel>(ix);
} }
inline size_t count() { return std::bitset<32>(mask).count(); } inline size_t count() { return std::bitset<32>(mask).count(); }
inline void clear() { mask = 0; } inline void clear() { mask = 0; }
static const size_t kMax = 32; static const size_t kMax = 32;
static Channels All(); static Channels All();
private: private:
unsigned int mask; unsigned int mask;
}; };
inline Channels::iterator Channels::iterator::operator++() { Channels::iterator i = *this; while (++ix_ < 32 && !channels_.has(ix_)); return i; } inline Channels::iterator Channels::iterator::operator++() { Channels::iterator i = *this; while (++ix_ < 32 && !channels_.has(ix_)); return i; }
...@@ -124,9 +125,9 @@ static const Channels kAllChannels(0xFFFFFFFFu); ...@@ -124,9 +125,9 @@ static const Channels kAllChannels(0xFFFFFFFFu);
inline bool isFloatChannel(ftl::codecs::Channel chan) { inline bool isFloatChannel(ftl::codecs::Channel chan) {
switch (chan) { switch (chan) {
case Channel::Depth : case Channel::Depth :
//case Channel::Normals : //case Channel::Normals :
case Channel::Confidence: case Channel::Confidence:
case Channel::Flow : case Channel::Flow :
case Channel::Density: case Channel::Density:
case Channel::Energy : return true; case Channel::Energy : return true;
default : return false; default : return false;
...@@ -139,11 +140,11 @@ inline bool isFloatChannel(ftl::codecs::Channel chan) { ...@@ -139,11 +140,11 @@ inline bool isFloatChannel(ftl::codecs::Channel chan) {
MSGPACK_ADD_ENUM(ftl::codecs::Channel); MSGPACK_ADD_ENUM(ftl::codecs::Channel);
inline ftl::codecs::Channels operator|(ftl::codecs::Channel a, ftl::codecs::Channel b) { inline ftl::codecs::Channels operator|(ftl::codecs::Channel a, ftl::codecs::Channel b) {
return ftl::codecs::Channels(a) | b; return ftl::codecs::Channels(a) | b;
} }
inline ftl::codecs::Channels operator+(ftl::codecs::Channel a, ftl::codecs::Channel b) { inline ftl::codecs::Channels operator+(ftl::codecs::Channel a, ftl::codecs::Channel b) {
return ftl::codecs::Channels(a) | b; return ftl::codecs::Channels(a) | b;
} }
#endif // _FTL_RGBD_CHANNELS_HPP_ #endif // _FTL_RGBD_CHANNELS_HPP_
...@@ -46,16 +46,16 @@ void free(Encoder *&e); ...@@ -46,16 +46,16 @@ void free(Encoder *&e);
* convert an OpenCV Mat or GpuMat into a compressed byte array of some form. * convert an OpenCV Mat or GpuMat into a compressed byte array of some form.
*/ */
class Encoder { class Encoder {
public: public:
friend Encoder *allocateEncoder(ftl::codecs::definition_t, friend Encoder *allocateEncoder(ftl::codecs::definition_t,
ftl::codecs::device_t, ftl::codecs::codec_t); ftl::codecs::device_t, ftl::codecs::codec_t);
friend void free(Encoder *&); friend void free(Encoder *&);
public: public:
Encoder(ftl::codecs::definition_t maxdef, Encoder(ftl::codecs::definition_t maxdef,
ftl::codecs::definition_t mindef, ftl::codecs::definition_t mindef,
ftl::codecs::device_t dev); ftl::codecs::device_t dev);
virtual ~Encoder(); virtual ~Encoder();
/** /**
* Wrapper encode to allow use of presets. * Wrapper encode to allow use of presets.
...@@ -76,21 +76,21 @@ class Encoder { ...@@ -76,21 +76,21 @@ class Encoder {
* @param cb Callback containing compressed data * @param cb Callback containing compressed data
* @return True if succeeded with encoding. * @return True if succeeded with encoding.
*/ */
virtual bool encode( virtual bool encode(
const cv::cuda::GpuMat &in, const cv::cuda::GpuMat &in,
ftl::codecs::definition_t definition, ftl::codecs::definition_t definition,
ftl::codecs::bitrate_t bitrate, ftl::codecs::bitrate_t bitrate,
const std::function<void(const ftl::codecs::Packet&)> &cb)=0; const std::function<void(const ftl::codecs::Packet&)> &cb)=0;
// TODO: Eventually, use GPU memory directly since some encoders can support this // TODO: Eventually, use GPU memory directly since some encoders can support this
//virtual bool encode(const cv::cuda::GpuMat &in, std::vector<uint8_t> &out, bitrate_t bix, bool)=0; //virtual bool encode(const cv::cuda::GpuMat &in, std::vector<uint8_t> &out, bitrate_t bix, bool)=0;
virtual void reset() {} virtual void reset() {}
virtual bool supports(ftl::codecs::codec_t codec)=0; virtual bool supports(ftl::codecs::codec_t codec)=0;
protected: protected:
bool available; bool available;
const ftl::codecs::definition_t max_definition; const ftl::codecs::definition_t max_definition;
const ftl::codecs::definition_t min_definition; const ftl::codecs::definition_t min_definition;
const ftl::codecs::device_t device; const ftl::codecs::device_t device;
......
...@@ -8,20 +8,20 @@ namespace ftl { ...@@ -8,20 +8,20 @@ namespace ftl {
namespace codecs { namespace codecs {
class NvPipeEncoder : public ftl::codecs::Encoder { class NvPipeEncoder : public ftl::codecs::Encoder {
public: public:
NvPipeEncoder(ftl::codecs::definition_t maxdef, NvPipeEncoder(ftl::codecs::definition_t maxdef,
ftl::codecs::definition_t mindef); ftl::codecs::definition_t mindef);
~NvPipeEncoder(); ~NvPipeEncoder();
bool encode(const cv::cuda::GpuMat &in, ftl::codecs::preset_t preset, bool encode(const cv::cuda::GpuMat &in, ftl::codecs::preset_t preset,
const std::function<void(const ftl::codecs::Packet&)> &cb) { const std::function<void(const ftl::codecs::Packet&)> &cb) {
return Encoder::encode(in, preset, cb); return Encoder::encode(in, preset, cb);
} }
bool encode(const cv::cuda::GpuMat &in, ftl::codecs::definition_t definition, ftl::codecs::bitrate_t bitrate, bool encode(const cv::cuda::GpuMat &in, ftl::codecs::definition_t definition, ftl::codecs::bitrate_t bitrate,
const std::function<void(const ftl::codecs::Packet&)>&) override; const std::function<void(const ftl::codecs::Packet&)>&) override;
//bool encode(const cv::cuda::GpuMat &in, std::vector<uint8_t> &out, bitrate_t bix, bool); //bool encode(const cv::cuda::GpuMat &in, std::vector<uint8_t> &out, bitrate_t bix, bool);
void reset(); void reset();
...@@ -29,18 +29,18 @@ class NvPipeEncoder : public ftl::codecs::Encoder { ...@@ -29,18 +29,18 @@ class NvPipeEncoder : public ftl::codecs::Encoder {
static constexpr int kFlagRGB = 0x00000001; static constexpr int kFlagRGB = 0x00000001;
private: private:
NvPipe *nvenc_; NvPipe *nvenc_;
definition_t current_definition_; definition_t current_definition_;
bool is_float_channel_; bool is_float_channel_;
bool was_reset_; bool was_reset_;
ftl::codecs::codec_t preference_; ftl::codecs::codec_t preference_;
cv::cuda::GpuMat tmp_; cv::cuda::GpuMat tmp_;
cv::cuda::GpuMat tmp2_; cv::cuda::GpuMat tmp2_;
cv::cuda::Stream stream_; cv::cuda::Stream stream_;
bool _encoderMatch(const cv::cuda::GpuMat &in, definition_t def); bool _encoderMatch(const cv::cuda::GpuMat &in, definition_t def);
bool _createEncoder(const cv::cuda::GpuMat &in, definition_t def, bitrate_t rate); bool _createEncoder(const cv::cuda::GpuMat &in, definition_t def, bitrate_t rate);
ftl::codecs::definition_t _verifiedDefinition(ftl::codecs::definition_t def, const cv::cuda::GpuMat &in); ftl::codecs::definition_t _verifiedDefinition(ftl::codecs::definition_t def, const cv::cuda::GpuMat &in);
}; };
......
...@@ -8,21 +8,18 @@ using ftl::codecs::preset_t; ...@@ -8,21 +8,18 @@ using ftl::codecs::preset_t;
using ftl::codecs::definition_t; using ftl::codecs::definition_t;
using ftl::codecs::codec_t; using ftl::codecs::codec_t;
static const CodecPreset special_presets[] = { static const CodecPreset special_presets[] = {
definition_t::HTC_VIVE, definition_t::HTC_VIVE, bitrate_t::High, bitrate_t::High definition_t::HTC_VIVE, bitrate_t::High
}; };
static const CodecPreset presets[] = { static const CodecPreset presets[] = {
definition_t::HD1080, definition_t::HD1080, bitrate_t::High, bitrate_t::High, definition_t::HD1080, bitrate_t::High,
definition_t::HD1080, definition_t::HD720, bitrate_t::Standard, bitrate_t::Standard, definition_t::HD720, bitrate_t::High,
definition_t::HD720, definition_t::HD720, bitrate_t::High, bitrate_t::High, definition_t::SD576, bitrate_t::High,
definition_t::HD720, definition_t::SD576, bitrate_t::Standard, bitrate_t::Standard, definition_t::SD480, bitrate_t::High,
definition_t::SD576, definition_t::SD576, bitrate_t::High, bitrate_t::High, definition_t::LD360, bitrate_t::Standard,
definition_t::SD576, definition_t::SD480, bitrate_t::Standard, bitrate_t::Standard, definition_t::LD360, bitrate_t::Low
definition_t::SD480, definition_t::SD480, bitrate_t::High, bitrate_t::High,
definition_t::SD480, definition_t::LD360, bitrate_t::Standard, bitrate_t::Standard,
definition_t::LD360, definition_t::LD360, bitrate_t::Standard, bitrate_t::Standard,
definition_t::LD360, definition_t::LD360, bitrate_t::Low, bitrate_t::Low
}; };
static const float kAspectRatio = 1.777778f; static const float kAspectRatio = 1.777778f;
...@@ -53,11 +50,27 @@ int ftl::codecs::getHeight(definition_t d) { ...@@ -53,11 +50,27 @@ int ftl::codecs::getHeight(definition_t d) {
return resolutions[static_cast<int>(d)].height; return resolutions[static_cast<int>(d)].height;
} }
definition_t ftl::codecs::findDefinition(int width, int height) {
int best = 0;
bool smaller = true;
for(const Resolution res : resolutions) {
if ((res.width == width) && (res.height == height)) {
return static_cast<definition_t>(best);
}
best++;
}
// TODO error!
return definition_t::Any;
}
/*
const CodecPreset &ftl::codecs::getPreset(preset_t p) { const CodecPreset &ftl::codecs::getPreset(preset_t p) {
if (p < 0 && p >= -1) return special_presets[std::abs(p+1)]; if (p < 0 && p >= -1) return special_presets[std::abs(p+1)];
if (p > kPresetWorst) return presets[kPresetWorst]; if (p > kPresetWorst) return presets[kPresetWorst];
if (p < kPresetBest) return presets[kPresetBest]; if (p < kPresetBest) return presets[kPresetBest];
return presets[p]; return presets[p];
} }
preset_t ftl::codecs::findPreset(size_t width, size_t height) { preset_t ftl::codecs::findPreset(size_t width, size_t height) {
...@@ -80,10 +93,11 @@ preset_t ftl::codecs::findPreset(size_t width, size_t height) { ...@@ -80,10 +93,11 @@ preset_t ftl::codecs::findPreset(size_t width, size_t height) {
for (preset_t i=kPresetMinimum; i<=kPresetWorst; ++i) { for (preset_t i=kPresetMinimum; i<=kPresetWorst; ++i) {
const auto &preset = getPreset(i); const auto &preset = getPreset(i);
if ((int)preset.colour_res == best_def && (int)preset.depth_res == best_def) { if ((int)preset.res == best_def) {
return i; return i;
} }
} }
return kPresetWorst; return kPresetWorst;
} }
*/
...@@ -36,7 +36,7 @@ static MUTEX mutex; ...@@ -36,7 +36,7 @@ static MUTEX mutex;
Encoder *ftl::codecs::allocateEncoder(ftl::codecs::definition_t maxdef, Encoder *ftl::codecs::allocateEncoder(ftl::codecs::definition_t maxdef,
ftl::codecs::device_t dev, ftl::codecs::codec_t codec) { ftl::codecs::device_t dev, ftl::codecs::codec_t codec) {
UNIQUE_LOCK(mutex, lk); UNIQUE_LOCK(mutex, lk);
if (!has_been_init) init_encoders(); if (!has_been_init) init_encoders();
for (auto i=encoders.begin(); i!=encoders.end(); ++i) { for (auto i=encoders.begin(); i!=encoders.end(); ++i) {
...@@ -55,10 +55,10 @@ Encoder *ftl::codecs::allocateEncoder(ftl::codecs::definition_t maxdef, ...@@ -55,10 +55,10 @@ Encoder *ftl::codecs::allocateEncoder(ftl::codecs::definition_t maxdef,
} }
void ftl::codecs::free(Encoder *&enc) { void ftl::codecs::free(Encoder *&enc) {
UNIQUE_LOCK(mutex, lk); UNIQUE_LOCK(mutex, lk);
enc->reset(); enc->reset();
enc->available = true; enc->available = true;
enc = nullptr; enc = nullptr;
} }
Encoder::Encoder(definition_t maxdef, definition_t mindef, device_t dev) : Encoder::Encoder(definition_t maxdef, definition_t mindef, device_t dev) :
...@@ -72,9 +72,8 @@ Encoder::~Encoder() { ...@@ -72,9 +72,8 @@ Encoder::~Encoder() {
bool Encoder::encode(const cv::cuda::GpuMat &in, preset_t preset, bool Encoder::encode(const cv::cuda::GpuMat &in, preset_t preset,
const std::function<void(const ftl::codecs::Packet&)> &cb) { const std::function<void(const ftl::codecs::Packet&)> &cb) {
const auto &settings = ftl::codecs::getPreset(preset); const definition_t definition = ftl::codecs::findDefinition(in.size().width, in.size().height);
const definition_t definition = (in.type() == CV_32F) ? settings.depth_res : settings.colour_res; const bitrate_t bitrate = bitrate_t::High;
const bitrate_t bitrate = (in.type() == CV_32F) ? settings.depth_qual : settings.colour_qual;
return encode(in, definition, bitrate, cb); return encode(in, definition, bitrate, cb);
} }
...@@ -18,7 +18,7 @@ bool OpenCVDecoder::accepts(const ftl::codecs::Packet &pkt) { ...@@ -18,7 +18,7 @@ bool OpenCVDecoder::accepts(const ftl::codecs::Packet &pkt) {
} }
bool OpenCVDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out) { bool OpenCVDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out) {
//CHECK(cv::Size(ftl::codecs::getWidth(pkt.definition), ftl::codecs::getHeight(pkt.definition)) == out.size());
int chunk_dim = std::sqrt(pkt.block_total); int chunk_dim = std::sqrt(pkt.block_total);
int chunk_width = out.cols / chunk_dim; int chunk_width = out.cols / chunk_dim;
int chunk_height = out.rows / chunk_dim; int chunk_height = out.rows / chunk_dim;
...@@ -37,7 +37,6 @@ bool OpenCVDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out ...@@ -37,7 +37,6 @@ bool OpenCVDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out
// Apply colour correction to chunk // Apply colour correction to chunk
//ftl::rgbd::colourCorrection(tmp_rgb, gamma_, temperature_); //ftl::rgbd::colourCorrection(tmp_rgb, gamma_, temperature_);
// TODO:(Nick) Decode directly into double buffer if no scaling // TODO:(Nick) Decode directly into double buffer if no scaling
// Can either check JPG/PNG headers or just use pkt definition. // Can either check JPG/PNG headers or just use pkt definition.
......
...@@ -17,7 +17,7 @@ OpenCVEncoder::OpenCVEncoder(ftl::codecs::definition_t maxdef, ...@@ -17,7 +17,7 @@ OpenCVEncoder::OpenCVEncoder(ftl::codecs::definition_t maxdef,
} }
OpenCVEncoder::~OpenCVEncoder() { OpenCVEncoder::~OpenCVEncoder() {
} }
bool OpenCVEncoder::supports(ftl::codecs::codec_t codec) { bool OpenCVEncoder::supports(ftl::codecs::codec_t codec) {
...@@ -30,9 +30,12 @@ bool OpenCVEncoder::supports(ftl::codecs::codec_t codec) { ...@@ -30,9 +30,12 @@ bool OpenCVEncoder::supports(ftl::codecs::codec_t codec) {
bool OpenCVEncoder::encode(const cv::cuda::GpuMat &in, definition_t definition, bitrate_t bitrate, const std::function<void(const ftl::codecs::Packet&)> &cb) { bool OpenCVEncoder::encode(const cv::cuda::GpuMat &in, definition_t definition, bitrate_t bitrate, const std::function<void(const ftl::codecs::Packet&)> &cb) {
bool is_colour = in.type() != CV_32F; bool is_colour = in.type() != CV_32F;
current_definition_ = definition;
// Ensure definition does not exceed max
current_definition_ = ((int)definition < (int)max_definition) ? max_definition : definition;
in.download(tmp_); in.download(tmp_);
//CHECK(cv::Size(ftl::codecs::getWidth(definition), ftl::codecs::getHeight(definition)) == in.size());
// Scale down image to match requested definition... // Scale down image to match requested definition...
if (ftl::codecs::getHeight(current_definition_) < in.rows) { if (ftl::codecs::getHeight(current_definition_) < in.rows) {
...@@ -42,11 +45,12 @@ bool OpenCVEncoder::encode(const cv::cuda::GpuMat &in, definition_t definition, ...@@ -42,11 +45,12 @@ bool OpenCVEncoder::encode(const cv::cuda::GpuMat &in, definition_t definition,
} }
// Represent float at 16bit int // Represent float at 16bit int
if (!is_colour) { if (!is_colour) {
tmp_.convertTo(tmp_, CV_16UC1, 1000); tmp_.convertTo(tmp_, CV_16UC1, 1000);
} }
chunk_dim_ = (definition == definition_t::LD360) ? 1 : 4; // FIXME: Chunking is broken so forced to single chunk
chunk_dim_ = 1; //(definition == definition_t::LD360) ? 1 : 4;
chunk_count_ = chunk_dim_ * chunk_dim_; chunk_count_ = chunk_dim_ * chunk_dim_;
jobs_ = chunk_count_; jobs_ = chunk_count_;
...@@ -94,6 +98,7 @@ bool OpenCVEncoder::_encodeBlock(const cv::Mat &in, ftl::codecs::Packet &pkt, bi ...@@ -94,6 +98,7 @@ bool OpenCVEncoder::_encodeBlock(const cv::Mat &in, ftl::codecs::Packet &pkt, bi
int cx = (pkt.block_number % chunk_dim_) * chunk_width; int cx = (pkt.block_number % chunk_dim_) * chunk_width;
int cy = (pkt.block_number / chunk_dim_) * chunk_height; int cy = (pkt.block_number / chunk_dim_) * chunk_height;
cv::Rect roi(cx,cy,chunk_width,chunk_height); cv::Rect roi(cx,cy,chunk_width,chunk_height);
cv::Mat chunkHead = in(roi); cv::Mat chunkHead = in(roi);
if (pkt.codec == codec_t::PNG) { if (pkt.codec == codec_t::PNG) {
......
...@@ -22,19 +22,18 @@ namespace ftl { ...@@ -22,19 +22,18 @@ namespace ftl {
} }
} }
/*
TEST_CASE( "NvPipeEncoder::encode() - A colour test image at preset 0" ) { TEST_CASE( "NvPipeEncoder::encode() - A colour test image at preset 0" ) {
ftl::codecs::NvPipeEncoder encoder(definition_t::HD1080, definition_t::SD480); ftl::codecs::NvPipeEncoder encoder(definition_t::HD1080, definition_t::SD480);
cv::cuda::GpuMat m(cv::Size(1920,1080), CV_8UC3, cv::Scalar(0,0,0)); cv::cuda::GpuMat m(cv::Size(1920,1080), CV_8UC3, cv::Scalar(0,0,0));
int block_total = 0; int block_total = 0;
std::atomic<int> block_count = 0; std::atomic<int> block_count = 0;
encoder.encode()
const CodecPreset &preset = ftl::codecs::getPreset(ftl::codecs::kPreset0); bool r = encoder.encode(m, definition::H, [&block_total, &block_count, preset, m](const ftl::codecs::Packet &pkt) {
bool r = encoder.encode(m, ftl::codecs::kPreset0, [&block_total, &block_count, preset, m](const ftl::codecs::Packet &pkt) {
REQUIRE( pkt.codec == codec_t::HEVC ); REQUIRE( pkt.codec == codec_t::HEVC );
REQUIRE( pkt.data.size() > 0 ); REQUIRE( pkt.data.size() > 0 );
REQUIRE( pkt.definition == preset.colour_res ); REQUIRE( pkt.definition == definition_t::HD1080 );
block_total = pkt.block_total; block_total = pkt.block_total;
block_count++; block_count++;
...@@ -51,12 +50,10 @@ TEST_CASE( "NvPipeEncoder::encode() - A depth test image at preset 0" ) { ...@@ -51,12 +50,10 @@ TEST_CASE( "NvPipeEncoder::encode() - A depth test image at preset 0" ) {
int block_total = 0; int block_total = 0;
std::atomic<int> block_count = 0; std::atomic<int> block_count = 0;
const CodecPreset &preset = ftl::codecs::getPreset(ftl::codecs::kPreset0);
bool r = encoder.encode(m, ftl::codecs::kPreset0, [&block_total, &block_count, preset](const ftl::codecs::Packet &pkt) { bool r = encoder.encode(m, ftl::codecs::kPreset0, [&block_total, &block_count, preset](const ftl::codecs::Packet &pkt) {
REQUIRE( pkt.codec == codec_t::HEVC ); REQUIRE( pkt.codec == codec_t::HEVC );
REQUIRE( pkt.data.size() > 0 ); REQUIRE( pkt.data.size() > 0 );
REQUIRE( pkt.definition == preset.depth_res ); REQUIRE( pkt.definition == definition_t::HD1080 );
block_total = pkt.block_total; block_total = pkt.block_total;
block_count++; block_count++;
...@@ -65,6 +62,7 @@ TEST_CASE( "NvPipeEncoder::encode() - A depth test image at preset 0" ) { ...@@ -65,6 +62,7 @@ TEST_CASE( "NvPipeEncoder::encode() - A depth test image at preset 0" ) {
REQUIRE( r ); REQUIRE( r );
REQUIRE( block_count == block_total ); REQUIRE( block_count == block_total );
} }
*/
TEST_CASE( "NvPipeDecoder::decode() - A colour test image" ) { TEST_CASE( "NvPipeDecoder::decode() - A colour test image" ) {
ftl::codecs::NvPipeEncoder encoder(definition_t::HD1080, definition_t::SD480); ftl::codecs::NvPipeEncoder encoder(definition_t::HD1080, definition_t::SD480);
......
...@@ -21,15 +21,17 @@ namespace ftl { ...@@ -21,15 +21,17 @@ namespace ftl {
} }
} }
} }
/*
TEST_CASE( "OpenCVEncoder::encode() - A colour test image at preset 0" ) { TEST_CASE( "OpenCVEncoder::encode() - A colour test image at preset 0" ) {
ftl::codecs::OpenCVEncoder encoder(definition_t::HD1080, definition_t::SD480); ftl::codecs::OpenCVEncoder encoder(definition_t::HD1080, definition_t::SD480);
cv::cuda::GpuMat m(cv::Size(1024,576), CV_8UC3, cv::Scalar(0,0,0));
int block_total = 0; int block_total = 0;
std::atomic<int> block_count = 0; std::atomic<int> block_count = 0;
const CodecPreset &preset = ftl::codecs::getPreset(ftl::codecs::kPreset4); const CodecPreset &preset = ftl::codecs::getPreset(ftl::codecs::kPreset4);
cv::cuda::GpuMat m(cv::Size(ftl::codecs::getWidth(preset.res),
ftl::codecs::getHeight(preset.res)),
CV_8UC3, cv::Scalar(0,0,0));
std::mutex mtx; std::mutex mtx;
...@@ -37,7 +39,7 @@ TEST_CASE( "OpenCVEncoder::encode() - A colour test image at preset 0" ) { ...@@ -37,7 +39,7 @@ TEST_CASE( "OpenCVEncoder::encode() - A colour test image at preset 0" ) {
std::unique_lock<std::mutex> lk(mtx); std::unique_lock<std::mutex> lk(mtx);
REQUIRE( pkt.codec == codec_t::JPG ); REQUIRE( pkt.codec == codec_t::JPG );
REQUIRE( pkt.data.size() > 0 ); REQUIRE( pkt.data.size() > 0 );
REQUIRE( pkt.definition == preset.colour_res ); REQUIRE( pkt.definition == preset.res );
block_total = pkt.block_total; block_total = pkt.block_total;
block_count++; block_count++;
...@@ -66,7 +68,7 @@ TEST_CASE( "OpenCVEncoder::encode() - A depth test image at preset 0" ) { ...@@ -66,7 +68,7 @@ TEST_CASE( "OpenCVEncoder::encode() - A depth test image at preset 0" ) {
std::unique_lock<std::mutex> lk(mtx); std::unique_lock<std::mutex> lk(mtx);
REQUIRE( pkt.codec == codec_t::PNG ); REQUIRE( pkt.codec == codec_t::PNG );
REQUIRE( pkt.data.size() > 0 ); REQUIRE( pkt.data.size() > 0 );
REQUIRE( pkt.definition == preset.depth_res ); REQUIRE( pkt.definition == preset.res );
block_total = pkt.block_total; block_total = pkt.block_total;
block_count++; block_count++;
...@@ -78,7 +80,7 @@ TEST_CASE( "OpenCVEncoder::encode() - A depth test image at preset 0" ) { ...@@ -78,7 +80,7 @@ TEST_CASE( "OpenCVEncoder::encode() - A depth test image at preset 0" ) {
REQUIRE( r ); REQUIRE( r );
REQUIRE( block_count == block_total ); REQUIRE( block_count == block_total );
} }
*/
TEST_CASE( "OpenCVDecoder::decode() - A colour test image no resolution change" ) { TEST_CASE( "OpenCVDecoder::decode() - A colour test image no resolution change" ) {
ftl::codecs::OpenCVEncoder encoder(definition_t::HD1080, definition_t::SD480); ftl::codecs::OpenCVEncoder encoder(definition_t::HD1080, definition_t::SD480);
ftl::codecs::OpenCVDecoder decoder; ftl::codecs::OpenCVDecoder decoder;
......
...@@ -14,11 +14,12 @@ ColourChannels::~ColourChannels() { ...@@ -14,11 +14,12 @@ ColourChannels::~ColourChannels() {
bool ColourChannels::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, ftl::rgbd::Source *s, cudaStream_t stream) { bool ColourChannels::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, ftl::rgbd::Source *s, cudaStream_t stream) {
auto cvstream = cv::cuda::StreamAccessor::wrapStream(stream); auto cvstream = cv::cuda::StreamAccessor::wrapStream(stream);
auto &col = in.get<cv::cuda::GpuMat>(Channel::Colour);
// Convert colour from BGR to BGRA if needed // Convert colour from BGR to BGRA if needed
if (in.get<cv::cuda::GpuMat>(Channel::Colour).type() == CV_8UC3) { if (col.type() == CV_8UC3) {
//cv::cuda::Stream cvstream = cv::cuda::StreamAccessor::wrapStream(stream); //cv::cuda::Stream cvstream = cv::cuda::StreamAccessor::wrapStream(stream);
// Convert to 4 channel colour // Convert to 4 channel colour
auto &col = in.get<cv::cuda::GpuMat>(Channel::Colour);
temp_.create(col.size(), CV_8UC4); temp_.create(col.size(), CV_8UC4);
cv::cuda::swap(col, temp_); cv::cuda::swap(col, temp_);
cv::cuda::cvtColor(temp_,col, cv::COLOR_BGR2BGRA, 0, cvstream); cv::cuda::cvtColor(temp_,col, cv::COLOR_BGR2BGRA, 0, cvstream);
...@@ -27,5 +28,13 @@ bool ColourChannels::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, ftl::rgb ...@@ -27,5 +28,13 @@ bool ColourChannels::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, ftl::rgb
//in.resetTexture(Channel::Colour); //in.resetTexture(Channel::Colour);
in.createTexture<uchar4>(Channel::Colour, true); in.createTexture<uchar4>(Channel::Colour, true);
auto &depth = in.get<cv::cuda::GpuMat>(Channel::Depth);
if (depth.size() != col.size()) {
auto &col2 = in.create<cv::cuda::GpuMat>(Channel::ColourHighRes);
cv::cuda::resize(col, col2, depth.size(), 0.0, 0.0, cv::INTER_LINEAR, cvstream);
in.createTexture<uchar4>(Channel::ColourHighRes, true);
in.swapChannels(Channel::Colour, Channel::ColourHighRes);
}
return true; return true;
} }
...@@ -22,7 +22,9 @@ bool DiscontinuityMask::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, ftl:: ...@@ -22,7 +22,9 @@ bool DiscontinuityMask::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, ftl::
out.createTexture<int>(Channel::Mask, ftl::rgbd::Format<int>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())), out.createTexture<int>(Channel::Mask, ftl::rgbd::Format<int>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
in.createTexture<uchar4>(Channel::Support1), in.createTexture<uchar4>(Channel::Support1),
in.createTexture<float>(Channel::Depth), in.createTexture<float>(Channel::Depth),
s->parameters(), radius, threshold, stream in.get<cv::cuda::GpuMat>(Channel::Depth).size(),
s->parameters().minDepth, s->parameters().maxDepth,
radius, threshold, stream
); );
return true; return true;
......
...@@ -4,16 +4,21 @@ ...@@ -4,16 +4,21 @@
using ftl::cuda::Mask; using ftl::cuda::Mask;
__global__ void discontinuity_kernel(ftl::cuda::TextureObject<int> mask_out, ftl::cuda::TextureObject<uchar4> support, ftl::cuda::TextureObject<float> depth, ftl::rgbd::Camera params, float threshold, int radius) { __global__ void discontinuity_kernel(ftl::cuda::TextureObject<int> mask_out,
ftl::cuda::TextureObject<uchar4> support,
ftl::cuda::TextureObject<float> depth,
const cv::Size size, const double minDepth, const double maxDepth,
float threshold, int radius) {
const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x; const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y; const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
if (x < params.width && y < params.height) { if (x < size.width && y < size.height) {
Mask mask(0); Mask mask(0);
const float d = depth.tex2D((int)x, (int)y); const float d = depth.tex2D((int)x, (int)y);
if (d >= params.minDepth && d <= params.maxDepth) { if (d >= minDepth && d <= maxDepth) {
/* Orts-Escolano S. et al. 2016. Holoportation: Virtual 3D teleportation in real-time. */ /* Orts-Escolano S. et al. 2016. Holoportation: Virtual 3D teleportation in real-time. */
// If colour cross support region terminates within the requested // If colour cross support region terminates within the requested
...@@ -37,17 +42,21 @@ __global__ void discontinuity_kernel(ftl::cuda::TextureObject<int> mask_out, ftl ...@@ -37,17 +42,21 @@ __global__ void discontinuity_kernel(ftl::cuda::TextureObject<int> mask_out, ftl
float dS = depth.tex2D((int)x, (int)y + sup.w + radius); float dS = depth.tex2D((int)x, (int)y + sup.w + radius);
if (fabs(dS - d) > threshold) mask.isDiscontinuity(true); if (fabs(dS - d) > threshold) mask.isDiscontinuity(true);
} }
} }
mask_out(x,y) = (int)mask; mask_out(x,y) = (int)mask;
} }
} }
void ftl::cuda::discontinuity(ftl::cuda::TextureObject<int> &mask_out, ftl::cuda::TextureObject<uchar4> &support, ftl::cuda::TextureObject<float> &depth, const ftl::rgbd::Camera &params, int discon, float thresh, cudaStream_t stream) { void ftl::cuda::discontinuity( ftl::cuda::TextureObject<int> &mask_out, ftl::cuda::TextureObject<uchar4> &support,
const dim3 gridSize((params.width + T_PER_BLOCK - 1)/T_PER_BLOCK, (params.height + T_PER_BLOCK - 1)/T_PER_BLOCK); ftl::cuda::TextureObject<float> &depth,
const cv::Size size, const double minDepth, const double maxDepth,
int discon, float thresh, cudaStream_t stream) {
const dim3 gridSize((size.width + T_PER_BLOCK - 1)/T_PER_BLOCK, (size.height + T_PER_BLOCK - 1)/T_PER_BLOCK);
const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
discontinuity_kernel<<<gridSize, blockSize, 0, stream>>>(mask_out, support, depth, params, thresh, discon); discontinuity_kernel<<<gridSize, blockSize, 0, stream>>>(mask_out, support, depth, size, minDepth, maxDepth, thresh, discon);
cudaSafeCall( cudaGetLastError() ); cudaSafeCall( cudaGetLastError() );
#ifdef _DEBUG #ifdef _DEBUG
...@@ -55,8 +64,6 @@ void ftl::cuda::discontinuity(ftl::cuda::TextureObject<int> &mask_out, ftl::cuda ...@@ -55,8 +64,6 @@ void ftl::cuda::discontinuity(ftl::cuda::TextureObject<int> &mask_out, ftl::cuda
#endif #endif
} }
__global__ void cull_discontinuity_kernel(ftl::cuda::TextureObject<int> mask, ftl::cuda::TextureObject<float> depth) { __global__ void cull_discontinuity_kernel(ftl::cuda::TextureObject<int> mask, ftl::cuda::TextureObject<float> depth) {
const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x; const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y; const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
...@@ -71,7 +78,7 @@ void ftl::cuda::cull_discontinuity(ftl::cuda::TextureObject<int> &mask, ftl::cud ...@@ -71,7 +78,7 @@ void ftl::cuda::cull_discontinuity(ftl::cuda::TextureObject<int> &mask, ftl::cud
const dim3 gridSize((depth.width() + T_PER_BLOCK - 1)/T_PER_BLOCK, (depth.height() + T_PER_BLOCK - 1)/T_PER_BLOCK); const dim3 gridSize((depth.width() + T_PER_BLOCK - 1)/T_PER_BLOCK, (depth.height() + T_PER_BLOCK - 1)/T_PER_BLOCK);
const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK); const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
cull_discontinuity_kernel<<<gridSize, blockSize, 0, stream>>>(mask, depth); cull_discontinuity_kernel<<<gridSize, blockSize, 0, stream>>>(mask, depth);
cudaSafeCall( cudaGetLastError() ); cudaSafeCall( cudaGetLastError() );
#ifdef _DEBUG #ifdef _DEBUG
......
...@@ -19,7 +19,7 @@ class Mask { ...@@ -19,7 +19,7 @@ class Mask {
#endif #endif
__device__ inline operator int() const { return v_; } __device__ inline operator int() const { return v_; }
__device__ inline bool is(int m) const { return v_ & m; } __device__ inline bool is(int m) const { return v_ & m; }
__device__ inline bool isFilled() const { return v_ & kMask_Filled; } __device__ inline bool isFilled() const { return v_ & kMask_Filled; }
__device__ inline bool isDiscontinuity() const { return v_ & kMask_Discontinuity; } __device__ inline bool isDiscontinuity() const { return v_ & kMask_Discontinuity; }
...@@ -31,7 +31,7 @@ class Mask { ...@@ -31,7 +31,7 @@ class Mask {
__device__ inline void hasCorrespondence(bool v) { v_ = (v) ? v_ | kMask_Correspondence : v_ & (~kMask_Correspondence); } __device__ inline void hasCorrespondence(bool v) { v_ = (v) ? v_ | kMask_Correspondence : v_ & (~kMask_Correspondence); }
__device__ inline void isBad(bool v) { v_ = (v) ? v_ | kMask_Bad : v_ & (~kMask_Bad); } __device__ inline void isBad(bool v) { v_ = (v) ? v_ | kMask_Bad : v_ & (~kMask_Bad); }
static constexpr int kMask_Filled = 0x0001; static constexpr int kMask_Filled = 0x0001;
static constexpr int kMask_Discontinuity = 0x0002; static constexpr int kMask_Discontinuity = 0x0002;
static constexpr int kMask_Correspondence = 0x0004; static constexpr int kMask_Correspondence = 0x0004;
static constexpr int kMask_Bad = 0x0008; static constexpr int kMask_Bad = 0x0008;
...@@ -44,7 +44,9 @@ void discontinuity( ...@@ -44,7 +44,9 @@ void discontinuity(
ftl::cuda::TextureObject<int> &mask, ftl::cuda::TextureObject<int> &mask,
ftl::cuda::TextureObject<uchar4> &support, ftl::cuda::TextureObject<uchar4> &support,
ftl::cuda::TextureObject<float> &depth, ftl::cuda::TextureObject<float> &depth,
const ftl::rgbd::Camera &params, const cv::Size size,
const double minDepth,
const double maxDepth,
int radius, float threshold, int radius, float threshold,
cudaStream_t stream); cudaStream_t stream);
......
...@@ -94,7 +94,10 @@ __global__ void reprojection_kernel( ...@@ -94,7 +94,10 @@ __global__ void reprojection_kernel(
const float dotproduct = (max(dot(ray,n),-0.1f)+0.1) / 1.1f; const float dotproduct = (max(dot(ray,n),-0.1f)+0.1) / 1.1f;
const float d2 = depth_src.tex2D(int(screenPos.x+0.5f), int(screenPos.y+0.5f)); const float d2 = depth_src.tex2D(int(screenPos.x+0.5f), int(screenPos.y+0.5f));
const auto input = in.tex2D(screenPos.x, screenPos.y); //generateInput(in.tex2D((int)screenPos.x, (int)screenPos.y), params, worldPos);
const float inSX = float(in.width()) / float(depth_src.width());
const float inSY = float(in.height()) / float(depth_src.height());
const auto input = in.tex2D(screenPos.x*inSX, screenPos.y*inSY); //generateInput(in.tex2D((int)screenPos.x, (int)screenPos.y), params, worldPos);
// TODO: Z checks need to interpolate between neighbors if large triangles are used // TODO: Z checks need to interpolate between neighbors if large triangles are used
//float weight = ftl::cuda::weighting(fabs(camPos.z - d2), params.depthThreshold); //float weight = ftl::cuda::weighting(fabs(camPos.z - d2), params.depthThreshold);
...@@ -213,7 +216,11 @@ __global__ void reprojection_kernel( ...@@ -213,7 +216,11 @@ __global__ void reprojection_kernel(
if (screenPos.x >= depth_src.width() || screenPos.y >= depth_src.height()) return; if (screenPos.x >= depth_src.width() || screenPos.y >= depth_src.height()) return;
const float d2 = depth_src.tex2D((int)(screenPos.x+0.5f), (int)(screenPos.y+0.5f)); const float d2 = depth_src.tex2D((int)(screenPos.x+0.5f), (int)(screenPos.y+0.5f));
const auto input = in.tex2D(screenPos.x, screenPos.y); //generateInput(in.tex2D((int)screenPos.x, (int)screenPos.y), params, worldPos);
const float inSX = float(in.width()) / float(depth_src.width());
const float inSY = float(in.height()) / float(depth_src.height());
const auto input = in.tex2D(screenPos.x*inSX, screenPos.y*inSY); //generateInput(in.tex2D((int)screenPos.x, (int)screenPos.y), params, worldPos);
float weight = ftl::cuda::weighting(fabs(camPos.z - d2), 0.02f); float weight = ftl::cuda::weighting(fabs(camPos.z - d2), 0.02f);
const B weighted = make<B>(input) * weight; const B weighted = make<B>(input) * weight;
......
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