Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • bug/335/nettimeadjust
  • bug/feedrecord
  • bug/mlsdestruct2
  • bug/optflow-disparity
  • calibration
  • censuseval
  • cherry-pick-75b9f6b3
  • chromatest
  • enhancement/235
  • exp/327/colourcor
  • exp/candidatemask
  • exp/labcolours
  • exp/multires-sgm
  • exp/triangleperf-2
  • exp/triangleperf3
  • feature/134/usegroup-nb
  • feature/231/segment
  • feature/274/lossyfilter
  • feature/329/dualoptflow-doffs
  • feature/330/audiocompress
  • feature/375/fullres-fstream
  • feature/SKR
  • feature/aruco
  • feature/autocalibration
  • feature/ceres
  • feature/compiletime
  • feature/corr_smooth
  • feature/depth-touch
  • feature/disconflow
  • feature/fixedres
  • feature/gui2-nanogui-mitsuba
  • feature/gui2-pch
  • feature/multiplexer-pose
  • feature/poses
  • feature/python
  • feature/sdk-python
  • feature/sgm-experimental
  • feature/stereocalib
  • feature/use-new-frame
  • feature/use10bit
  • feature/vr
  • feature/warpcorr-costing
  • feature/web-service/camMover
  • feature/web-service/configurations
  • feature/web-service/vanillaClient
  • feature/websocket-pose
  • guirefactor
  • master
  • v0.0.1
  • v0.0.2
  • v0.0.3
  • v0.0.4
  • v0.0.5
  • v0.0.6
54 results

Target

Select target project
  • nicolaspope/ftl
1 result
Select Git revision
  • bug/335/nettimeadjust
  • bug/feedrecord
  • bug/mlsdestruct2
  • bug/optflow-disparity
  • calibration
  • censuseval
  • cherry-pick-75b9f6b3
  • chromatest
  • enhancement/235
  • exp/327/colourcor
  • exp/candidatemask
  • exp/labcolours
  • exp/multires-sgm
  • exp/triangleperf-2
  • exp/triangleperf3
  • feature/134/usegroup-nb
  • feature/231/segment
  • feature/274/lossyfilter
  • feature/329/dualoptflow-doffs
  • feature/330/audiocompress
  • feature/375/fullres-fstream
  • feature/SKR
  • feature/aruco
  • feature/autocalibration
  • feature/ceres
  • feature/compiletime
  • feature/corr_smooth
  • feature/depth-touch
  • feature/disconflow
  • feature/fixedres
  • feature/gui2-nanogui-mitsuba
  • feature/gui2-pch
  • feature/multiplexer-pose
  • feature/poses
  • feature/python
  • feature/sdk-python
  • feature/sgm-experimental
  • feature/stereocalib
  • feature/use-new-frame
  • feature/use10bit
  • feature/vr
  • feature/warpcorr-costing
  • feature/web-service/camMover
  • feature/web-service/configurations
  • feature/web-service/vanillaClient
  • feature/websocket-pose
  • guirefactor
  • master
  • v0.0.1
  • v0.0.2
  • v0.0.3
  • v0.0.4
  • v0.0.5
  • v0.0.6
54 results
Show changes
Showing
with 3678 additions and 135 deletions
......@@ -8,11 +8,12 @@ using ftl::operators::Graph;
using ftl::rgbd::Frame;
using ftl::rgbd::FrameSet;
using ftl::rgbd::Source;
using ftl::codecs::Channel;
Operator::Operator(ftl::Configurable *config) : config_(config) {
Operator::Operator(ftl::operators::Graph *g, ftl::Configurable *config) : config_(config), graph_(g) {
enabled_ = config_->value("enabled", true);
config_->on("enabled", [this](const ftl::config::Event &e) {
config_->on("enabled", [this]() {
enabled_ = config_->value("enabled", true);
});
}
......@@ -34,24 +35,83 @@ bool Operator::apply(FrameSet &in, Frame &out, cudaStream_t stream) {
Graph::Graph(nlohmann::json &config) : ftl::Configurable(config) {
cudaSafeCall( cudaStreamCreate(&stream_) );
busy_.clear();
}
Graph::~Graph() {
cudaStreamDestroy(stream_);
// Cleanup configurables
for (auto &c : configs_) {
delete c.second;
}
for (auto &o : operators_) {
for (auto *i : o.instances) {
delete i;
}
}
}
cv::cuda::GpuMat &Graph::createBuffer(ftl::operators::Buffer b, uint32_t fid) {
if (fid > 32) throw FTL_Error("Too many frames for buffer");
auto &v = buffers_[(uint32_t(b) << 8) + fid];
valid_buffers_.insert((uint32_t(b) << 8) + fid);
return v;
}
cv::cuda::GpuMat &Graph::getBuffer(ftl::operators::Buffer b, uint32_t fid) {
if (fid > 32) throw FTL_Error("Too many frames for buffer");
if (!hasBuffer(b, fid)) throw FTL_Error("Buffer does not exist: " << int(b));
auto &v = buffers_.at((uint32_t(b) << 8) + fid);
return v;
}
bool Graph::hasBuffer(ftl::operators::Buffer b, uint32_t fid) const {
return valid_buffers_.count((uint32_t(b) << 8) + fid) > 0;
}
bool Graph::queue(const ftl::data::FrameSetPtr &fs, const std::function<void()> &cb) {
if (!value("enabled", true)) return true;
if (fs->frames.size() < 1) return true;
{
UNIQUE_LOCK(mtx_, lk);
if (queue_.size() > 3) {
LOG(ERROR) << "Pipeline queue exceeded";
return false;
}
queue_.emplace_back(fs, cb);
}
if (busy_.test_and_set()) {
LOG(INFO) << "Pipeline queued... " << queue_.size();
return true;
}
_processOne();
return true;
}
bool Graph::apply(ftl::rgbd::FrameSet &in, ftl::rgbd::FrameSet &out) {
if (!value("enabled", true)) return true;
if (in.frames.size() < 1) return true;
bool Graph::apply(FrameSet &in, FrameSet &out, cudaStream_t stream) {
if (!value("enabled", true)) return false;
return _apply(in, out);
}
auto stream_actual = (stream == 0) ? stream_ : stream;
bool Graph::_apply(ftl::rgbd::FrameSet &in, ftl::rgbd::FrameSet &out) {
auto stream_actual = in.frames[0].stream();
bool success = true;
if (in.frames.size() != out.frames.size()) return false;
valid_buffers_.clear();
for (auto &f : out.frames) {
if (!f.hasOwn(Channel::Pipelines)) f.create<std::list<std::string>>(Channel::Pipelines);
auto pls = f.set<std::list<std::string>>(Channel::Pipelines);
pls = getID();
}
for (auto &i : operators_) {
if (i.instances.size() < 1) {
i.instances.push_back(i.maker->make());
i.instances.push_back(i.maker->make(this));
}
if (i.instances[0]->type() == Operator::Type::OneToOne) {
......@@ -60,20 +120,22 @@ bool Graph::apply(FrameSet &in, FrameSet &out, cudaStream_t stream) {
//i.instances.push_back(i.maker->make());
//}
if (in.frames.size() > 1 && i.instances.size() < 2 && !i.instances[0]->isMemoryHeavy()) {
i.instances.push_back(i.maker->make());
i.instances.push_back(i.maker->make(this));
}
for (size_t j=0; j<in.frames.size(); ++j) {
if (!in.hasFrame(j)) continue;
if (!in.hasFrame(j)) in.frames[j].message(ftl::data::Message::Warning_INCOMPLETE_FRAME, "Frame not complete in Pipeline");
int iix = (i.instances[0]->isMemoryHeavy()) ? 0 : j&0x1;
auto *instance = i.instances[iix];
if (instance->enabled()) {
try {
instance->apply(in.frames[j], out.frames[j], stream_actual);
instance->apply(in.frames[j].cast<ftl::rgbd::Frame>(), out.frames[j].cast<ftl::rgbd::Frame>(), stream_actual);
//cudaSafeCall(cudaStreamSynchronize(stream_actual));
} catch (const std::exception &e) {
LOG(ERROR) << "Operator exception for '" << instance->config()->getID() << "': " << e.what();
in.frames[j].message(ftl::data::Message::Error_OPERATOR_EXCEPTION, "Operator exception");
success = false;
break;
}
......@@ -86,8 +148,10 @@ bool Graph::apply(FrameSet &in, FrameSet &out, cudaStream_t stream) {
if (instance->enabled()) {
try {
instance->apply(in, out, stream_actual);
//cudaSafeCall(cudaStreamSynchronize(stream_actual));
} catch (const std::exception &e) {
LOG(ERROR) << "Operator exception for '" << instance->config()->getID() << "': " << e.what();
if (in.frames.size() > 0) in.frames[0].message(ftl::data::Message::Error_OPERATOR_EXCEPTION, "Operator exception");
success = false;
break;
}
......@@ -96,12 +160,51 @@ bool Graph::apply(FrameSet &in, FrameSet &out, cudaStream_t stream) {
}
success = waitAll(stream_actual) && success;
return success;
}
void Graph::_processOne() {
if (stream == 0) {
cudaSafeCall(cudaStreamSynchronize(stream_actual));
ftl::data::FrameSetPtr fs;
std::function<void()> cb;
{
UNIQUE_LOCK(mtx_, lk);
if(queue_.size() == 0) {
busy_.clear();
return;
}
return success;
fs = queue_.front().first;
cb = queue_.front().second;
queue_.pop_front();
}
auto &in = *fs;
auto &out = *fs;
auto stream_actual = in.frames[0].stream();
_apply(in, out);
if (cb) {
cudaCallback(stream_actual, [this,cb]() {
bool sched = false;
{
UNIQUE_LOCK(mtx_, lk);
if (queue_.size() == 0) busy_.clear();
else sched = true;
}
ftl::pool.push([this,cb,sched](int id) {
if (sched) _processOne();
cb();
});
});
} else {
busy_.clear();
}
return;
}
bool Graph::waitAll(cudaStream_t stream) {
......@@ -118,16 +221,28 @@ bool Graph::waitAll(cudaStream_t stream) {
return true;
}
bool Graph::apply(Frame &in, Frame &out, cudaStream_t stream) {
if (!value("enabled", true)) return false;
bool Graph::apply(Frame &in, Frame &out, const std::function<void()> &cb) {
if (!value("enabled", true)) return true;
auto stream_actual = (stream == 0) ? stream_ : stream;
auto stream_actual = in.stream();
bool success = true;
if (busy_.test_and_set()) {
LOG(ERROR) << "Pipeline already in use: " << in.timestamp();
//if (cb) cb();
return false;
}
valid_buffers_.clear();
if (!out.hasOwn(Channel::Pipelines)) out.create<std::list<std::string>>(Channel::Pipelines);
auto pls = out.set<std::list<std::string>>(Channel::Pipelines);
pls = getID();
for (auto &i : operators_) {
// Make sure there are enough instances
if (i.instances.size() < 1) {
i.instances.push_back(i.maker->make());
i.instances.push_back(i.maker->make(this));
}
auto *instance = i.instances[0];
......@@ -135,9 +250,11 @@ bool Graph::apply(Frame &in, Frame &out, cudaStream_t stream) {
if (instance->enabled()) {
try {
instance->apply(in, out, stream_actual);
//cudaSafeCall(cudaStreamSynchronize(stream_actual));
} catch (const std::exception &e) {
LOG(ERROR) << "Operator exception for '" << instance->config()->getID() << "': " << e.what();
success = false;
out.message(ftl::data::Message::Error_OPERATOR_EXCEPTION, "Operator exception");
break;
}
}
......@@ -145,11 +262,18 @@ bool Graph::apply(Frame &in, Frame &out, cudaStream_t stream) {
success = waitAll(stream_actual) && success;
if (stream == 0) {
cudaSafeCall(cudaStreamSynchronize(stream_actual));
if (cb) {
cudaCallback(stream_actual, [this,cb]() {
busy_.clear();
ftl::pool.push([cb](int id) { cb(); });
});
} else {
//cudaSafeCall(cudaStreamSynchronize(stream_actual));
busy_.clear();
}
return success;
//busy_.clear();
return true;
}
ftl::Configurable *Graph::_append(ftl::operators::detail::ConstructionHelperBase *m) {
......
......@@ -8,9 +8,11 @@ using ftl::codecs::Channel;
using ftl::codecs::Shape3DType;
using std::string;
static SHARED_MUTEX smtx;
std::unordered_map<std::string,ftl::operators::Poser::PoseState> Poser::pose_db__;
std::unordered_map<int,std::list<ftl::codecs::Shape3D*>> Poser::fs_shapes__;
Poser::Poser(ftl::Configurable *cfg) : ftl::operators::Operator(cfg) {
Poser::Poser(ftl::operators::Graph *g, ftl::Configurable *cfg) : ftl::operators::Operator(g, cfg) {
}
......@@ -18,36 +20,48 @@ Poser::~Poser() {
}
void Poser::add(const ftl::codecs::Shape3D &t, int frameset, int frame) {
void Poser::add(const ftl::codecs::Shape3D &t, ftl::data::FrameID id) {
std::string idstr;
switch(t.type) {
case Shape3DType::ARUCO : idstr = "aruco-"; break;
case Shape3DType::CAMERA : idstr = "camera-"; break;
case Shape3DType::CURSOR : idstr = "cursor-"; break;
default : idstr = "unk-"; break;
}
idstr += std::to_string(frameset) + string("-") + std::to_string(frame) + string("-") + std::to_string(t.id);
idstr += std::to_string(id.frameset()) + string("-") + std::to_string(id.source()) + string("-") + std::to_string(t.id);
auto pose = t.pose.cast<double>(); // f.getPose() *
//auto pose = t.pose.cast<double>(); // f.getPose() *
UNIQUE_LOCK(smtx, lk);
auto p = pose_db__.find(idstr);
if (p == pose_db__.end()) {
ftl::operators::Poser::PoseState ps;
ps.pose = pose;
ps.shape = t;
ps.locked = false;
pose_db__.emplace(std::make_pair(idstr,ps));
LOG(INFO) << "POSE ID: " << idstr;
fs_shapes__[id.frameset()].push_back(&pose_db__[idstr].shape);
} else {
// TODO: Merge poses
if (!(*p).second.locked) (*p).second.pose = pose;
if (!(*p).second.locked) (*p).second.shape = t;
//LOG(INFO) << "POSE ID: " << idstr;
}
}
std::list<ftl::codecs::Shape3D*> Poser::getAll(int32_t fsid) {
SHARED_LOCK(smtx, lk);
if (fs_shapes__.count(fsid)) {
return fs_shapes__[fsid];
}
return {};
}
bool Poser::get(const std::string &name, Eigen::Matrix4d &pose) {
SHARED_LOCK(smtx, lk);
auto p = pose_db__.find(name);
if (p != pose_db__.end()) {
pose = (*p).second.pose;
pose = (*p).second.shape.pose.cast<double>();
return true;
} else {
LOG(WARNING) << "Pose not found: " << name;
......@@ -55,58 +69,59 @@ bool Poser::get(const std::string &name, Eigen::Matrix4d &pose) {
}
}
bool Poser::set(const std::string &name, const Eigen::Matrix4d &pose) {
auto p = pose_db__.find(name);
if (p == pose_db__.end()) {
ftl::operators::Poser::PoseState ps;
ps.pose = pose;
ps.locked = false;
pose_db__.emplace(std::make_pair(name,ps));
LOG(INFO) << "POSE ID: " << name;
} else {
// TODO: Merge poses
if (!(*p).second.locked) (*p).second.pose = pose;
//LOG(INFO) << "POSE ID: " << idstr;
}
return true;
}
bool Poser::apply(ftl::rgbd::FrameSet &in, ftl::rgbd::FrameSet &out, cudaStream_t stream) {
if (in.hasChannel(Channel::Shapes3D)) {
std::vector<ftl::codecs::Shape3D> transforms;
in.get(Channel::Shapes3D, transforms);
const auto &transforms = in.get<std::list<ftl::codecs::Shape3D>>(Channel::Shapes3D);
//LOG(INFO) << "Found shapes 3D global: " << (int)transforms.size();
for (auto &t : transforms) {
// LOG(INFO) << "Have FS transform: " << t.label;
add(t, in.id, 255);
add(t, in.id());
}
}
for (size_t i=0; i<in.frames.size(); ++i) {
if (in.hasFrame(i)) {
auto &f = in.frames[i];
//if (in.hasFrame(i)) {
auto &f = in.frames[i].cast<ftl::rgbd::Frame>();
if (f.hasChannel(Channel::Shapes3D)) {
std::vector<ftl::codecs::Shape3D> transforms;
f.get(Channel::Shapes3D, transforms);
const auto &transforms = f.get<std::list<ftl::codecs::Shape3D>>(Channel::Shapes3D);
//LOG(INFO) << "Found shapes 3D: " << (int)transforms.size();
for (auto &t : transforms) {
add(t, in.id, i);
add(t, f.id());
}
}
if (f.hasChannel(Channel::Pose)) {
ftl::codecs::Shape3D cam;
cam.id = 0;
cam.label = f.name();
cam.pose = f.getPose().cast<float>();
cam.type = ftl::codecs::Shape3DType::CAMERA;
add(cam, f.id());
}
//}
}
SHARED_LOCK(smtx, lk);
string pose_ident = config()->value("pose_ident",string("default"));
if (pose_ident != "default") {
auto p = pose_db__.find(pose_ident);
if (p != pose_db__.end()) {
(*p).second.locked = config()->value("locked",false);
in.pose = (*p).second.pose;
Eigen::Matrix4d pose = (*p).second.shape.pose.cast<double>();
if (in.frames.size() == 1) {
auto response = in.frames[0].response();
auto &rgbdf = response.cast<ftl::rgbd::Frame>();
rgbdf.setPose() = (config()->value("inverse",false)) ? pose.inverse() : pose;
} else {
in.cast<ftl::rgbd::Frame>().setPose() = (config()->value("inverse",false)) ? pose.inverse() : pose;
}
} else {
LOG(WARNING) << "Pose not found: " << pose_ident;
}
......@@ -114,3 +129,25 @@ bool Poser::apply(ftl::rgbd::FrameSet &in, ftl::rgbd::FrameSet &out, cudaStream_
return true;
}
bool Poser::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t stream) {
auto &f = in;
if (f.hasChannel(Channel::Shapes3D)) {
const auto &transforms = f.get<std::list<ftl::codecs::Shape3D>>(Channel::Shapes3D);
for (auto &t : transforms) {
add(t, f.id());
}
}
if (f.hasChannel(Channel::Pose)) {
ftl::codecs::Shape3D cam;
cam.id = 0;
cam.label = f.name();
cam.pose = f.getPose().cast<float>();
cam.type = ftl::codecs::Shape3DType::CAMERA;
add(cam, f.id());
}
return true;
}
\ No newline at end of file
#include <ftl/operators/segmentation.hpp>
#include "segmentation_cuda.hpp"
#include <opencv2/cudawarping.hpp>
#include <loguru.hpp>
using ftl::operators::CrossSupport;
using ftl::operators::VisCrossSupport;
using ftl::codecs::Channel;
using cv::cuda::GpuMat;
CrossSupport::CrossSupport(ftl::Configurable *cfg) : ftl::operators::Operator(cfg) {
CrossSupport::CrossSupport(ftl::operators::Graph *g, ftl::Configurable *cfg) : ftl::operators::Operator(g, cfg) {
}
......@@ -16,20 +20,48 @@ CrossSupport::~CrossSupport() {
bool CrossSupport::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t stream) {
bool use_mask = config()->value("discon_support", false);
if (!in.hasChannel(Channel::Colour)) {
out.message(ftl::data::Message::Warning_MISSING_CHANNEL, "Missing Colour channel in Support operator");
return false;
}
auto cvstream = cv::cuda::StreamAccessor::wrapStream(stream);
const auto &intrin = in.getLeft();
cv::Size size(intrin.width, intrin.height);
const GpuMat &rgb = in.get<GpuMat>(Channel::Colour);
if (rgb.empty()) return false;
GpuMat rgb_buf;
if (rgb.size() != size) {
if (graph()->hasBuffer(Buffer::LowLeft, in.source())) {
rgb_buf = graph()->getBuffer(Buffer::LowLeft, in.source());
} else {
auto &t = graph()->createBuffer(Buffer::LowLeft, in.source());
cv::cuda::resize(rgb, t, size, 0, 0, cv::INTER_LINEAR, cvstream);
rgb_buf = t;
}
} else {
rgb_buf = rgb;
}
if (use_mask && !in.hasChannel(Channel::Support2)) {
if (!in.hasChannel(Channel::Mask)) return false;
if (!in.hasChannel(Channel::Mask)) {
out.message(ftl::data::Message::Warning_MISSING_CHANNEL, "Missing Mask channel in Support operator");
return false;
}
ftl::cuda::support_region(
in.createTexture<uint8_t>(Channel::Mask),
out.createTexture<uchar4>(Channel::Support2, ftl::rgbd::Format<uchar4>(in.get<cv::cuda::GpuMat>(Channel::Colour).size())),
out.createTexture<uchar4>(Channel::Support2, ftl::rgbd::Format<uchar4>(rgb_buf.size())),
config()->value("v_max", 5),
config()->value("h_max", 5),
config()->value("symmetric", false), stream
);
} else if (!in.hasChannel(Channel::Support1)) {
ftl::cuda::support_region(
in.createTexture<uchar4>(Channel::Colour),
out.createTexture<uchar4>(Channel::Support1, ftl::rgbd::Format<uchar4>(in.get<cv::cuda::GpuMat>(Channel::Colour).size())),
rgb_buf,
out.createTexture<uchar4>(Channel::Support1, ftl::rgbd::Format<uchar4>(rgb_buf.size())),
config()->value("tau", 10.0f),
config()->value("v_max", 5),
config()->value("h_max", 5),
......@@ -43,7 +75,7 @@ bool CrossSupport::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream
VisCrossSupport::VisCrossSupport(ftl::Configurable *cfg) : ftl::operators::Operator(cfg) {
VisCrossSupport::VisCrossSupport(ftl::operators::Graph *g, ftl::Configurable *cfg) : ftl::operators::Operator(g, cfg) {
}
......
......@@ -25,20 +25,20 @@ __device__ inline float cross<float>(float p1, float p2) {
}
template <typename T, bool SYM>
__device__ uchar4 calculate_support_region(const TextureObject<T> &img, int x, int y, float tau, int v_max, int h_max) {
__device__ uchar4 calculate_support_region(const T* __restrict__ img, int width, int height, int pitch, int x, int y, float tau, int v_max, int h_max) {
int x_min = max(0, x - h_max);
int x_max = min(img.width()-1, static_cast<unsigned int>(x + h_max));
int x_max = min(width-1, static_cast<unsigned int>(x + h_max));
int y_min = max(0, y - v_max);
int y_max = min(img.height()-1, static_cast<unsigned int>(y + v_max));
int y_max = min(height-1, static_cast<unsigned int>(y + v_max));
uchar4 result = make_uchar4(0, 0, 0, 0);
auto colour = img.tex2D((float)x+0.5f,(float)y+0.5f);
auto colour = img[x+y*pitch];
auto prev_colour = colour;
int u;
for (u=x-1; u >= x_min; --u) {
auto next_colour = img.tex2D((float)u+0.5f,(float)y+0.5f);
auto next_colour = img[u+y*pitch];
if (cross(prev_colour, next_colour) > tau) {
result.x = x - u - 1;
break;
......@@ -49,7 +49,7 @@ __device__ uchar4 calculate_support_region(const TextureObject<T> &img, int x, i
prev_colour = colour;
for (u=x+1; u <= x_max; ++u) {
auto next_colour = img.tex2D((float)u+0.5f,(float)y+0.5f);
auto next_colour = img[u+y*pitch];
if (cross(prev_colour, next_colour) > tau) {
result.y = u - x - 1;
break;
......@@ -61,7 +61,7 @@ __device__ uchar4 calculate_support_region(const TextureObject<T> &img, int x, i
int v;
prev_colour = colour;
for (v=y-1; v >= y_min; --v) {
auto next_colour = img.tex2D((float)x+0.5f,(float)v+0.5f);
auto next_colour = img[x+v*pitch];
if (cross(prev_colour, next_colour) > tau) {
result.z = y - v - 1;
break;
......@@ -72,7 +72,7 @@ __device__ uchar4 calculate_support_region(const TextureObject<T> &img, int x, i
prev_colour = colour;
for (v=y+1; v <= y_max; ++v) {
auto next_colour = img.tex2D((float)x+0.5f,(float)v+0.5f);
auto next_colour = img[x+v*pitch];
if (cross(prev_colour, next_colour) > tau) {
result.w = v - y - 1;
break;
......@@ -91,19 +91,19 @@ __device__ uchar4 calculate_support_region(const TextureObject<T> &img, int x, i
return result;
}
__device__ uchar4 calculate_support_region(const TextureObject<uint8_t> &img, int x, int y, int v_max, int h_max) {
__device__ uchar4 calculate_support_region(const uint8_t* __restrict__ img, int width, int height, int pitch, int x, int y, int v_max, int h_max) {
int x_min = max(0, x - h_max);
int x_max = min(img.width()-1, static_cast<unsigned int>(x + h_max));
int x_max = min(width-1, static_cast<unsigned int>(x + h_max));
int y_min = max(0, y - v_max);
int y_max = min(img.height()-1, static_cast<unsigned int>(y + v_max));
int y_max = min(height-1, static_cast<unsigned int>(y + v_max));
uchar4 result = make_uchar4(0, 0, 0, 0);
Mask m1(img.tex2D(x,y));
Mask m1(img[x+y*pitch]);
int u;
for (u=x-1; u >= x_min; --u) {
Mask m2(img.tex2D(u,y));
Mask m2(img[u+y*pitch]);
if (m2.isDiscontinuity()) {
result.x = x - u - 1;
break;
......@@ -112,7 +112,7 @@ __device__ uchar4 calculate_support_region(const TextureObject<uint8_t> &img, in
if (u < x_min) result.x = x - x_min;
for (u=x+1; u <= x_max; ++u) {
Mask m2(img.tex2D(u,y));
Mask m2(img[u+y*pitch]);
if (m2.isDiscontinuity()) {
result.y = u - x - 1;
break;
......@@ -122,7 +122,7 @@ __device__ uchar4 calculate_support_region(const TextureObject<uint8_t> &img, in
int v;
for (v=y-1; v >= y_min; --v) {
Mask m2(img.tex2D(x,v));
Mask m2(img[x+v*pitch]);
if (m2.isDiscontinuity()) {
result.z = y - v - 1;
break;
......@@ -131,7 +131,7 @@ __device__ uchar4 calculate_support_region(const TextureObject<uint8_t> &img, in
if (v < y_min) result.z = y - y_min;
for (v=y+1; v <= y_max; ++v) {
Mask m2(img.tex2D(x,v));
Mask m2(img[x+v*pitch]);
if (m2.isDiscontinuity()) {
result.w = v - y - 1;
break;
......@@ -150,26 +150,26 @@ __device__ uchar4 calculate_support_region(const TextureObject<uint8_t> &img, in
}
template <typename T, bool SYM>
__global__ void support_region_kernel(TextureObject<T> img, TextureObject<uchar4> region, float tau, int v_max, int h_max) {
__global__ void support_region_kernel(const T* __restrict__ img, int width, int height, int pitch, TextureObject<uchar4> region, float tau, int v_max, int h_max) {
const int x = blockIdx.x*blockDim.x + threadIdx.x;
const int y = blockIdx.y*blockDim.y + threadIdx.y;
if (x < 0 || y < 0 || x >= img.width() || y >= img.height()) return;
if (x < 0 || y < 0 || x >= width || y >= height) return;
region(x,y) = calculate_support_region<T,SYM>(img, x, y, tau, v_max, h_max);
region(x,y) = calculate_support_region<T,SYM>(img, width, height, pitch, x, y, tau, v_max, h_max);
}
__global__ void support_region_kernel(TextureObject<uint8_t> img, TextureObject<uchar4> region, int v_max, int h_max) {
__global__ void support_region_kernel(const uint8_t* __restrict__ img, int width, int height, int pitch, TextureObject<uchar4> region, int v_max, int h_max) {
const int x = blockIdx.x*blockDim.x + threadIdx.x;
const int y = blockIdx.y*blockDim.y + threadIdx.y;
if (x < 0 || y < 0 || x >= img.width() || y >= img.height()) return;
if (x < 0 || y < 0 || x >= width || y >= height) return;
region(x,y) = calculate_support_region(img, x, y, v_max, h_max);
region(x,y) = calculate_support_region(img, width, height, pitch, x, y, v_max, h_max);
}
void ftl::cuda::support_region(
ftl::cuda::TextureObject<uchar4> &colour,
const cv::cuda::GpuMat &colour,
ftl::cuda::TextureObject<uchar4> &region,
float tau,
int v_max,
......@@ -180,8 +180,8 @@ void ftl::cuda::support_region(
const dim3 gridSize((region.width() + T_PER_BLOCK - 1)/T_PER_BLOCK, (region.height() + T_PER_BLOCK - 1)/T_PER_BLOCK);
const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
if (sym) support_region_kernel<uchar4, true><<<gridSize, blockSize, 0, stream>>>(colour, region, tau, v_max, h_max);
else support_region_kernel<uchar4, false><<<gridSize, blockSize, 0, stream>>>(colour, region, tau, v_max, h_max);
if (sym) support_region_kernel<uchar4, true><<<gridSize, blockSize, 0, stream>>>((uchar4*)colour.data, colour.cols, colour.rows, colour.step/4, region, tau, v_max, h_max);
else support_region_kernel<uchar4, false><<<gridSize, blockSize, 0, stream>>>((uchar4*)colour.data, colour.cols, colour.rows, colour.step/4, region, tau, v_max, h_max);
cudaSafeCall( cudaGetLastError() );
......@@ -202,7 +202,7 @@ void ftl::cuda::support_region(
const dim3 gridSize((region.width() + T_PER_BLOCK - 1)/T_PER_BLOCK, (region.height() + T_PER_BLOCK - 1)/T_PER_BLOCK);
const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
support_region_kernel<float, true><<<gridSize, blockSize, 0, stream>>>(depth, region, tau, v_max, h_max);
support_region_kernel<float, true><<<gridSize, blockSize, 0, stream>>>(depth.devicePtr(), depth.width(), depth.height(), depth.pixelPitch(), region, tau, v_max, h_max);
cudaSafeCall( cudaGetLastError() );
......@@ -222,7 +222,7 @@ void ftl::cuda::support_region(
const dim3 gridSize((region.width() + T_PER_BLOCK - 1)/T_PER_BLOCK, (region.height() + T_PER_BLOCK - 1)/T_PER_BLOCK);
const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
support_region_kernel<<<gridSize, blockSize, 0, stream>>>(mask, region, v_max, h_max);
support_region_kernel<<<gridSize, blockSize, 0, stream>>>(mask.devicePtr(), mask.width(), mask.height(), mask.pixelPitch(), region, v_max, h_max);
cudaSafeCall( cudaGetLastError() );
......
......@@ -7,7 +7,7 @@ namespace ftl {
namespace cuda {
void support_region(
ftl::cuda::TextureObject<uchar4> &colour,
const cv::cuda::GpuMat &colour,
ftl::cuda::TextureObject<uchar4> &region,
float tau, int v_max, int h_max, bool sym,
cudaStream_t stream);
......
......@@ -18,7 +18,7 @@ using ftl::codecs::Channel;
using ftl::rgbd::Format;
using cv::cuda::GpuMat;
HFSmoother::HFSmoother(ftl::Configurable *cfg) : ftl::operators::Operator(cfg) {
HFSmoother::HFSmoother(ftl::operators::Graph *g, ftl::Configurable *cfg) : ftl::operators::Operator(g, cfg) {
}
......@@ -71,7 +71,7 @@ bool HFSmoother::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t
// ====== Smoothing Channel ====================================================
SmoothChannel::SmoothChannel(ftl::Configurable *cfg) : ftl::operators::Operator(cfg) {
SmoothChannel::SmoothChannel(ftl::operators::Graph *g, ftl::Configurable *cfg) : ftl::operators::Operator(g, cfg) {
}
......@@ -89,7 +89,7 @@ bool SmoothChannel::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStrea
float scale = 1.0f;
// Clear to max smoothing
out.create<GpuMat>(Channel::Smoothing, Format<float>(width, height)).setTo(cv::Scalar(1.0f));
out.create<ftl::rgbd::VideoFrame>(Channel::Smoothing).createGPU(Format<float>(width, height)).setTo(cv::Scalar(1.0f));
// Reduce to nearest
ftl::cuda::smooth_channel(
......@@ -108,14 +108,16 @@ bool SmoothChannel::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStrea
height /= 2;
scale *= 2.0f;
temp_[i].create(width,height);
ftl::rgbd::Camera scaledCam = in.getLeftCamera().scaled(width, height);
// Downscale images for next pass
cv::cuda::resize(in.get<GpuMat>(Channel::Colour), temp_[i].create<GpuMat>(Channel::Colour), cv::Size(width, height), 0.0, 0.0, cv::INTER_LINEAR);
cv::cuda::resize(in.get<GpuMat>(Channel::Colour), temp_[i].to_gpumat(), cv::Size(width, height), 0.0, 0.0, cv::INTER_LINEAR);
//cv::cuda::resize(in.get<GpuMat>(Channel::Depth), temp_[i].create<GpuMat>(Channel::Depth), cv::Size(width, height), 0.0, 0.0, cv::INTER_NEAREST);
ftl::cuda::smooth_channel(
temp_[i].createTexture<uchar4>(Channel::Colour),
temp_[i],
//temp_[i].createTexture<float>(Channel::Depth),
out.getTexture<float>(Channel::Smoothing),
scaledCam,
......@@ -133,7 +135,7 @@ bool SmoothChannel::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStrea
// ===== MLS ===================================================================
SimpleMLS::SimpleMLS(ftl::Configurable *cfg) : ftl::operators::Operator(cfg) {
SimpleMLS::SimpleMLS(ftl::operators::Graph *g, ftl::Configurable *cfg) : ftl::operators::Operator(g, cfg), temp_(ftl::data::Frame::make_standalone()) {
}
......@@ -146,6 +148,8 @@ bool SimpleMLS::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t
int iters = config()->value("mls_iterations", 1);
int radius = config()->value("mls_radius",2);
auto &temp = temp_.cast<ftl::rgbd::Frame>();
if (!in.hasChannel(Channel::Normals)) {
/*ftl::cuda::normals(
in.createTexture<float4>(Channel::Normals, ftl::rgbd::Format<float4>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
......@@ -160,9 +164,9 @@ bool SimpleMLS::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t
for (int i=0; i<iters; ++i) {
ftl::cuda::mls_smooth(
in.createTexture<half4>(Channel::Normals),
temp_.createTexture<half4>(Channel::Normals, ftl::rgbd::Format<half4>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
temp.createTexture<half4>(Channel::Normals, ftl::rgbd::Format<half4>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
in.createTexture<float>(Channel::Depth),
temp_.createTexture<float>(Channel::Depth, ftl::rgbd::Format<float>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
temp.createTexture<float>(Channel::Depth, ftl::rgbd::Format<float>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
thresh,
radius,
in.getLeftCamera(),
......@@ -171,7 +175,8 @@ bool SimpleMLS::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t
//in.swapChannels(Channel::Depth, Channel::Depth2);
//in.swapChannels(Channel::Normals, Channel::Points);
temp_.swapChannels(Channel::Normals + Channel::Depth, in);
temp.swapChannel(Channel::Normals, in);
temp.swapChannel(Channel::Depth, in);
}
return true;
......@@ -179,7 +184,7 @@ bool SimpleMLS::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t
ColourMLS::ColourMLS(ftl::Configurable *cfg) : ftl::operators::Operator(cfg) {
ColourMLS::ColourMLS(ftl::operators::Graph *g, ftl::Configurable *cfg) : ftl::operators::Operator(g, cfg), temp_(ftl::data::Frame::make_standalone()) {
}
......@@ -200,14 +205,33 @@ bool ColourMLS::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t
return false;
}
auto &temp = temp_.cast<ftl::rgbd::Frame>();
auto size = in.get<GpuMat>(Channel::Depth).size();
auto cvstream = cv::cuda::StreamAccessor::wrapStream(stream);
const GpuMat &rgb = in.get<GpuMat>(Channel::Colour);
GpuMat rgb_buf;
if (rgb.size() != size) {
if (graph()->hasBuffer(Buffer::LowLeft, in.source())) {
rgb_buf = graph()->getBuffer(Buffer::LowLeft, in.source());
} else {
auto &t = graph()->createBuffer(Buffer::LowLeft, in.source());
cv::cuda::resize(rgb, t, size, 0, 0, cv::INTER_LINEAR, cvstream);
rgb_buf = t;
}
} else {
rgb_buf = rgb;
}
// FIXME: Assume in and out are the same frame.
for (int i=0; i<iters; ++i) {
if (!crosssup) {
ftl::cuda::colour_mls_smooth(
in.createTexture<half4>(Channel::Normals),
temp_.createTexture<half4>(Channel::Normals, ftl::rgbd::Format<half4>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
temp.createTexture<half4>(Channel::Normals, ftl::rgbd::Format<half4>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
in.createTexture<float>(Channel::Depth),
temp_.createTexture<float>(Channel::Depth, ftl::rgbd::Format<float>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
temp.createTexture<float>(Channel::Depth, ftl::rgbd::Format<float>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
in.createTexture<uchar4>(Channel::Colour),
thresh,
col_smooth,
......@@ -219,10 +243,11 @@ bool ColourMLS::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t
ftl::cuda::colour_mls_smooth_csr(
in.createTexture<uchar4>(Channel::Support1),
in.createTexture<half4>(Channel::Normals),
temp_.createTexture<half4>(Channel::Normals, ftl::rgbd::Format<half4>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
temp.createTexture<half4>(Channel::Normals, ftl::rgbd::Format<half4>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
in.createTexture<float>(Channel::Depth),
temp_.createTexture<float>(Channel::Depth, ftl::rgbd::Format<float>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
in.createTexture<uchar4>(Channel::Colour),
temp.createTexture<float>(Channel::Depth, ftl::rgbd::Format<float>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
//in.createTexture<uchar4>(Channel::Colour),
rgb_buf,
thresh,
col_smooth,
filling,
......@@ -233,7 +258,8 @@ bool ColourMLS::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t
//in.swapChannels(Channel::Depth, Channel::Depth2);
//in.swapChannels(Channel::Normals, Channel::Points);
temp_.swapChannels(Channel::Normals + Channel::Depth, in);
temp_.swapChannel(Channel::Depth, in);
temp_.swapChannel(Channel::Normals, in);
}
return true;
......@@ -242,8 +268,8 @@ bool ColourMLS::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t
// ====== Aggregating MLS ======================================================
AggreMLS::AggreMLS(ftl::Configurable *cfg) : ftl::operators::Operator(cfg) {
AggreMLS::AggreMLS(ftl::operators::Graph *g, ftl::Configurable *cfg) : ftl::operators::Operator(g, cfg), temp_(ftl::data::Frame::make_standalone()) {
temp_.store();
}
AggreMLS::~AggreMLS() {
......@@ -267,11 +293,29 @@ bool AggreMLS::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t s
return false;
}
auto &temp = temp_.cast<ftl::rgbd::Frame>();
auto size = in.get<GpuMat>(Channel::Depth).size();
centroid_horiz_.create(size.height, size.width);
normals_horiz_.create(size.height, size.width);
centroid_vert_.create(size.width, size.height);
auto cvstream = cv::cuda::StreamAccessor::wrapStream(stream);
const GpuMat &rgb = in.get<GpuMat>(Channel::Colour);
GpuMat rgb_buf;
if (rgb.size() != size) {
if (graph()->hasBuffer(Buffer::LowLeft, in.source())) {
rgb_buf = graph()->getBuffer(Buffer::LowLeft, in.source());
} else {
auto &t = graph()->createBuffer(Buffer::LowLeft, in.source());
cv::cuda::resize(rgb, t, size, 0, 0, cv::INTER_LINEAR, cvstream);
rgb_buf = t;
}
} else {
rgb_buf = rgb;
}
// FIXME: Assume in and out are the same frame.
for (int i=0; i<iters; ++i) {
......@@ -282,7 +326,8 @@ bool AggreMLS::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t s
normals_horiz_,
in.createTexture<float>(Channel::Depth),
centroid_horiz_,
in.createTexture<uchar4>(Channel::Colour),
//in.createTexture<uchar4>(Channel::Colour),
rgb_buf,
thresh,
col_smooth,
radius,
......@@ -306,7 +351,7 @@ bool AggreMLS::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t s
ftl::cuda::mls_adjust_depth(
in.createTexture<half4>(Channel::Normals),
centroid_vert_,
temp_.createTexture<float>(Channel::Depth, ftl::rgbd::Format<float>(size)),
temp.createTexture<float>(Channel::Depth, ftl::rgbd::Format<float>(size)),
in.getTexture<float>(Channel::Depth),
in.getLeftCamera(),
stream
......@@ -314,16 +359,17 @@ bool AggreMLS::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t s
//in.swapChannels(Channel::Depth, Channel::Depth2);
//in.swapChannels(Channel::Normals, Channel::Points);
temp_.swapChannels(ftl::codecs::Channels<0>(Channel::Depth), in);
temp_.swapChannel(Channel::Depth, in);
} else {
ftl::cuda::colour_mls_smooth_csr(
in.createTexture<uchar4>(Channel::Support1),
in.createTexture<half4>(Channel::Normals),
temp_.createTexture<half4>(Channel::Normals, ftl::rgbd::Format<half4>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
temp.createTexture<half4>(Channel::Normals, ftl::rgbd::Format<half4>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
in.createTexture<float>(Channel::Depth),
temp_.createTexture<float>(Channel::Depth, ftl::rgbd::Format<float>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
in.createTexture<uchar4>(Channel::Colour),
temp.createTexture<float>(Channel::Depth, ftl::rgbd::Format<float>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
//in.createTexture<uchar4>(Channel::Colour),
rgb_buf,
thresh,
col_smooth,
false,
......@@ -331,7 +377,8 @@ bool AggreMLS::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t s
stream
);
temp_.swapChannels(Channel::Normals + Channel::Depth, in);
temp_.swapChannel(Channel::Depth, in);
temp_.swapChannel(Channel::Normals, in);
}
}
......@@ -341,7 +388,7 @@ bool AggreMLS::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t s
// ====== Adaptive MLS =========================================================
AdaptiveMLS::AdaptiveMLS(ftl::Configurable *cfg) : ftl::operators::Operator(cfg) {
AdaptiveMLS::AdaptiveMLS(ftl::operators::Graph *g, ftl::Configurable *cfg) : ftl::operators::Operator(g, cfg), temp_(ftl::data::Frame::make_standalone()) {
}
......@@ -358,20 +405,23 @@ bool AdaptiveMLS::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_
return false;
}
auto &temp = temp_.cast<ftl::rgbd::Frame>();
// FIXME: Assume in and out are the same frame.
for (int i=0; i<iters; ++i) {
ftl::cuda::adaptive_mls_smooth(
in.createTexture<half4>(Channel::Normals),
temp_.createTexture<half4>(Channel::Normals, ftl::rgbd::Format<half4>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
temp.createTexture<half4>(Channel::Normals, ftl::rgbd::Format<half4>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
in.createTexture<float>(Channel::Depth),
temp_.createTexture<float>(Channel::Depth, ftl::rgbd::Format<float>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
temp.createTexture<float>(Channel::Depth, ftl::rgbd::Format<float>(in.get<cv::cuda::GpuMat>(Channel::Depth).size())),
in.createTexture<float>(Channel::Smoothing),
radius,
in.getLeftCamera(),
stream
);
temp_.swapChannels(Channel::Normals + Channel::Depth, in);
temp_.swapChannel(Channel::Depth, in);
temp_.swapChannel(Channel::Normals, in);
}
......
......@@ -35,7 +35,8 @@ void colour_mls_smooth_csr(
ftl::cuda::TextureObject<half4> &normals_out,
ftl::cuda::TextureObject<float> &depth_in,
ftl::cuda::TextureObject<float> &depth_out,
ftl::cuda::TextureObject<uchar4> &colour_in,
//ftl::cuda::TextureObject<uchar4> &colour_in,
const cv::cuda::GpuMat &colour_in,
float smoothing,
float colour_smoothing,
bool filling,
......@@ -56,7 +57,8 @@ void mls_aggr_horiz(
ftl::cuda::TextureObject<half4> &normals_out,
ftl::cuda::TextureObject<float> &depth_in,
ftl::cuda::TextureObject<float4> &centroid_out,
ftl::cuda::TextureObject<uchar4> &colour_in,
//ftl::cuda::TextureObject<uchar4> &colour_in,
const cv::cuda::GpuMat &colour_in,
float smoothing,
float colour_smoothing,
int radius,
......
......@@ -9,7 +9,7 @@ using ftl::operators::CullWeight;
using ftl::operators::DegradeWeight;
using ftl::codecs::Channel;
PixelWeights::PixelWeights(ftl::Configurable *cfg) : ftl::operators::Operator(cfg) {
PixelWeights::PixelWeights(ftl::operators::Graph *g, ftl::Configurable *cfg) : ftl::operators::Operator(g, cfg) {
}
......@@ -33,14 +33,22 @@ bool PixelWeights::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream
params.normals = config()->value("use_normals", true);
bool output_normals = config()->value("output_normals", params.normals);
if ((!in.hasChannel(Channel::Depth) && !in.hasChannel(Channel::GroundTruth)) || !in.hasChannel(Channel::Support1)) return false;
if (!in.hasChannel(Channel::Depth) && !in.hasChannel(Channel::GroundTruth)) {
out.message(ftl::data::Message::Warning_MISSING_CHANNEL, "Missing Depth channel in Weights operators");
return false;
}
if (!in.hasChannel(Channel::Support1)) {
out.message(ftl::data::Message::Warning_MISSING_CHANNEL, "Missing Support channel in Weights operators");
return false;
}
Channel dchan = (in.hasChannel(Channel::Depth)) ? Channel::Depth : Channel::GroundTruth;
if (!out.hasChannel(Channel::Mask)) {
cv::cuda::Stream cvstream = cv::cuda::StreamAccessor::wrapStream(stream);
auto &m = out.create<cv::cuda::GpuMat>(Channel::Mask);
m.create(in.get<cv::cuda::GpuMat>(dchan).size(), CV_8UC1);
m.setTo(cv::Scalar(0));
m.setTo(cv::Scalar(0), cvstream);
}
if (output_normals) {
......@@ -69,7 +77,7 @@ bool PixelWeights::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream
return true;
}
CullWeight::CullWeight(ftl::Configurable *cfg) : ftl::operators::Operator(cfg) {
CullWeight::CullWeight(ftl::operators::Graph *g, ftl::Configurable *cfg) : ftl::operators::Operator(g, cfg) {
}
......@@ -82,7 +90,7 @@ bool CullWeight::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t
float weight = config()->value("weight", 0.1f);
out.clearPackets(Channel::Depth); // Force reset
out.set<ftl::rgbd::VideoFrame>(Channel::Depth); // Force reset
ftl::cuda::cull_weight(
in.createTexture<short>(Channel::Weights),
out.createTexture<float>(Channel::Depth),
......@@ -95,7 +103,7 @@ bool CullWeight::apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t
DegradeWeight::DegradeWeight(ftl::Configurable *cfg) : ftl::operators::Operator(cfg) {
DegradeWeight::DegradeWeight(ftl::operators::Graph *g, ftl::Configurable *cfg) : ftl::operators::Operator(g, cfg) {
}
......
......@@ -26,6 +26,8 @@ __global__ void pixel_weight_kernel(
if (x < size.width && y < size.height) {
Mask mask(mask_out(x,y));
if (normals_out.isValid()) normals_out(x,y) = make_half4(0.0f);
const float d = depth.tex2D((int)x, (int)y);
// Multiples of pixel size at given depth
//const float threshold = (depthCoef / ((depthCoef / d) - (radius+disconDisparities-1))) - d;
......
### DBSCAN Unit ################################################################
add_executable(dbscan_unit
$<TARGET_OBJECTS:CatchTest>
./dbscan_unit.cpp
)
target_include_directories(dbscan_unit PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../include")
target_link_libraries(dbscan_unit ftlcommon)
add_test(DBSCANUnitTest dbscan_unit)
#pragma once
#include <vector>
#include <opencv2/core.hpp>
/**
* Test data generated with sklearn.datasets (make_circles and make_moons)
* Two clusters in both.
*
* Visualization:
* https://scikit-learn.org/stable/auto_examples/cluster/plot_cluster_comparison.html
*/
static const std::vector<cv::Vec2f> noisy_circles {
{-0.677999, -0.698757},
{0.931437, 0.191391},
{0.548291, -0.006017},
{0.872837, 0.375023},
{0.435427, -0.294726},
{-0.536253, -0.163471},
{0.935534, -0.069950},
{0.159219, 0.971415},
{-0.611547, 0.751418},
{0.423040, -0.268125},
{0.173147, -0.458363},
{-0.219125, -0.398849},
{0.096109, -0.519602},
{-0.104486, 0.942077},
{0.967687, -0.174183},
{0.754242, -0.621617},
{-0.043996, -0.531987},
{0.430365, -0.355165},
{-1.027807, 0.155325},
{-0.228548, 0.382529},
{0.071758, 0.989000},
{0.655803, -0.812775},
{0.758490, 0.629618},
{-0.866656, -0.497841},
{-0.520035, 0.072190},
{0.394909, 0.221529},
{-0.480141, -0.098754},
{-0.184218, -0.921755},
{0.101596, 0.524727},
{-0.140615, -0.420062},
{0.305418, -0.305836},
{-0.850261, 0.502583},
{-0.520933, -0.010492},
{0.157637, 0.523338},
{-0.434189, 0.023918},
{0.316513, -0.394525},
{-0.603595, -0.675230},
{0.120921, -0.969693},
{-0.699461, -0.700145},
{-0.829813, 0.384497},
{-0.450135, -0.285030},
{0.342891, -0.455510},
{0.531814, 0.031431},
{0.738477, -0.657938},
{-0.615457, 0.768498},
{-0.378752, -0.893043},
{-0.469287, 0.170619},
{0.940516, -0.345081},
{0.280564, 0.318425},
{-0.375463, -0.387242},
{0.513356, 0.249786},
{-0.461774, -0.224138},
{0.053183, -0.948771},
{0.070808, -0.380032},
{-0.160072, -0.895151},
{-0.027487, -0.554549},
{0.912894, -0.342490},
{-0.441389, -0.890764},
{0.454790, 0.032809},
{-0.506644, 0.080482},
{-0.734677, -0.666446},
{0.860849, 0.554751},
{-0.456707, 0.221557},
{-0.331154, 0.969166},
{0.035349, 0.466655},
{-0.008867, 0.516405},
{-0.312811, -1.016868},
{-0.331718, -0.439313},
{-0.753690, -0.642232},
{-0.546627, 0.079896},
{0.914885, 0.087661},
{-0.946636, -0.593912},
{0.407068, 0.108282},
{-0.409579, 0.293544},
{0.418979, 0.871143},
{-0.079673, -0.959064},
{0.022271, 0.492024},
{-0.128445, 1.034038},
{0.296129, 0.927400},
{0.221448, -0.372743},
{0.423269, -0.212434},
{-0.924347, -0.351271},
{-0.605629, -0.715164},
{-0.765676, -0.728862},
{0.338073, 0.372803},
{-0.428441, 0.807283},
{0.333686, -0.263154},
{-0.524092, -0.848993},
{-0.038609, -0.995680},
{-0.984526, 0.046951},
{0.210340, -0.985424},
{0.008886, -0.996032},
{-0.659499, 0.594582},
{0.971926, 0.224894},
{-0.353677, -0.235196},
{-0.057825, -0.566347},
{0.871634, -0.633181},
{-0.321464, 0.931368},
{0.984817, 0.281003},
{0.087167, 0.529270},
{-0.388277, 0.193739},
{0.179648, -0.497591},
{0.551416, 0.873007},
{0.057045, 0.497796},
{-0.573832, 0.033362},
{0.074692, 0.579819},
{-0.952958, 0.325481},
{-0.732914, -0.528069},
{0.248820, -0.956671},
{-0.511009, 0.180196},
{-0.015967, 1.037270},
{0.961245, 0.087256},
{0.924577, 0.380657},
{0.694589, 0.584797},
{-0.168396, -0.486705},
{0.112856, 0.455664},
{0.905957, 0.235716},
{-0.193360, -0.380150},
{0.428584, 0.279267},
{-0.129808, -1.006865},
{0.849347, 0.433455},
{0.958172, -0.407165},
{-0.684629, -0.698642},
{-0.303698, -0.935910},
{-0.605071, -0.870112},
{-0.171775, 0.504553},
{-0.941087, -0.363499},
{-1.026895, -0.176613},
{0.251774, -0.375210},
{-0.039233, 0.508237},
{0.598627, 0.161475},
{0.150253, 0.467936},
{-0.158063, 0.993672},
{-0.174484, -0.490936},
{0.797353, -0.570802},
{-0.880238, 0.581656},
{0.248483, 0.975321},
{-0.764439, 0.640960},
{-0.555157, 0.222931},
{0.398577, -0.875908},
{-0.908205, 0.407285},
{0.539886, -0.845203},
{0.162116, 0.440918},
{0.481715, 0.116853},
{-0.049455, 0.973072},
{-1.094953, -0.026592},
{0.081761, -0.882492},
{-0.935893, 0.378655},
{0.397561, -0.169954},
{0.974016, 0.059282},
{-0.854687, 0.659927},
{-0.468957, -0.282842},
{0.980104, 0.249931},
{0.086943, 0.513643},
{0.541957, 0.144448},
{-0.019935, 0.411957},
{0.495279, -0.184585},
{-0.992969, 0.072164},
{-0.045094, 0.469167},
{0.909351, -0.449186},
{-0.225598, -0.473253},
{0.865109, -0.496427},
{-0.227253, 0.997429},
{-0.461060, -0.179750},
{0.254634, -0.391796},
{0.162349, 0.399205},
{-0.547372, 0.199308},
{0.432875, -0.288995},
{-0.838898, 0.395562},
{0.985178, 0.197549},
{-0.866028, -0.502550},
{0.507851, 0.173829},
{0.380959, -0.212232},
{-0.084691, 1.016472},
{-0.222872, 0.397240},
{-0.900582, -0.474540},
{0.237292, 0.830083},
{-0.462334, -0.958491},
{0.294507, -0.392423},
{0.660606, -0.680099},
{-0.852687, 0.549440},
{-0.307098, 0.859804},
{0.986497, -0.286053},
{1.072890, -0.014782},
{0.347051, -0.952041},
{0.792057, 0.622892},
{0.856374, -0.659352},
{0.716643, 0.739131},
{-0.949822, -0.413830},
{0.439084, 0.973049},
{-0.901443, 0.473575},
{-0.417679, -0.292204},
{-0.401663, 0.230490},
{-0.770459, -0.624693},
{0.104649, -0.419057},
{-0.351992, 0.925476},
{-0.461885, 0.081054},
{0.776156, 0.563417},
{-0.609453, 0.776124},
{-0.869826, 0.611030},
{-0.936343, -0.250396},
{0.947641, 0.195189},
{0.172001, 0.505505},
{0.670847, 0.722337},
{-0.128180, 0.382630},
{0.084943, 0.970973},
{0.502432, 0.836911},
{-0.765820, -0.598353},
{0.267783, -0.953261},
{-0.136963, 0.505817},
{0.526329, 0.006974},
{0.033778, -1.002287},
{1.060646, 0.045413},
{0.500939, -0.059420},
{-0.440592, -0.186962},
{-0.725037, -0.670232},
{-0.259295, -0.395699},
{0.356994, 0.302502},
{0.411269, -0.865534},
{-0.459595, 0.127022},
{0.187557, 0.503566},
{0.350990, 0.962713},
{0.946578, -0.211255},
{0.599337, -0.842506},
{-0.186974, -1.057288},
{-0.781941, -0.518192},
{0.504377, -0.112438},
{-0.424958, -0.131915},
{-0.988047, -0.290393},
{0.583738, 0.762403},
{0.905616, -0.191904},
{0.122915, -0.478367},
{0.321184, -0.380730},
{0.925293, -0.452892},
{0.177570, -0.932051},
{0.285047, 0.423628},
{-0.506985, -0.110505},
{0.482756, -0.083604},
{-0.308917, 1.035905},
{-0.486191, -0.079374},
{-0.109448, 0.483735},
{0.927042, 0.372615},
{-0.227088, 0.396412},
{0.194856, -0.431768},
{0.807127, 0.410153},
{-0.487039, -0.197967},
{-0.015964, -0.483816},
{-0.275203, -0.955066},
{-0.322384, 0.299988},
{-0.680302, 0.686720},
{0.300083, -0.209034},
{0.768799, -0.659106},
{-0.316121, 0.841761},
{-0.100478, 0.441617},
{-0.317351, 0.463191},
{-0.168533, -0.524660},
{-0.210372, 0.910182},
{0.380473, -0.301154},
{1.059209, -0.238330},
{-0.437668, 0.260651},
{-0.918127, -0.625615},
{0.661263, -0.592862},
{0.208281, 0.511717},
{-0.862470, 0.560693},
{-0.357175, -0.253458},
{0.419587, -0.862857},
{0.075456, -0.499759},
{-0.112886, 0.495239},
{-0.947117, 0.115546},
{-0.386086, -0.093426},
{0.397381, -0.358283},
{0.586201, -0.039841},
{0.373323, -0.211077},
{0.523411, -0.313837},
{-0.302930, 0.392802},
{-0.373475, -0.972741},
{-0.535744, -0.111344},
{0.030460, 0.952755},
{-0.833726, 0.623528},
{0.330402, -0.415524},
{0.198183, -0.417874},
{0.419158, -0.220807},
{0.243254, -0.480818},
{-0.164164, 0.447863},
{-0.356430, 0.316113},
{0.960673, -0.532562},
{-0.217009, 0.399249},
{-0.182977, -0.968204},
{-0.486861, 0.001070},
{-0.998201, 0.285770},
{-0.258566, -0.348945},
{1.001401, -0.083753},
{0.899496, 0.399639},
{-0.029120, -1.011456},
{-0.510889, -0.033808},
{-0.236222, 1.014309},
{-0.025134, 0.500611},
{-0.177920, 0.445065},
{0.458141, -0.109140},
{-0.764946, -0.621198},
{0.486058, -0.860182},
{0.727380, -0.663891},
{-0.896435, 0.431432},
{0.353965, 0.906513},
{0.494337, -0.865661},
{-0.677504, -0.798777},
{0.981943, 0.348849},
{-0.417313, 0.230326},
{-0.534694, 0.085594},
{-1.036211, 0.138269},
{0.470304, 0.116420},
{-0.758203, -0.634538},
{0.298848, 0.459691},
{0.866894, -0.494182},
{-0.887719, -0.376569},
{-0.462029, -0.263352},
{0.098598, 0.485244},
{-0.420278, -0.214920},
{0.946167, 0.515926},
{-0.341843, 0.925878},
{-0.867367, 0.397898},
{0.402215, 0.293868},
{-0.512864, -0.231789},
{0.547200, -0.109036},
{0.906324, 0.490822},
{-0.109815, 0.497706},
{-0.088632, -1.021199},
{-0.290762, -0.932944},
{-0.394197, 0.256479},
{-0.287780, 0.253140},
{-1.011401, -0.038588},
{0.360575, 0.294392},
{-0.297505, -0.231839},
{0.864790, 0.276511},
{-0.660445, 0.812650},
{-0.193294, 0.544461},
{0.406888, -0.296968},
{0.605198, 0.862784},
{0.216620, -0.431742},
{-0.519715, 0.175320},
{-0.836740, -0.527318},
{0.544606, 0.854625},
{-0.075076, 1.107216},
{-0.355730, 0.390136},
{0.178468, -0.516520},
{-0.414952, 0.230035},
{-0.400819, 0.301432},
{0.047976, -0.430378},
{0.045276, -0.968817},
{0.173568, -0.500156},
{0.412780, 0.205282},
{-0.179633, -0.530022},
{-0.492470, -0.942870},
{-0.842717, 0.046667},
{0.253652, -0.423416},
{-0.175362, -0.491158},
{-0.251316, -0.452699},
{0.347521, -0.337458},
{-0.428995, -0.840094},
{0.455201, 0.287714},
{0.226316, -0.935593},
{0.834339, 0.359791},
{-0.051508, -0.432374},
{-0.151291, -0.915885},
{0.746569, 0.736690},
{0.254548, 0.416879},
{-0.446322, -0.292015},
{-0.145351, -0.490869},
{0.896341, 0.382621},
{-0.299118, 0.359764},
{0.783893, 0.606463},
{-0.605867, -0.777543},
{0.104327, -0.497191},
{1.010678, -0.084427},
{0.134126, -0.483766},
{-0.432429, 0.846934},
{0.814122, -0.561370},
{0.953933, -0.213570},
{0.220573, -0.982055},
{0.012950, 0.994213},
{0.211678, 0.947325},
{0.183041, -0.410490},
{-0.841034, 0.397786},
{0.974489, 0.088833},
{-0.183430, -0.928581},
{0.306613, -0.350987},
{-0.622288, -0.834056},
{0.019717, -1.008886},
{-0.476608, -0.078728},
{-0.979637, -0.093796},
{0.218740, 0.481157},
{-0.352026, -0.354291},
{0.317821, -0.236924},
{0.419291, 0.326369},
{-0.549357, 0.053576},
{0.508234, -0.296205},
{0.725601, -0.751717},
{-0.088771, -0.456016},
{1.046336, 0.000276},
{-0.215564, 0.455457},
{-0.508651, 0.056324},
{0.510434, -0.888738},
{0.117664, 0.525736},
{-0.380721, 0.227415},
{0.478517, -0.122766},
{-0.424344, 0.233289},
{0.454687, -0.876208},
{-0.441405, 0.146215},
{0.163840, 0.382482},
{0.569654, 0.085293},
{-0.986534, -0.478661},
{-0.387836, -0.916126},
{-0.127072, 0.426384},
{-0.199391, -0.526146},
{-1.035742, -0.196234},
{-0.051233, -0.465139},
{-0.428369, -0.047364},
{-0.476371, -0.138416},
{0.426817, 0.215754},
{0.495331, 0.191533},
{0.415164, -0.263429},
{0.838259, -0.494880},
{0.750893, -0.689373},
{-0.495794, -0.109527},
{0.234781, 0.427291},
{0.155417, -0.399608},
{0.566996, -0.760463},
{-0.507943, 0.806253},
{1.000322, -0.297023},
{0.835510, -0.638754},
{0.437386, 0.350652},
{-0.776158, -0.490757},
{0.347571, 0.509521},
{-0.477439, 0.861656},
{-0.971329, -0.370001},
{-0.400733, -0.190103},
{-0.545942, 0.905461},
{-0.433641, 0.166344},
{0.073579, -0.504871},
{-0.603776, -0.867520},
{0.208232, -0.473395},
{-0.877820, -0.402422},
{-0.417911, -0.364646},
{0.417578, -0.186013},
{-0.295229, 0.385251},
{0.048779, -0.436437},
{-0.379831, -0.251605},
{-0.049125, -0.601650},
{-0.421046, -0.131185},
{-0.037624, 0.385958},
{-0.301450, -0.845250},
{-0.322129, 0.373384},
{-0.017798, -0.996371},
{0.602488, -0.794054},
{0.695779, -0.742608},
{-0.410989, 0.360557},
{-0.079627, 0.584187},
{0.479044, -0.180925},
{-0.985729, -0.388357},
{-0.019055, 0.964549},
{-0.399048, 0.911348},
{-0.007990, -0.410155},
{0.064184, -0.515430},
{0.448937, -0.223400},
{-0.490115, 0.138612},
{0.243716, 0.462987},
{0.859155, 0.444468},
{0.202435, -0.499262},
{0.008052, -0.515216},
{0.656704, -0.730802},
{0.409827, 0.298936},
{-0.046320, 0.441092},
{0.446148, 0.022525},
{0.133035, -0.973219},
{0.747157, 0.652588},
{-0.767683, -0.669115},
{-0.427130, -0.249255},
{-0.447851, 0.161126},
{0.902155, 0.358619},
{-0.262299, -0.378197},
{-0.382379, 0.753528},
{0.470632, -0.157226},
{-0.734169, 0.627161},
{0.923239, -0.476153},
{0.870001, -0.471650},
{-0.651064, 0.704730},
{0.020101, 0.434650},
{-0.070438, -0.978500},
{-0.984267, -0.157078},
{-0.673376, 0.755563},
{-0.413699, 0.159980},
{-0.526451, -0.756120},
{0.577600, -0.067938},
{-0.541985, -0.013614},
{0.648841, -0.753135},
{-0.707874, 0.714192},
{-0.399472, 0.375041},
{0.303638, 0.409792},
{-0.988832, -0.119125},
{-0.662159, 0.764752},
{-0.974710, -0.334435},
{-0.059847, -0.547556},
{-0.926454, 0.237144},
{-0.714904, -0.642235},
{-1.061997, 0.144262},
{0.499472, -0.093872},
{0.436698, 0.456442},
{-0.145575, -1.015787},
{-0.833639, 0.415878},
{-0.538611, -0.130033},
{-0.047882, 0.988187},
{0.547303, 0.059564},
{-0.152244, 0.482598},
{0.883323, 0.551497},
{-0.525826, -0.899296},
{0.940643, 0.079329},
{0.159549, 0.471706},
{-0.431122, -0.869813},
{-0.420376, -0.284674},
{0.964114, -0.316045},
{0.090721, -0.510467},
{0.846677, 0.421471},
{-0.323696, 0.388932},
{0.360118, -0.342293},
{-0.906269, -0.332858},
{-0.172270, -1.003398},
{-0.112386, 1.012097},
{-0.896784, 0.373224},
{-0.590284, -0.778550},
{0.344965, 0.363182},
{-0.159235, -0.389218},
{-0.310178, -0.937732},
{0.463532, -0.206673},
{-1.018857, -0.336616},
{0.408806, -0.958345},
{-0.310498, 0.345931},
{0.280534, -0.966998},
{-0.091346, -1.035662},
{0.446762, 0.183808},
{-0.680360, -0.779284},
{-0.360954, -0.363679},
{0.447993, 0.825974},
{1.035206, 0.125413},
{-0.504644, 0.190076},
{0.272663, -0.291740},
{-0.679006, -0.716972},
{-0.007885, -1.023776},
{-0.264651, 0.328191},
{0.477003, 0.287399},
{-0.301861, -0.394858},
{0.702429, 0.728898},
{0.822623, 0.486387},
{-0.551961, -0.016652},
{-0.054259, 0.506987},
{-0.987546, -0.179947},
{0.175134, 0.892756},
{-0.330313, 0.372251},
{0.174161, -0.529993},
{-0.996708, 0.234108},
{-0.006552, 1.115930},
{-0.481870, -0.177124},
{-1.037933, 0.089382},
{0.649831, 0.885337},
{0.744833, -0.413087},
{-0.488744, 0.812116},
{-0.136410, 0.569903},
{-0.902982, 0.431387},
{-0.090668, 0.423669},
{-1.032578, -0.110512},
{-1.066994, 0.210198},
{-0.633369, 0.805055},
{-0.945786, 0.142619},
{-0.471333, -0.166392},
{-0.439499, 0.337179},
{0.293864, -0.372854},
{0.933753, -0.247618},
{0.438968, -0.344030},
{1.025843, 0.083377},
{0.848692, 0.409470},
{0.385671, -0.312714},
{-0.353101, -0.505543},
{0.500672, 0.207075},
{-0.992601, 0.094303},
{0.481475, 0.167595},
{0.536283, -0.134784},
{0.196846, -0.467952},
{0.935402, -0.133775},
{0.750427, -0.669785},
{0.699906, 0.707980},
{-0.369993, -0.414249},
{0.024423, -0.480681},
{-0.040300, 1.005000},
{0.082553, 1.020216},
{0.082123, -0.496301},
{0.453136, -0.225144},
{0.921309, -0.304055},
{0.413877, 0.208432},
{-0.201807, -0.975618},
{0.994212, -0.090429},
{0.794808, 0.610930},
{-0.481421, 0.123685},
{-0.916295, -0.248705},
{-0.720330, 0.821486},
{0.218266, -0.962246},
{-0.880411, -0.105727},
{0.061270, -0.464201},
{0.459177, 0.925891},
{-0.653836, 0.805294},
{0.467594, 0.137074},
{-0.276385, -0.395558},
{0.734202, 0.722302},
{0.375361, 0.189260},
{0.193504, -0.353737},
{-0.104672, 0.429293},
{-0.532233, -0.278900},
{0.522314, 0.003217},
{-0.753675, 0.663684},
{-0.637161, 0.801987},
{0.473039, -0.128132},
{0.892201, -0.510702},
{-0.220471, -0.451811},
{0.520514, -0.090235},
{-0.802982, -0.344827},
{0.083527, 0.467431},
{-0.958861, 0.135801},
{0.359597, -0.898957},
{-0.478897, 0.969480},
{0.083039, -0.494771},
{0.971487, -0.324155},
{-0.152730, -0.554838},
{-0.111315, 0.523428},
{-0.429918, 0.334627},
{0.426713, 0.199641},
{-0.945873, -0.015962},
{-0.618717, -0.577649},
{0.665114, 0.811857},
{-0.370519, -0.430923},
{-0.176774, -0.462536},
{0.795572, -0.468388},
{-0.456108, -0.196354},
{-0.468823, -0.927027},
{0.698177, -0.717687},
{-0.483736, 0.062662},
{-0.075897, -0.515180},
{0.250325, 0.378778},
{0.074739, 0.568741},
{-0.970513, 0.072880},
{0.511300, -0.015676},
{-1.014409, -0.123089},
{-0.179697, 1.044341},
{0.886630, 0.497947},
{-0.323735, -0.465294},
{0.386387, 0.369443},
{-0.670069, 0.730704},
{-0.055726, -0.484028},
{0.496090, 0.073803},
{-0.461010, -0.114447},
{-0.385740, 0.377162},
{0.462717, 0.211399},
{-0.217345, -0.912625},
{-0.722023, -0.762705},
{-0.465836, -0.210400},
{-0.155215, -0.449592},
{0.183616, -0.372897},
{-0.336088, -0.479256},
{0.043281, 1.047885},
{0.485354, 0.051776},
{1.014635, -0.009731},
{0.011073, -0.550879},
{-0.916356, 0.510771},
{-0.221729, 1.033860},
{-0.083329, 0.511366},
{0.173632, -0.380025},
{-0.083335, 0.510564},
{-0.255195, 0.507867},
{-0.257340, -0.992995},
{-0.534572, 0.904511},
{0.959089, 0.332995},
{0.710885, -0.668363},
{-0.457090, -0.119187},
{-0.371356, 0.843448},
{0.176817, 0.509167},
{-0.125945, 0.481280},
{-0.210094, 0.479303},
{0.025689, -0.471464},
{-0.138035, 0.420077},
{-0.555670, 0.801908},
{0.682827, 0.730237},
{0.940400, 0.164225},
{0.422610, -0.140270},
{0.258934, 0.403768},
{0.392850, 0.308711},
{-0.353735, 0.337216},
{0.241158, 0.403967},
{0.486632, -0.203836},
{-0.040170, -0.976753},
{-0.277386, 0.329737},
{-0.451354, -0.186307},
{-0.334577, -0.985400},
{0.542603, -0.892565},
{-0.567149, -0.784833},
{0.428929, -0.248270},
{-0.296177, 0.442089},
{0.976838, -0.136481},
{0.493476, 0.085780},
{0.468365, -0.081299},
{-0.530080, 0.075962},
{-0.920270, 0.015242},
{0.010270, 0.422162},
{-0.299807, 0.859005},
{-0.974349, -0.338235},
{-0.139248, 0.940724},
{0.721951, 0.578520},
{-0.064088, 1.036968},
{-0.579669, -0.800171},
{0.428870, 0.165491},
{0.354812, 1.071620},
{0.400755, 0.106264},
{-0.898130, 0.482274},
{-0.304259, -0.369392},
{0.220212, 0.323096},
{-0.781949, -0.623955},
{0.367734, 0.876235},
{-0.253624, -0.411581},
{-0.357577, -0.178154},
{-0.372693, -0.198908},
{-0.406149, 0.355235},
{-0.153364, -0.539393},
{1.017186, -0.062682},
{0.344752, -1.036994},
{0.308680, 0.384987},
{-0.089193, -0.509445},
{0.768380, 0.636211},
{0.291620, 1.075851},
{-0.513505, 0.148544},
{-0.495245, -0.205787},
{-0.358480, -0.354498},
{0.446033, 0.929607},
{-0.463365, 0.176340},
{0.525789, 0.047947},
{-0.957993, -0.154614},
{0.349895, 0.850708},
{-0.083150, 0.468088},
{-0.902392, -0.379334},
{-0.284484, 0.252711},
{0.008046, 0.491875},
{-1.069040, -0.235484},
{0.541315, 0.070689},
{0.401161, -0.320203},
{0.245583, 0.542472},
{0.041052, 0.518707},
{-0.899949, 0.165900},
{0.674320, 0.786183},
{0.495284, -0.815471},
{0.127167, -0.951990},
{1.006253, 0.305377},
{-0.660674, -0.778331},
{0.331870, 0.928536},
{0.306922, -0.485999},
{0.280189, 0.943400},
{-0.055382, -1.077626},
{0.241309, 0.475105},
{0.094016, 0.573092},
{-0.394661, -0.896598},
{-0.427261, 0.169856},
{-0.275674, -0.471098},
{-0.402323, 0.915196},
{-0.279216, 0.462328},
{-0.413871, 0.920625},
{0.048175, -0.470363},
{-0.562606, -0.035914},
{-0.320784, 0.453396},
{0.731346, -0.770326},
{0.265057, -1.069975},
{0.099509, 0.501058},
{-0.501528, -0.195086},
{0.809791, 0.513727},
{0.335598, -0.427183},
{0.053389, 0.953207},
{-0.319600, 0.920113},
{0.001808, 0.911417},
{-0.369341, -0.383086},
{-0.119685, 0.474282},
{-0.187143, 0.474779},
{-0.325911, -1.025640},
{0.865542, -0.618799},
{0.090815, 0.419351},
{-0.369454, 0.294803},
{-0.482744, 0.221822},
{0.445478, 0.125008},
{-0.966671, -0.026235},
{-0.173210, -0.453061},
{0.302727, -0.503564},
{-0.970381, 0.344969},
{0.318373, 0.398460},
{-0.557221, 0.844919},
{0.983052, -0.000581},
{-0.551473, 0.912465},
{0.515336, 0.054156},
{0.928301, 0.361197},
{0.496398, -0.063496},
{-0.077390, -1.016462},
{0.525593, 0.879311},
{0.581996, 0.123192},
{0.627640, -0.678406},
{-0.345232, 0.331676},
{0.899028, -0.373113},
{0.702078, 0.673463},
{-0.521317, 0.060243},
{-0.601738, -0.803358},
{0.398823, -0.085422},
{0.032989, 0.474670},
{0.800714, -0.591061},
{0.986086, 0.165684},
{-0.388703, 0.894500},
{1.032332, 0.449815},
{0.192942, 0.867326},
{-0.771062, -0.519478},
{1.005554, -0.117033},
{0.461506, 0.288624},
{-0.154530, -0.544829},
{-0.486015, 0.118645},
{0.376450, 0.309615},
{-0.806289, 0.630394},
{-0.319940, 0.411189},
{0.051525, 1.040204},
{0.950788, -0.421353},
{0.701025, -0.743509},
{0.112522, -0.535038},
{-0.759595, 0.698365},
{0.491356, -0.121127},
{-0.127813, -0.417265},
{0.514028, 0.048678},
{-0.035365, -0.488239},
{-0.305626, -0.487870},
{-0.051946, 0.474658},
{0.744777, -0.663359},
{0.299279, -0.377281},
{0.550034, 0.198919},
{-0.166453, 0.913321},
{-1.021316, 0.299421},
{-0.827893, 0.606640},
{-0.187675, 0.969991},
{0.449252, -0.085263},
{-0.767316, 0.634944},
{-1.024035, -0.060637},
{0.168887, 0.941176},
{-0.897486, -0.361963},
{-0.332873, 0.966020},
{0.392346, -0.897803},
{1.044408, 0.227324},
{-0.367036, -0.838350},
{-0.504571, 0.032648},
{0.780275, 0.532232},
{0.679892, 0.708961},
{-0.439129, -0.124304},
{-0.956624, -0.122037},
{0.354346, 0.379391},
{1.030654, -0.035462},
{-1.006929, 0.022802},
{-0.518946, 0.771745},
{-0.219357, -0.371995},
{-0.194638, 0.431672},
{-0.805356, 0.600714},
{0.050899, -0.462852},
{0.432222, -0.317450},
{-0.988473, -0.345247},
{0.461139, -0.209826},
{0.061760, 0.481055},
{0.984321, 0.331883},
{-0.192602, 0.996800},
{-0.221280, -0.940994},
{0.219954, -0.490378},
{-0.604191, -0.877882},
{0.238072, -0.935167},
{0.700646, 0.642798},
{-0.448660, -0.875638},
{-0.679051, 0.704965},
{-0.323195, -0.334981},
{0.290347, 0.329250},
{0.802618, 0.552108},
{0.035006, -0.933954},
{0.094873, 1.014236},
{-0.461481, 0.032805},
{0.374549, -0.395426},
{-0.497669, -0.866975},
{0.564980, 0.771422},
{-0.755256, 0.591953},
{0.853036, 0.620307},
{0.881031, 0.368812},
{-0.519580, 0.063204},
{0.516245, 0.100368},
{0.450105, 0.087523},
{-0.208434, -0.373102},
{-0.311449, 0.278894},
{0.403683, -0.356229},
{-0.973684, 0.398929},
{0.201784, -1.004757},
{0.558343, -0.740753},
{0.034402, -0.950940},
{0.245965, 0.440794},
{0.355503, -0.430036},
{0.553435, -0.246366},
{-0.991333, -0.317265},
{0.642115, -0.854216},
{0.550148, 0.024761},
{0.451398, -0.191057},
{-0.208500, -0.514551},
{-0.722274, 0.709757},
{0.089467, -0.505752},
{0.320688, 0.183011},
{0.496722, -0.891702},
{-0.372067, -0.909623},
{0.241996, 1.051972},
{-0.958143, 0.275267},
{0.370231, -0.298906},
{-0.597011, -0.848203},
{0.931080, 0.414752},
{1.010477, -0.086310},
{0.487209, 0.864507},
{0.555038, 0.054017},
{-0.704031, -0.667664},
{-0.154694, -0.474038},
{0.133300, 0.494701},
{0.090005, -0.476426},
{-0.019342, 0.399014},
{-0.869800, -0.489999},
{0.035840, 1.031111},
{0.018195, -0.985033},
{-0.299542, -0.310752},
{-0.899981, -0.395739},
{-0.899360, 0.402692},
{0.585884, -0.779693},
{0.809335, -0.638818},
{-0.974411, 0.258079},
{-0.721276, -0.608132},
{-0.184171, 0.384248},
{1.066470, 0.177712},
{0.132497, 0.506993},
{-0.457500, 0.056175},
{-0.470025, 0.082220},
{0.435519, -0.092114},
{0.301192, -0.468054},
{-0.378981, 0.312109},
{0.363742, -0.411328},
{-1.008506, 0.203303},
{-0.738627, -0.745201},
{-0.899889, 0.537853},
{0.451594, 0.087341},
{0.028924, -0.527891},
{-0.835159, -0.554372},
{0.134479, 0.926280},
{0.948206, -0.445523},
{0.474911, -0.056195},
{0.511050, 0.918605},
{0.460029, 0.299129},
{-0.178995, -0.395847},
{-0.413853, -0.332490},
{0.429056, 0.315831},
{0.744840, 0.635992},
{0.009672, 0.490753},
{-0.370538, -0.237352},
{-1.003524, 0.295700},
{-0.929624, -0.184736},
{-0.314313, -0.366878},
{-1.014434, -0.121328},
{-0.989514, -0.080057},
{0.225726, 0.533268},
{-0.028389, -0.531210},
{0.596054, 0.875477},
{-0.231779, -0.522481},
{-0.481723, -0.038715},
{-0.252789, 1.029409},
{-0.097026, -0.428761},
{0.944188, 0.195783},
{-0.312067, -0.290475},
{0.533306, 0.040163},
{-1.064723, -0.110085},
{-0.540323, 0.805300},
{-0.453397, 0.841064},
{-0.522874, 0.117572},
{0.909542, 0.319463},
{0.233413, -0.948346},
{0.735792, -0.565654},
{-0.426096, -0.860008},
{0.306204, -0.376464},
{0.513797, -0.080315},
{-0.567029, 0.050771},
{-0.357161, 0.433139},
{-0.367562, -0.336762},
{0.612312, 0.832645},
{-0.332439, 0.381784},
{-0.954311, -0.024405},
{0.216949, 0.519744},
{0.488314, -0.871016},
{-0.245132, 0.410721},
{0.351714, -0.924785},
{-0.031865, -0.433848},
{-0.365679, 0.446656},
{0.478104, -0.866874},
{0.455618, 0.247756},
{0.169163, 0.419925},
{0.840899, -0.674092},
{0.221998, -1.013374},
{-0.392459, 0.340925},
{1.028387, -0.204017},
{0.131400, 0.948342},
{0.939001, -0.675875},
{-0.460551, 0.884335},
{0.876336, -0.446613},
{-0.419194, 0.009156},
{-0.369248, 0.247624},
{-0.305214, -0.466132},
{0.266818, 0.474927},
{0.953633, -0.318703},
{0.482722, -0.107249},
{-0.904048, 0.507719},
{0.439848, 0.907631},
{0.084049, -0.529169},
{0.237457, 0.995416},
{-0.173878, -0.395430},
{0.450156, -0.958853},
{0.336825, 0.991952},
{0.460242, 0.869154},
{-0.333714, 0.428898},
{0.366839, 0.321966},
{0.391169, 0.104227},
{0.447770, -1.028608},
{0.540066, -0.119012},
{-0.243343, -0.398468},
{-0.917746, -0.338820},
{0.721882, 0.753841},
{1.001621, -0.088740},
{-0.984483, 0.264624},
{-0.360019, -0.382035},
{0.405406, 0.317800},
{0.406108, 0.319288},
{0.473152, 0.028579},
{-0.074484, 0.556967},
{0.010953, -0.566084},
{0.393257, -0.414675},
{0.407159, -0.223823},
{-0.417633, 0.189307},
{0.678347, -0.728900},
{0.577653, 0.773425},
{0.466233, 0.230573},
{-0.163636, 0.487134},
{0.370502, -0.277420},
{-0.740525, -0.636081},
{-0.433690, 0.296692},
{0.202976, -0.938022},
{-0.415849, 0.220315},
{-0.449295, 0.203081},
{-0.495797, -0.817518},
{0.874216, -0.377343},
{-0.983755, -0.015402},
{-0.124427, 0.601232},
{-0.485739, -0.245096},
{-0.878236, -0.182226},
{-0.881333, -0.318121},
{-0.390600, -0.350182},
{0.081729, 0.996557},
{0.891666, -0.478845},
{0.365114, 0.226572},
{-0.881245, -0.513695},
{0.508938, -0.062032},
{-0.101059, -0.463196},
{1.010469, -0.165137},
{-0.607886, 0.667311},
{-0.464874, 0.107424},
{-0.531313, 0.003952},
{0.595537, -0.764054},
{0.942425, -0.125652},
{-0.648483, -0.918233},
{0.916670, -0.556077},
{0.992609, 0.002324},
{-0.046385, 0.556241},
{-0.476001, -0.206958},
{-0.454945, -0.227882},
{-0.983195, 0.413575},
{0.583945, 0.884536},
{-0.190500, 0.906293},
{0.330712, 0.300851},
{-0.495760, 0.988711},
{0.543964, -0.059297},
{-0.358287, -0.264572},
{0.223275, -0.534666},
{-0.541845, -0.122202},
{-0.125065, -0.433062},
{-1.016218, 0.029935},
{-0.504339, 0.866565},
{0.950125, -0.121832},
{0.980363, 0.267497},
{0.394181, 0.391181},
{0.230903, -0.407107},
{0.849827, -0.484925},
{-0.536631, -0.184924},
{0.984419, 0.065796},
{0.461853, 0.934906},
{0.416901, 0.334080},
{-0.946590, 0.205127},
{-0.741713, 0.615476},
{0.926394, -0.376759},
{-0.284763, 0.318066},
{-0.080446, -0.463094},
{-0.992389, 0.046124},
{-0.276708, -0.440953},
{-0.332416, 0.924615},
{-0.945089, 0.287879},
{-0.103122, -0.462234},
{0.311354, -1.044021},
{-0.771181, -0.637471},
{0.770971, 0.518756},
{-0.086222, 0.427731},
{-0.466227, 0.872673},
{0.690939, -0.785689},
{0.548732, 0.800597},
{0.444045, -0.086904},
{0.391039, -0.378106},
{0.142521, -0.958676},
{0.510387, 0.929678},
{-0.284864, 0.497143},
{-0.408416, -0.285712},
{0.281564, 0.351807},
{0.992714, -0.332831},
{0.454432, 0.869861},
{-0.258281, 0.304245},
{-0.325406, -0.344919},
{0.984775, 0.074724},
{-0.477904, -0.909029},
{0.320254, 0.409001},
{-0.042222, 0.379767},
{0.614195, -0.827724},
{0.040221, 0.326742},
{-0.274337, -0.345170},
{-1.003709, -0.250561},
{0.474003, -0.110149},
{-1.077146, 0.193423},
{0.327366, 0.945689},
{-1.027258, 0.302112},
{-0.897435, 0.588509},
{0.106834, -0.419810},
{0.357477, -0.950413},
{-0.460222, -0.307745},
{-0.659331, 0.726169},
{-0.125560, -0.463263},
{0.445107, -0.157654},
{-0.568031, 0.195085},
{-1.014986, -0.235421},
{-0.701418, -0.750731},
{-0.405717, -0.894773},
{-0.179560, -1.004727},
{-0.220206, 0.435017},
{0.053922, 0.467573},
{-0.348787, -0.169544},
{-0.053541, -1.082162},
{0.116742, -0.524175},
{-0.353468, -0.342156},
{-0.542439, -0.043689},
{-0.026337, 0.517938},
{0.217994, 0.920258},
{-0.981648, 0.315322},
{0.905878, 0.451923},
{-0.464861, 0.070224},
{0.360896, -0.342396},
{0.418600, -0.258813},
{-0.806425, -0.662186},
{0.271735, 0.433591},
{-0.422813, -0.256724},
{0.109504, -0.457610},
{0.149350, -0.490384},
{-0.899182, -0.470314},
{0.467307, 0.061304},
{0.243285, 0.333500},
{0.307520, -0.408844},
{0.428611, 0.307305},
{-0.338755, 0.382677},
{0.276947, -0.921600},
{-0.019245, 0.497374},
{-0.954131, 0.217698},
{-0.344901, -0.445352},
{-0.292174, 0.309940},
{-0.494543, -0.073494},
{-0.728477, -0.650504},
{-0.514548, -0.089884},
{0.360816, -0.407978},
{0.739496, -0.685008},
{0.067760, -0.934016},
{0.576356, -0.810586},
{0.321006, -0.972535},
{0.213011, 0.388703},
{-0.745160, -0.618341},
{0.491501, 0.118117},
{-0.796973, 0.595279},
{-0.045844, 0.468815},
{1.001157, -0.178135},
{0.942886, -0.351557},
{0.331833, 0.330623},
{-0.141553, 0.556938},
{-0.477403, -0.161101},
{-0.369510, 0.244190},
{0.242561, -0.577656},
{-0.733119, -0.587480},
{0.178210, -0.981741},
{0.348704, 0.935786},
{0.252215, 0.975301},
{-0.493787, 0.037428},
{0.550540, -0.100111},
{-0.504781, 0.079933},
{0.273486, 0.333708},
{-0.149994, 0.388655},
{-0.247735, -0.549131},
{0.455940, -0.903726},
{0.358295, -0.932358},
{0.224732, 0.964639},
{0.538466, 0.730261},
{-0.343736, 0.279659},
{0.444942, -0.916538},
{-0.231686, -0.422261},
{-0.978419, 0.325287},
{-0.655643, -0.810852},
{-0.426042, -0.878073},
{0.291281, -0.381267},
{-0.135738, -0.494186},
{0.705822, 0.736291},
{0.516533, 0.269974},
{-0.767511, -0.425239},
{-0.523601, 0.092158},
{1.000695, 0.314966},
{0.301603, 0.421054},
{-0.008160, -0.544579},
{-0.064308, 0.450383},
{0.858791, -0.231316},
{0.487322, -0.232450},
{0.440480, -0.251661},
{0.476227, 0.068865},
{0.226160, 0.439081},
{-0.026710, -0.946614},
{0.329355, -0.260583},
{0.800360, 0.561859},
{-0.390560, -0.889959},
{-0.506943, -0.883699},
{-1.034389, 0.287685},
{-0.342719, 0.977152},
{0.355106, 0.932132},
{-0.397898, 0.188358},
{-0.530487, -0.137700},
{0.524106, 0.239887},
{-0.472427, -0.856932},
{0.110046, -0.521439},
{0.152209, 1.061592},
{0.492374, 0.239054},
{0.142710, 0.904405},
{0.002087, -0.534016},
{0.238633, -0.348559},
{0.462593, 0.925018},
{-0.012578, 0.957160},
{0.454616, 0.864379},
{0.268653, -0.377859},
{0.190130, 0.478896},
{-0.123566, 0.960644},
{-0.792596, 0.669592},
{0.965816, 0.288679},
{0.437699, 0.097823},
{-0.412824, 0.959961},
{0.576257, -0.740743},
{1.068025, 0.267385},
{-0.577311, 0.120711},
{0.407283, -0.212444},
{-0.397210, 0.234002},
{0.252226, 0.526789},
{-0.874150, 0.339354},
{-0.413585, 0.091574},
{-0.062437, 0.982064},
{-0.935365, -0.476033},
{0.533594, -0.055220},
{0.345678, 0.443038},
{0.928102, -0.202280},
{0.096503, 0.603694},
{-0.795526, 0.657247},
{0.828283, 0.561331},
{0.376683, 0.194640},
{-0.177283, -0.986708},
{-0.040941, 0.470609},
{0.276590, -0.442912},
{0.271131, -0.456701},
{0.254383, -0.453384},
{0.416401, 0.342874},
{0.730008, -0.714453},
{-0.290483, -0.378248},
{0.224182, -0.526300},
{0.468004, -0.850300},
{-0.475102, -0.201755},
{-0.150610, 0.964198},
{-0.374576, 0.296889},
{0.326127, -0.403445},
{0.293239, -0.358646},
{0.977400, -0.246636},
{0.839435, -0.390965},
{-0.312602, 0.329096},
{0.396110, -0.188653},
{-0.345810, 0.979769},
{-0.235239, 0.424713},
{-0.121138, 0.492547},
{0.920001, 0.579908},
{0.956540, 0.190687},
{-0.274876, 0.989650},
{0.437722, 0.243599},
{0.991046, -0.119906},
{-0.456911, -0.106230},
{0.585620, 0.828932},
{0.153801, 0.928593},
{0.462057, -0.290546},
{-0.217044, 0.990277},
{-0.584347, 0.694665},
{0.936432, 0.387643},
{0.189225, -0.933064},
{0.077744, -0.555827},
{-0.366123, -0.922218},
{-0.761475, 0.704149},
{-0.699725, -0.734398},
{0.439303, 0.819247},
{0.557673, -0.079411},
{-0.265055, -0.604687},
{0.045423, 0.485691},
{0.871393, -0.597538},
{-0.578653, -0.051956},
{0.210804, 0.400319},
{-0.005140, 0.587265},
{1.021576, 0.175319},
{-0.493216, 0.058602},
{0.391830, 1.011464},
{0.112199, 0.505886},
{-0.494688, -0.166269},
{0.879432, -0.408510},
{0.328677, 0.401118},
{0.239682, 0.419771},
{0.219065, -0.935714},
{-0.325962, 0.335467},
{0.410568, 0.903644},
{0.954673, -0.031991},
{-0.165429, -0.445167},
{-0.308758, 0.506077},
{-0.949142, 0.410075},
{0.025179, 1.086534},
{-0.282731, -0.401589},
{-0.751915, -0.540239},
{0.401528, -0.954622},
{-0.325838, 0.320585},
{-0.789071, 0.652788},
{-0.067263, -0.415211},
{-0.342763, -0.500473},
{0.614655, 0.772828},
{0.193913, -0.416394},
{0.598747, -0.897963},
{0.017949, -0.549917},
{-0.777863, 0.681901},
{-0.622935, -0.776148},
{-0.842153, -0.513615},
{-0.342361, -0.285485},
{-0.479340, -0.257759},
{-0.647113, 0.708901},
{0.404161, 0.178805},
{-0.592213, -0.095235},
{-0.331177, -0.271972},
{0.977967, 0.215754},
{-0.452242, 0.119274},
{-0.898306, 0.546823},
{0.470385, 0.097732},
{1.074445, 0.120241},
{0.311009, 0.477228},
{-0.498992, 0.230706},
{0.553832, 0.558558},
{0.436860, 0.156143},
{-0.444444, 0.249753},
{0.486519, -0.106007},
{-0.421283, 0.180623},
{-0.406001, 0.247732},
{0.450869, 0.165908},
{-0.036799, -1.048837},
{-0.204806, 0.991814},
{-0.469319, -0.237311},
{0.960148, -0.029572},
{0.290759, -0.931106},
{0.457885, 0.727751},
{0.990829, -0.109917},
{-0.020007, 0.545816},
{0.709308, 0.874297},
{-1.010977, -0.074784},
{0.473314, 0.926140},
{1.045204, 0.166321},
{0.388059, -0.312612},
{-0.110272, -1.061526},
{-1.022783, 0.071001},
{-0.879856, 0.008920},
{-0.044214, 0.935743},
{0.085258, 0.472718},
{-1.010090, 0.084493},
{-0.153919, 0.507331},
{-0.914801, -0.077787},
{0.397552, 0.253458},
{-0.071208, -0.584040},
{-0.586113, 0.822001},
{-0.315848, -0.428398},
{-0.475201, 0.045856},
{0.119077, 0.958341},
{-0.004970, -0.633133},
{-0.091496, -1.063429},
{-0.977251, 0.001460},
{0.105994, 0.535126},
{0.906682, -0.362689},
{0.419639, 0.227265},
{-0.128094, 0.443781},
{-0.236173, -0.421747},
{-0.561705, -0.149725},
{-0.399144, -0.315863},
{0.249800, 0.456173},
{-0.067688, 0.474221},
{-0.403660, -0.089936},
{0.422568, -0.195349},
{-0.507068, 0.236393},
{-0.049440, 0.494637},
{0.573601, 0.160837},
{-0.957441, 0.346013},
{-0.103069, 0.984878},
{0.732054, 0.654709},
{0.505812, -0.848135},
{0.136014, 0.432586},
{0.423961, -1.023403},
{-0.993448, -0.073076},
{0.716949, 0.686259},
{-0.475708, -0.013893},
{-0.932824, -0.520301},
{0.507099, 0.099702},
{-0.536745, -0.061553},
{-0.749363, 0.642360},
{0.871757, 0.398393},
{0.139424, -0.579037},
{-0.513559, 0.829711},
{0.216548, 0.518864},
{0.528756, -0.211615},
{-0.498062, 0.252568},
{-0.961372, -0.198659},
{-0.997016, 0.387509},
{-0.665681, 0.794896},
{0.479599, 0.001011},
{-0.491049, 0.160684},
{0.418982, -0.324877},
{0.513648, 0.881750},
{0.389844, 0.224851},
{0.909708, 0.223947},
{-0.320696, -0.223657},
{0.195747, 0.454857},
{-0.472384, -0.971927},
{0.818149, -0.552201},
{0.300139, 1.023248},
{-0.475618, 0.766312},
{0.952992, -0.295727},
{-0.156673, -0.960558},
{-0.072489, -1.029532},
{0.565584, -0.871809},
{0.968489, -0.416161},
{-0.158193, -0.469685},
{-0.035628, -0.566708},
{-0.868991, -0.393100},
{0.120758, 0.482890},
{-0.499142, -0.133691},
{0.718468, -0.673767},
{0.483947, 0.200953},
{0.504083, -0.092725},
{-0.380365, -0.348349},
{0.644130, 0.753145},
{0.325310, 0.443521},
{-0.712700, -0.626573},
{0.432635, -0.220105},
{0.509025, -0.003331},
{-0.140491, 0.458993},
{0.554641, 0.831357},
{0.382893, 0.180935},
{0.856840, 0.624508},
{0.306591, 0.314238},
{-0.157257, -0.989907},
{0.271623, 0.321017},
{0.045540, 1.064526},
{0.742861, 0.603701},
{-0.076098, -0.977182},
{0.897281, -0.340274},
{-0.878503, 0.487946},
{0.361002, -0.343894},
{0.236070, -0.887971},
{-0.418928, 0.076475},
{0.310445, -0.936192},
{-0.679949, 0.792224},
{-0.238985, 0.434101},
{0.222413, -0.405034},
{0.473205, 0.034184},
{0.406588, 0.274089},
{-0.345188, -0.358048},
{0.017197, -0.945138},
{0.913779, -0.598842}
};
static const std::vector<short> noisy_circles_labels {
0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0,
};
static const std::vector<cv::Vec2f> noisy_moons {
{0.496271, -0.342753},
{-0.166300, 0.922342},
{0.718956, 0.665290},
{-0.337840, 0.912074},
{0.103768, 0.116946},
{0.702804, 0.667720},
{-0.614904, 0.881684},
{0.667835, -0.456815},
{0.803439, 0.768419},
{0.434519, 0.833548},
{-0.451526, 0.867688},
{0.573179, -0.413433},
{1.566417, -0.440186},
{1.396258, -0.353635},
{1.011969, -0.562964},
{1.071866, -0.033929},
{-0.067705, 0.985937},
{1.739636, -0.173039},
{0.214441, -0.128790},
{0.984292, -0.469513},
{1.998867, 0.349441},
{1.132009, -0.548606},
{0.082511, 0.989596},
{0.713686, -0.499899},
{-1.036180, 0.389093},
{0.475082, -0.369990},
{0.185801, 0.952638},
{0.119731, 0.022406},
{1.993655, 0.445478},
{0.637446, 0.747901},
{1.068196, -0.482278},
{-0.148474, 1.050313},
{0.386807, 0.980657},
{-0.178671, 0.940450},
{1.282258, -0.396343},
{-0.980326, 0.100863},
{1.987377, 0.464477},
{0.126748, -0.112373},
{0.444394, -0.291783},
{0.615013, 0.724495},
{-0.907856, 0.515206},
{0.006890, 0.971489},
{1.815501, 0.005442},
{1.973811, 0.316884},
{0.888139, -0.557867},
{0.013169, 1.014930},
{1.958637, 0.154446},
{0.466269, 0.879144},
{0.423977, 0.988572},
{0.669984, 0.789333},
{0.549956, 0.826760},
{0.652881, 0.678939},
{0.167620, 0.124025},
{2.021983, 0.289367},
{2.036312, 0.392123},
{-0.705304, 0.802209},
{0.721721, -0.446847},
{-1.057252, 0.288871},
{0.538738, 0.707988},
{-0.730453, 0.641255},
{-0.085058, 1.040617},
{0.446517, 0.817575},
{0.895367, 0.414274},
{0.299042, -0.121882},
{0.340815, -0.268886},
{0.640343, -0.425107},
{-0.104821, 0.874745},
{1.025808, 0.030871},
{1.500083, -0.388380},
{1.058557, -0.486871},
{0.153143, 0.143906},
{0.698832, 0.732750},
{0.337857, 1.001806},
{0.582376, 0.779731},
{0.516631, 0.908242},
{-0.012161, 0.549717},
{0.377415, -0.209377},
{0.398307, 0.876080},
{0.079609, 0.407017},
{0.932146, 0.253114},
{0.390304, -0.209082},
{-0.548919, 0.775369},
{0.601761, -0.472310},
{0.330164, -0.214821},
{1.870198, 0.073266},
{0.239898, -0.051028},
{-0.173536, 1.009318},
{0.596136, -0.400319},
{0.573521, -0.352605},
{2.056516, 0.169410},
{0.608283, 0.768349},
{0.009094, 0.943835},
{0.940722, 0.280645},
{0.460975, -0.396293},
{1.592816, -0.425294},
{1.495644, -0.381199},
{1.721367, -0.131403},
{1.575977, -0.286960},
{0.020088, 0.569959},
{0.811551, 0.576702},
{0.055550, 0.272523},
{1.819475, -0.054582},
{1.103558, -0.453437},
{0.409392, 1.025252},
{0.737369, 0.751975},
{0.872074, 0.504964},
{0.785829, -0.466771},
{0.962392, -0.564115},
{-0.110210, 0.953938},
{-0.070268, 0.997614},
{1.378774, -0.458579},
{1.738328, -0.388595},
{0.639144, -0.496515},
{0.078786, -0.000002},
{0.040087, 0.090268},
{1.576896, -0.287797},
{-0.200912, 1.063326},
{0.998387, 0.144506},
{0.323512, -0.122834},
{0.264926, 1.015290},
{0.100261, -0.065602},
{1.658930, -0.317580},
{1.947505, 0.131751},
{0.983862, -0.484429},
{0.157345, -0.017765},
{0.891421, -0.564348},
{1.660918, -0.357718},
{-0.800244, 0.655224},
{-0.887394, 0.572426},
{0.192676, -0.208585},
{0.436821, -0.373582},
{1.544492, -0.292624},
{0.781851, 0.650672},
{-0.974938, 0.423303},
{2.057088, 0.445394},
{0.104283, 0.139031},
{-0.900360, 0.514926},
{0.110123, 0.152040},
{0.132428, -0.100307},
{1.588997, -0.316330},
{0.635979, -0.299898},
{-0.931900, 0.393856},
{0.439267, -0.440381},
{0.141521, 0.106246},
{-0.918870, 0.431856},
{0.962587, -0.431892},
{-0.217579, 0.993247},
{0.800562, -0.441895},
{-1.040423, 0.047103},
{1.044428, 0.208865},
{1.810265, 0.077613},
{1.759604, -0.009136},
{0.902235, 0.578826},
{-0.012210, 0.400599},
{-0.821795, 0.444680},
{0.193363, -0.173325},
{1.713100, -0.297758},
{-0.967452, 0.222840},
{1.055905, -0.589195},
{0.504378, 0.887087},
{0.547195, 0.819841},
{0.299226, -0.193671},
{1.487537, -0.376296},
{0.835609, 0.513659},
{0.658154, -0.423461},
{1.233342, -0.417314},
{0.809141, 0.420955},
{0.746324, 0.693303},
{0.949128, 0.445078},
{1.054587, 0.125273},
{0.517902, 0.890201},
{1.768829, -0.051471},
{0.205701, -0.161854},
{0.739271, 0.680402},
{0.262667, 0.935655},
{0.342983, -0.260148},
{1.475912, -0.406119},
{-0.504364, 0.856305},
{1.913484, 0.238542},
{0.004023, 0.175472},
{-0.554247, 0.674363},
{0.970432, 0.213194},
{0.928017, 0.114638},
{1.114424, -0.505299},
{0.413875, 1.037991},
{-0.909651, 0.566537},
{0.129417, 0.983640},
{0.252087, -0.173061},
{2.046959, 0.181122},
{0.668592, 0.790053},
{1.040943, 0.045980},
{-0.942211, 0.466921},
{0.899339, -0.583971},
{-0.948669, 0.430538},
{-0.028274, 1.008480},
{0.377596, -0.349484},
{0.177070, 0.978919},
{2.010137, 0.261438},
{-0.411131, 0.892558},
{1.306855, -0.507745},
{-1.060357, 0.038647},
{-0.736548, 0.808592},
{1.910212, 0.181975},
{0.877901, -0.447353},
{0.852328, 0.416398},
{-0.369799, 0.969105},
{1.331886, -0.389373},
{-0.020269, 0.176746},
{0.466894, -0.341575},
{-0.488444, 0.868594},
{1.583979, -0.333800},
{0.680046, -0.516741},
{-0.433420, 0.840947},
{2.047737, 0.115775},
{-0.025382, 0.204912},
{0.040868, 0.437197},
{1.409347, -0.322897},
{0.241290, -0.148644},
{0.547439, 0.792839},
{0.419439, 0.934155},
{0.990374, 0.317210},
{-0.932609, 0.226892},
{0.964145, 0.154370},
{0.365350, 0.880556},
{1.966250, 0.282548},
{1.382008, -0.428482},
{1.774570, -0.079093},
{1.279362, -0.475287},
{-0.327030, 0.942494},
{-0.846831, 0.598684},
{1.821176, 0.154144},
{-0.297012, 0.964664},
{0.284678, -0.246232},
{0.036619, 0.871615},
{-0.882686, 0.561393},
{0.463534, -0.405212},
{-1.019289, 0.096581},
{1.186580, -0.503269},
{1.064199, 0.203492},
{-0.014080, 0.984262},
{-0.260531, 0.937734},
{0.476119, 0.888053},
{-0.899156, 0.370780},
{-0.967527, 0.198586},
{0.080516, 0.304394},
{-0.152795, 0.994968},
{0.134037, -0.026378},
{0.342460, 0.048616},
{0.789416, -0.523685},
{1.758768, -0.136356},
{0.380487, 0.954451},
{0.291565, -0.184119},
{-0.571589, 0.771131},
{-0.078582, 0.267424},
{-0.897296, 0.405563},
{-0.734993, 0.686952},
{-0.082654, 0.991224},
{0.358199, -0.181583},
{0.458459, -0.396925},
{0.172811, 0.984229},
{0.740393, -0.470821},
{1.006055, 0.239333},
{-0.431573, 0.914546},
{1.696607, -0.309738},
{1.932289, 0.376846},
{0.929765, 0.453516},
{2.035588, 0.568315},
{0.976158, 0.124099},
{0.463355, -0.424725},
{-0.601509, 0.752203},
{-0.562183, 0.802706},
{0.572949, 0.839057},
{0.405519, -0.279836},
{1.357518, -0.454862},
{0.096638, 1.016000},
{-0.890866, 0.537476},
{0.086266, -0.108601},
{-0.282772, 0.980814},
{0.471907, 0.926533},
{0.366001, 0.864812},
{0.657707, 0.909999},
{0.563240, -0.350304},
{1.001594, -0.564994},
{1.214816, -0.449014},
{1.486306, -0.402688},
{0.874145, 0.154797},
{1.836478, -0.104014},
{0.027896, 0.289415},
{-0.025324, 0.509605},
{0.616038, 0.919443},
{0.028360, 0.464538},
{0.752592, 0.689399},
{0.590992, 0.717415},
{0.017417, 0.978641},
{0.623180, -0.385546},
{1.963936, 0.073110},
{-0.809626, 0.504689},
{2.023012, 0.398103},
{0.282129, -0.168219},
{-0.135411, 0.934845},
{0.927352, -0.570734},
{0.701812, -0.566872},
{1.925137, 0.111727},
{-0.831711, 0.413159},
{0.381555, -0.333279},
{1.901296, 0.031873},
{-0.571052, 0.790012},
{-1.030996, 0.054978},
{1.645374, -0.130236},
{0.805682, 0.544531},
{-0.994894, 0.159745},
{0.126796, 0.142265},
{0.050546, 0.010417},
{0.263523, -0.167431},
{0.921280, 0.268062},
{-0.656305, 0.601641},
{-0.143499, 0.977204},
{0.945685, 0.585951},
{0.013709, 0.509968},
{1.729951, -0.213765},
{1.759855, 0.005968},
{1.155554, -0.474211},
{0.195909, 0.924522},
{-0.931949, 0.384193},
{0.200643, 1.056856},
{2.030331, 0.517385},
{-0.785892, 0.557837},
{1.936705, 0.058275},
{0.088427, 0.159000},
{0.366030, 0.972371},
{1.078585, -0.460590},
{1.256507, -0.459344},
{-0.946477, 0.085086},
{-1.073925, 0.177264},
{0.118155, 0.129063},
{0.036859, 0.302329},
{2.050380, 0.157713},
{0.053195, 1.025376},
{0.019131, 0.275517},
{-0.057567, 0.414117},
{0.174004, -0.151689},
{1.963096, 0.340024},
{0.792813, -0.429732},
{0.542305, 0.792847},
{1.030704, 0.020613},
{-0.870394, 0.580660},
{0.947174, -0.026291},
{-0.035915, 0.235092},
{0.912323, 0.430158},
{0.393322, 0.871471},
{1.616672, -0.278860},
{1.898796, 0.319588},
{0.143081, 0.908479},
{0.833448, 0.460590},
{0.566370, 0.795585},
{-0.795690, 0.478968},
{-0.521798, 0.763925},
{0.463918, -0.427475},
{0.972411, 0.172115},
{0.328914, 0.989370},
{-0.330882, 0.879693},
{1.340195, -0.452956},
{-0.356462, 0.927992},
{-0.223078, 0.927490},
{0.206803, -0.043373},
{-1.059685, 0.207520},
{-0.886412, 0.239992},
{0.727928, 0.569232},
{2.014097, 0.407058},
{1.108755, 0.075316},
{-0.923454, 0.049743},
{0.407518, 0.917457},
{0.906429, 0.078531},
{1.610760, -0.274863},
{1.068399, -0.557376},
{1.843047, -0.028402},
{0.274464, -0.211134},
{0.914475, 0.229288},
{1.383910, -0.409746},
{1.862668, 0.396777},
{-0.012625, 0.462519},
{1.689782, -0.178566},
{0.262078, -0.241627},
{-0.047884, 0.973583},
{0.880122, -0.529893},
{0.902445, -0.491365},
{-0.019043, 0.040873},
{0.707514, -0.391041},
{-0.724897, 0.693954},
{0.372070, 0.914303},
{0.927815, 0.355252},
{0.794788, -0.532710},
{-0.957853, 0.179512},
{0.735042, -0.526675},
{-0.844149, 0.537472},
{1.585073, -0.250573},
{0.875332, -0.485010},
{0.796758, -0.493820},
{-0.872319, 0.258632},
{0.603286, -0.335370},
{-0.695870, 0.646880},
{-0.498993, 0.894352},
{0.162072, 0.982262},
{2.007652, 0.283631},
{1.978689, 0.382974},
{-0.805040, 0.470932},
{1.962411, 0.161136},
{0.930354, -0.537602},
{0.934006, 0.067405},
{-0.754532, 0.540486},
{-0.604119, 0.716755},
{-0.974534, 0.157934},
{-0.055294, 0.985908},
{1.693047, -0.202096},
{-0.811544, 0.595923},
{0.988753, 0.259068},
{0.910798, 0.379193},
{-0.682960, 0.750650},
{1.190720, -0.564751},
{1.682545, -0.261579},
{1.047946, -0.427851},
{-0.868704, 0.378066},
{-0.613038, 0.816375},
{1.642798, -0.240747},
{0.716391, 0.720832},
{0.014638, 0.423205},
{0.128033, 0.956122},
{-0.478291, 0.912955},
{1.066181, 0.076145},
{-0.775598, 0.623022},
{1.024819, 0.058190},
{-1.016538, 0.131743},
{1.993535, 0.373910},
{0.484023, 0.906797},
{0.643277, 0.716530},
{0.250731, -0.075192},
{1.282402, -0.457561},
{-0.658440, 0.773163},
{0.647803, -0.494807},
{0.858833, 0.481916},
{-0.982523, 0.330829},
{1.055949, -0.526800},
{-0.481049, 0.998914},
{0.011470, 1.010560},
{1.919935, 0.049774},
{1.011512, -0.114710},
{0.870945, 0.548585},
{-0.539433, 0.897177},
{0.023966, 0.047861},
{0.086763, 0.968948},
{0.792762, 0.667084},
{0.803375, 0.553578},
{1.047347, 0.197931},
{0.273136, -0.208467},
{0.463516, 0.931923},
{1.001583, -0.527386},
{0.263144, 0.834717},
{0.040992, 0.896198},
{0.529531, -0.333572},
{1.849525, -0.116135},
{2.010013, 0.341519},
{0.954687, 0.056256},
{-0.961819, 0.555229},
{-1.037350, 0.178098},
{1.959100, 0.281157},
{0.544748, -0.375624},
{1.713845, -0.172761},
{1.948518, 0.193389},
{1.585462, -0.303281},
{0.887551, -0.496036},
{0.017488, 0.961959},
{1.007602, 0.131019},
{0.765145, -0.510643},
{0.188689, -0.118159},
{-0.016115, 0.235161},
{0.837375, 0.375398},
{1.974453, 0.550002},
{1.869913, -0.159721},
{-0.051454, 0.221528},
{0.981590, 0.134119},
{1.476609, -0.368615},
{-0.623378, 0.783102},
{0.623551, 0.791507},
{-0.615059, 0.748300},
{1.509050, -0.383068},
{0.971287, -0.404530},
{1.670550, -0.266694},
{2.057936, 0.172495},
{0.392840, 1.012723},
{0.611677, 0.798972},
{-0.630367, 0.909643},
{0.085440, 0.004517},
{0.666127, 0.825488},
{0.414683, 0.919746},
{-1.001736, -0.053692},
{2.042805, 0.504148},
{0.737137, -0.425287},
{0.888802, 0.554820},
{-0.791947, 0.641675},
{1.516305, -0.409061},
{-0.840593, 0.539072},
{-0.105039, 1.011806},
{1.369623, -0.547646},
{0.042257, 0.254585},
{0.811323, 0.683292},
{1.576423, -0.262082},
{0.184115, 0.931668},
{0.946175, -0.470095},
{0.256002, 0.969496},
{0.123463, 0.998779},
{0.779836, -0.406278},
{1.299751, -0.458160},
{0.246294, 1.006846},
{1.258167, -0.510401},
{0.991527, 0.151969},
{1.429809, -0.375911},
{0.168439, 0.036398},
{0.817818, -0.439428},
{0.250526, -0.167255},
{0.028227, 0.452056},
{-0.176511, 1.006626},
{0.669383, 0.737935},
{-0.778768, 0.689070},
{2.014209, 0.348268},
{-0.668901, 0.631334},
{0.700043, 0.775122},
{0.127051, 0.966583},
{-0.615550, 0.803914},
{-0.638229, 0.784227},
{1.637936, -0.255958},
{0.601378, -0.368817},
{0.977976, -0.535715},
{1.933565, 0.315332},
{1.392589, -0.299979},
{-0.988392, 0.225844},
{1.810280, -0.101660},
{1.658857, -0.289555},
{-0.510122, 0.996818},
{-0.398897, 0.834220},
{1.503831, -0.270006},
{-0.297766, 0.931551},
{1.038481, -0.574859},
{0.595492, 0.725707},
{-0.788434, 0.711187},
{-0.961470, 0.252442},
{-0.013059, 0.918064},
{0.846959, 0.620696},
{0.594875, -0.415357},
{-0.978066, 0.463218},
{1.190432, -0.517136},
{1.878252, 0.002960},
{1.924820, 0.123009},
{0.954405, 0.379896},
{0.405748, -0.322683},
{0.089029, 0.148671},
{-0.336937, 0.884798},
{-0.117016, 0.918931},
{0.396080, -0.334715},
{-0.921743, 0.308865},
{0.850389, 0.430958},
{0.389593, -0.277222},
{1.971562, 0.352262},
{-0.703930, 0.723667},
{2.003826, 0.110409},
{0.056923, 0.112895},
{0.861734, 0.705571},
{-0.747621, 0.702980},
{0.049177, 0.252773},
{-1.044252, 0.210782},
{1.918267, 0.106201},
{0.015492, 0.216829},
{-0.411690, 0.895506},
{-0.144124, 0.942843},
{0.444993, -0.342964},
{-0.997800, -0.022769},
{0.783241, 0.632167},
{0.069239, 0.488263},
{0.080523, 1.034611},
{0.416876, -0.287567},
{0.920497, 0.108863},
{0.682463, -0.432382},
{1.599841, -0.138063},
{-0.615892, 0.763435},
{-0.061584, 1.071994},
{1.914421, 0.067344},
{0.510691, -0.295096},
{0.236741, -0.190955},
{1.131800, -0.479509},
{0.739476, 0.653669},
{1.792722, -0.198557},
{1.572359, -0.415641},
{-0.165740, 0.934407},
{-1.017765, 0.233729},
{1.002052, 0.158603},
{0.079119, 0.084563},
{1.014845, 0.046980},
{1.816078, -0.144205},
{-0.980715, 0.171495},
{-0.703285, 0.717882},
{-0.959211, 0.262014},
{1.160088, -0.458143},
{0.005613, 0.315028},
{0.615970, -0.479113},
{0.859002, 0.526447},
{-0.405014, 0.866730},
{-0.927944, 0.120513},
{0.847125, 0.428229},
{-0.016591, 0.386431},
{-0.094287, 0.252717},
{1.220941, -0.534576},
{0.726582, 0.642565},
{0.307360, -0.178595},
{1.121450, -0.429976},
{-0.895724, 0.464041},
{0.941708, 0.338417},
{0.069426, 0.168462},
{0.824394, -0.472337},
{1.140648, -0.493586},
{-0.791807, 0.590292},
{1.743109, -0.110036},
{-0.199136, 0.987622},
{1.820615, 0.010975},
{0.079542, 0.952591},
{-0.546314, 0.779701},
{-0.919637, 0.274297},
{0.183059, 0.969702},
{0.290056, 0.859716},
{-0.270505, 0.964013},
{-0.660530, 0.714735},
{1.762770, -0.187882},
{-0.373097, 0.866083},
{0.523990, -0.396502},
{0.228475, 0.932237},
{0.806318, -0.439653},
{0.040753, 0.237637},
{1.099178, -0.483577},
{0.858106, 0.591586},
{1.271853, -0.369148},
{1.626611, -0.323550},
{-0.123639, 0.502025},
{0.130780, 1.009305},
{0.243747, -0.162773},
{0.010425, 0.566818},
{-0.508881, 0.957991},
{-0.593271, 0.753624},
{0.268535, -0.204692},
{0.418663, -0.342013},
{0.192743, -0.091517},
{-0.911233, 0.235734},
{0.878685, 0.452582},
{-0.236781, 0.973836},
{-0.773233, 0.640352},
{0.436380, -0.270300},
{-0.909861, 0.415216},
{1.684271, -0.280306},
{0.184936, 0.968389},
{1.052570, 0.178306},
{0.694703, 0.711501},
{0.286335, 0.933240},
{0.652877, 0.636946},
{1.823728, -0.184588},
{0.790306, -0.510649},
{0.356344, -0.254518},
{0.097082, 0.187908},
{0.475782, -0.274717},
{0.231007, 1.005774},
{1.795122, -0.117099},
{0.801095, 0.567066},
{0.946900, 0.240961},
{0.637972, -0.366623},
{0.304445, -0.310948},
{-0.001808, 0.451750},
{1.810474, 0.354936},
{1.013389, 0.238449},
{-0.798495, 0.460701},
{0.751566, -0.415832},
{0.247445, -0.177784},
{0.122302, 0.258487},
{0.201179, -0.173881},
{-0.837225, 0.669824},
{0.783701, 0.665509},
{-0.018040, 0.370109},
{0.437818, -0.347291},
{-0.195249, 1.072674},
{0.060387, 0.278019},
{-0.913695, 0.429943},
{1.457969, -0.290435},
{0.070242, 1.076923},
{-0.477700, 0.934233},
{1.765876, -0.226673},
{0.592394, 0.837986},
{0.950505, 0.419898},
{0.123300, 1.012986},
{0.624291, -0.421914},
{1.343748, -0.465895},
{0.650881, 0.698266},
{0.844325, -0.423582},
{0.269609, 0.830784},
{-0.123863, 1.098885},
{1.702336, -0.181974},
{1.361339, -0.412906},
{1.062883, 0.319179},
{1.869669, 0.234356},
{0.689881, -0.357275},
{-0.484569, 0.882117},
{-0.028965, 0.400626},
{-0.918874, 0.469227},
{1.113433, -0.500161},
{1.652722, -0.219777},
{1.880378, 0.279037},
{0.905364, 0.413704},
{-0.630856, 0.785450},
{0.981790, 0.172254},
{0.414366, 0.914970},
{-0.022160, 0.919562},
{0.888195, -0.436919},
{-0.041295, 0.145085},
{-0.899383, 0.418387},
{-0.506611, 0.886182},
{1.102557, -0.492328},
{0.138441, 0.981428},
{1.272340, -0.441868},
{0.958767, 0.232284},
{1.351935, -0.466713},
{0.772701, 0.661288},
{1.827292, -0.072850},
{0.097917, 0.014184},
{1.779244, 0.001716},
{0.209755, 1.021343},
{0.731039, -0.465006},
{1.132549, -0.472395},
{0.088217, 0.924143},
{1.681411, -0.125958},
{1.773324, -0.067148},
{-0.417047, 0.938815},
{-0.940901, 0.401605},
{1.063309, 0.266846},
{1.926717, 0.273951},
{1.618181, -0.322081},
{0.928029, -0.481319},
{-0.996931, 0.294634},
{1.466848, -0.427068},
{0.145702, 0.978156},
{1.863714, -0.091411},
{0.313786, 0.962891},
{-0.015516, 0.371711},
{1.814466, 0.104112},
{-0.703469, 0.829162},
{-0.219409, 1.056912},
{1.847164, -0.067939},
{1.649082, -0.430069},
{1.963644, 0.095740},
{-0.233576, 0.912699},
{-0.254144, 1.034611},
{0.947022, 0.359081},
{-0.495804, 0.776957},
{-0.010219, 0.094684},
{0.134275, -0.084927},
{0.385201, -0.217824},
{0.147113, 0.920659},
{-0.552964, 0.813835},
{1.917175, 0.299968},
{1.238795, -0.489206},
{0.806173, 0.564016},
{0.562590, 0.851649},
{2.065116, 0.576776},
{-0.209235, 0.939668},
{0.586169, -0.443558},
{0.213571, -0.185088},
{0.026146, 0.417267},
{0.888511, -0.501655},
{2.076865, 0.390374},
{0.110074, -0.072791},
{-0.702488, 0.656150},
{0.112400, 0.998404},
{0.970428, 0.408279},
{-1.037110, 0.364119},
{-0.973274, 0.242688},
{0.572525, -0.451005},
{1.530146, -0.409321},
{0.513328, 0.751046},
{0.501972, 0.872710},
{-0.095367, 0.509063},
{-0.876611, 0.247547},
{1.560595, -0.266934},
{0.272575, -0.262411},
{-0.518970, 0.897349},
{0.488126, 0.886857},
{1.801540, -0.205026},
{-1.023219, 0.079988},
{0.771314, 0.605261},
{0.704482, 0.600302},
{-1.070810, 0.074274},
{0.890178, -0.527951},
{0.933021, -0.459874},
{1.906469, 0.028193},
{-0.331577, 1.021127},
{-0.047549, 0.193271},
{1.917958, -0.009012},
{0.961895, 0.448328},
{0.805569, 0.325809},
{1.329618, -0.469317},
{0.185347, -0.048335},
{-0.115227, 0.937911},
{0.770947, -0.469683},
{0.968596, 0.455542},
{0.926832, -0.541946},
{0.541607, 0.804993},
{-0.564031, 0.875823},
{2.057631, 0.376087},
{0.140188, -0.116968},
{0.608815, 0.891560},
{0.924562, 0.502569},
{-0.369076, 0.962036},
{1.484494, -0.258392},
{1.700646, -0.134132},
{0.004085, 0.403135},
{-0.778469, 0.647700},
{1.794405, -0.096394},
{1.071993, 0.205204},
{0.577728, -0.370941},
{0.194561, 0.982626},
{-0.855157, 0.655290},
{-1.022124, -0.016234},
{-0.072611, 1.068761},
{-0.502488, 0.793466},
{-0.965752, 0.255553},
{0.964323, 0.354032},
{-0.832631, 0.644305},
{0.415497, -0.287618},
{1.483393, -0.407044},
{0.240532, 1.038227},
{0.889738, 0.587310},
{1.977431, 0.199800},
{-0.994073, 0.145032},
{0.491942, 0.871268},
{1.943857, 0.323828},
{0.553876, 0.974438},
{1.749833, -0.211385},
{0.817430, 0.683119},
{1.025486, 0.311845},
{-1.041813, 0.065283},
{0.927884, 0.266655},
{1.055491, 0.000754},
{1.617931, -0.179946},
{1.864250, 0.007130},
{-0.775088, 0.593845},
{-0.778315, 0.724098},
{-0.265298, 0.911709},
{-0.006731, 0.213446},
{1.796149, -0.077659},
{0.046005, 1.041695},
{0.278435, -0.367633},
{1.056302, 0.003752},
{-0.827518, 0.478343},
{1.761870, -0.141272},
{0.203481, 1.035961},
{0.578188, -0.455238},
{-0.353864, 0.891790},
{0.978292, -0.505724},
{0.304723, 0.872209},
{1.968029, 0.448676},
{-0.948102, 0.504910},
{0.749021, -0.430916},
{-0.168103, 0.936456},
{-0.929200, 0.402479},
{1.969431, 0.241906},
{0.139604, 0.026284},
{-0.917267, 0.414950},
{0.414750, 0.919978},
{1.137264, -0.556664},
{0.692865, 0.682379},
{1.691508, -0.117563},
{0.896428, 0.362007},
{-0.894701, 0.114668},
{0.606027, 0.829339},
{0.002779, 0.040400},
{-0.788992, 0.559568},
{1.015192, -0.063149},
{-1.127206, 0.033944},
{0.089662, -0.129168},
{-1.008327, 0.307763},
{0.857693, 0.487736},
{0.156809, 0.045769},
{2.039753, 0.536073},
{0.922407, 0.483239},
{1.023954, -0.459292},
{1.422774, -0.362877},
{0.077695, -0.005755},
{0.765989, -0.403496},
{1.755280, -0.071936},
{0.628866, 0.845062},
{1.865356, -0.094322},
{0.837605, 0.576419},
{0.856077, 0.376384},
{1.980884, 0.297995},
{-0.494306, 0.876457},
{1.163098, -0.499559},
{0.822718, 0.631627},
{1.573271, -0.323713},
{0.539157, 0.914428},
{0.115842, -0.170725},
{1.886645, 0.088309},
{0.491619, 0.831360},
{1.237571, -0.536248},
{0.948463, 0.315026},
{-1.000791, 0.077147},
{0.063607, -0.003559},
{-0.038414, 0.208159},
{1.713575, -0.201462},
{-0.777612, 0.553862},
{0.529974, -0.278545},
{2.011906, 0.490380},
{0.025160, 1.064478},
{1.851780, 0.117649},
{0.883731, 0.596139},
{1.895900, 0.255129},
{0.812410, 0.507357},
{1.322986, -0.487688},
{0.239077, 0.914062},
{0.161163, 0.954431},
{-0.714085, 0.747340},
{1.099939, -0.481123},
{1.316430, -0.439051},
{0.637417, -0.452223},
{0.709382, -0.493668},
{1.022628, 0.167743},
{0.314550, 0.977636},
{0.768385, 0.648182},
{-0.293145, 0.912156},
{0.860516, 0.186809},
{-0.788605, 0.721582},
{-0.666887, 0.769339},
{0.646930, -0.426946},
{1.672479, -0.225887},
{1.476016, -0.372136},
{-0.842952, 0.342001},
{-0.064826, 1.005730},
{0.063680, 0.027235},
{1.447327, -0.402177},
{1.532738, -0.302256},
{0.295973, 0.991352},
{1.380631, -0.498410},
{-0.302976, 0.941201},
{-0.493432, 0.859237},
{-0.999601, 0.336260},
{-0.830666, 0.718992},
{-0.980283, 0.155477},
{0.391269, -0.370320},
{1.099411, -0.559854},
{-0.275466, 0.986200},
{0.487358, -0.413786},
{-0.378258, 0.827067},
{0.496750, -0.299648},
{1.515076, -0.303851},
{0.026684, 1.014932},
{-0.098800, 1.020516},
{1.035718, -0.450237},
{0.792161, 0.729022},
{-0.658071, 0.573861},
{0.320033, -0.230940},
{0.829639, 0.565706},
{0.018966, 0.442025},
{1.606368, -0.204381},
{0.484741, -0.266998},
{1.313964, -0.456586},
{0.573980, 0.751020},
{0.007844, 0.247142},
{1.509728, -0.329699},
{0.142884, -0.017739},
{0.010814, 0.220911},
{0.079250, 0.262280},
{0.727431, -0.430450},
{-0.529456, 0.783135},
{-0.314719, 1.023439},
{-0.849429, 0.474732},
{-0.221593, 1.089239},
{-0.987279, 0.229743},
{0.770743, 0.652182},
{0.951870, 0.010946},
{-0.856354, 0.525438},
{1.029354, -0.452736},
{1.424133, -0.474354},
{1.801520, -0.067370},
{1.744520, -0.369512},
{-0.043462, 0.403862},
{0.724772, -0.651344},
{1.922169, -0.039369},
{1.018020, -0.447123},
{0.764845, 0.618281},
{0.930603, 0.502057},
{0.476355, 0.920288},
{0.334232, 0.899143},
{1.716805, -0.234778},
{0.902126, 0.227534},
{-0.364474, 0.933141},
{0.214953, 0.003566},
{0.092235, 0.244482},
{0.893276, 0.390847},
{-0.483334, 0.914563},
{2.018904, 0.071256},
{-0.814643, 0.442269},
{-0.613655, 0.810521},
{0.762009, 0.419123},
{1.434706, -0.337772},
{-0.842737, 0.657621},
{-1.048589, 0.054561},
{-0.021857, 0.279999},
{-0.490034, 0.897323},
{1.867957, 0.060374},
{0.317957, -0.226475},
{0.095655, 1.039185},
{0.971460, 0.030393},
{0.844059, -0.602620},
{2.057751, 0.335419},
{1.540388, -0.310742},
{0.871085, -0.605143},
{0.402829, -0.230709},
{1.785589, -0.126331},
{0.043547, 0.290105},
{1.025271, 0.189324},
{0.518896, -0.331697},
{-0.902327, 0.351792},
{1.017409, 0.106655},
{2.004715, 0.289078},
{1.109100, -0.465287},
{1.373370, -0.439988},
{-1.101112, 0.069448},
{-0.020436, 0.400367},
{-0.222364, 0.941012},
{0.926767, 0.542129},
{-0.224489, 0.917377},
{0.937605, 0.070316},
{0.333242, 0.953593},
{1.419875, -0.359573},
{1.933062, 0.004952},
{1.825539, -0.153958},
{-0.725908, 0.701590},
{1.183000, -0.496431},
{0.979851, 0.278704},
{0.747287, 0.613190},
{-0.880120, 0.446538},
{0.956756, -0.495208},
{0.541462, 0.889930},
{-0.010937, 0.335959},
{2.049883, 0.312684},
{0.032665, 0.993500},
{1.314915, -0.337891},
{1.827553, 0.055617},
{0.015135, 0.207463},
{0.321188, 0.968582},
{1.959680, 0.043287},
{2.051663, 0.440216},
{1.234955, -0.527606},
{-1.006708, 0.135337},
{-0.013463, 0.296579},
{-0.900125, 0.387638},
{0.062448, -0.002272},
{0.739083, -0.429045},
{-0.945328, 0.002822},
{-0.319396, 0.996699},
{-0.818791, 0.544160},
{0.295365, 0.917986},
{0.238260, -0.030368},
{-0.032849, 1.011178},
{1.890539, -0.048711},
{0.069270, 1.051162},
{-0.817974, 0.540803},
{1.506988, -0.389107},
{0.865010, 0.570521},
{1.272596, -0.403276},
{0.831473, 0.618589},
{1.677542, -0.306637},
{1.863664, -0.015044},
{-0.983660, 0.219492},
{1.409356, -0.440830},
{0.556735, -0.362753},
{1.542049, -0.293177},
{0.275146, 0.922392},
{0.839746, -0.565840},
{0.594928, -0.416774},
{-0.859591, 0.530238},
{0.878811, 0.444530},
{-1.089284, 0.174896},
{1.933961, 0.096553},
{0.800158, -0.495279},
{-0.962624, 0.255423},
{0.454111, -0.262032},
{1.746187, -0.039707},
{1.015309, 0.405267},
{0.084266, -0.021184},
{1.425057, -0.426102},
{-0.050612, 0.295493},
{0.290406, -0.221576},
{1.053212, -0.476350},
{-0.965724, 0.252549},
{-0.515182, 0.923972},
{-0.520874, 0.800913},
{1.717090, -0.198103},
{1.383848, -0.378162},
{1.914799, 0.085750},
{-0.135729, 1.055527},
{-0.982776, 0.016877},
{1.043567, -0.534758},
{0.767395, -0.499783},
{-0.858276, 0.439048},
{-1.007341, 0.156550},
{0.442303, -0.335325},
{-0.643249, 0.715743},
{0.154170, 0.058791},
{1.874486, 0.179509},
{1.257742, -0.507674},
{0.842887, -0.535426},
{-0.958227, 0.165488},
{-0.884654, 0.397300},
{-0.277570, 0.989903},
{-0.027555, 0.435180},
{-0.898964, 0.367345},
{-0.968017, 0.080519},
{-1.052020, 0.159805},
{0.489639, 0.909463},
{0.295100, -0.334256},
{-0.293751, 0.941094},
{-0.962256, 0.027125},
{0.892193, 0.474452},
{-0.742804, 0.616452},
{-0.280649, 0.942420},
{0.566586, -0.427992},
{0.150308, 0.868716},
{1.238216, -0.490968},
{1.530832, -0.258454},
{-0.936692, 0.285366},
{-0.731766, 0.691292},
{1.940116, 0.476755},
{-0.942540, 0.330770},
{0.287592, 0.996836},
{0.452778, -0.379059},
{-0.149537, 0.973974},
{1.032119, 0.337238},
{0.161169, -0.178615},
{0.524032, 0.881968},
{0.605678, -0.433667},
{1.903029, 0.080978},
{1.411402, -0.401393},
{0.086160, 0.002624},
{-0.112262, 0.627420},
{-0.958406, 0.032572},
{0.265949, 0.878927},
{-0.330154, 0.930493},
{0.810520, 0.604709},
{0.965497, -0.467291},
{1.015025, -0.529315},
{-0.021882, 0.411085},
{-0.628660, 0.735648},
{-0.865102, 0.589042},
{0.531753, 0.849087},
{0.368138, -0.239757},
{1.111555, -0.505976},
{1.000575, 0.216265},
{0.309629, -0.180464},
{1.970165, 0.238080},
{2.015501, 0.487637},
{-0.668824, 0.801821},
{-1.090992, 0.140943},
{1.464551, -0.389069},
{2.047649, 0.353707},
{0.812124, 0.377782},
{0.993446, 0.401215},
{1.866624, -0.057398},
{-0.615064, 0.784470},
{-0.493770, 0.926331},
{-0.703263, 0.706535},
{0.833080, 0.593098},
{0.419678, 0.932303},
{0.061289, -0.029986},
{0.111869, -0.032584},
{-0.508201, 0.721360},
{-0.049591, 0.462859},
{-1.084732, 0.282470},
{0.279268, 0.979543},
{-0.336197, 1.009357},
{0.138583, -0.037314},
{-0.845177, 0.573057},
{0.048651, 0.212818},
{1.998907, 0.436598},
{1.524810, -0.310846},
{-0.852273, 0.693712},
{0.312212, -0.137077},
{0.604822, -0.414580},
{-0.022099, 0.961760},
{0.990277, -0.520190},
{0.058058, 0.254649},
{1.947760, 0.071421},
{0.314997, -0.302236},
{-1.043031, 0.044560},
{1.106648, -0.435029},
{-0.211299, 0.940982},
{0.934626, 0.316289},
{1.964347, 0.230726},
{0.721664, 0.671392},
{0.146093, -0.050481},
{-0.342076, 0.937329},
{2.011612, 0.448573},
{0.974391, 0.314916},
{0.298786, -0.143717},
{0.955922, 0.324982},
{-0.408658, 0.963722},
{0.742804, 0.680852},
{1.743709, -0.181210},
{0.314714, -0.137710},
{-0.092031, 0.961372},
{-0.702479, 0.769795},
{0.839017, 0.400835},
{-1.041318, 0.316274},
{1.846009, -0.076618},
{0.407674, -0.321502},
{1.976894, 0.284721},
{0.337385, -0.334260},
{0.586201, -0.368885},
{0.432563, 0.924590},
{-0.879775, 0.345697},
{-0.014395, 0.313793},
{0.503783, -0.239654},
{-0.407768, 0.914401},
{0.916260, 0.444225},
{-0.418969, 0.901274},
{1.111643, -0.452600},
{0.937454, -0.527681},
{0.835120, 0.624568},
{-0.851018, 0.375570},
{-0.915210, 0.378375},
{-0.064244, 0.327803},
{0.659794, 0.708016},
{1.335793, -0.448514},
{0.410420, -0.310221},
{-0.162192, 0.998459},
{0.223661, -0.198823},
{-0.570358, 0.831877},
{1.032324, 0.129681},
{0.217019, -0.003042},
{0.261615, -0.285742},
{0.048796, 0.984813},
{-0.254938, 0.994804},
{0.898794, 0.046838},
{1.069669, 0.126048},
{0.440227, -0.285024},
{0.136637, 0.198051},
{1.120624, -0.477247},
{-0.973364, 0.339979},
{0.053698, 0.231351},
{1.262157, -0.486460},
{1.839316, -0.081125},
{2.052578, 0.427548},
{1.932266, 0.410544},
{0.306282, 0.951114},
{-0.075340, 0.944025},
{1.898917, 0.198505},
{0.981225, 0.336562},
{-0.921751, 0.360200},
{1.073715, 0.279362},
{0.037450, 0.350880},
{1.242632, -0.449359},
{0.271190, 1.006297},
{-0.955722, -0.022154},
{0.398929, 0.849623},
{1.905541, 0.235737},
{0.849080, 0.490684},
{-0.957821, 0.300314},
{0.417028, 0.889683},
{1.934534, 0.306650},
{0.479683, -0.294547},
{0.034986, 0.360210},
{-1.038837, 0.211337},
{0.205103, -0.070759},
{0.190626, 0.037918},
{0.645647, 0.801434},
{-0.628091, 0.715487},
{0.732760, 0.664974},
{-0.590563, 0.775441},
{0.285149, 0.959786},
{0.800147, -0.467614},
{-0.000921, 1.032517},
{0.455246, 0.893279},
{1.052181, -0.475257},
{1.226588, -0.425567},
{-0.432090, 0.925309},
{1.829544, 0.255384},
{0.944458, 0.191713},
{-0.510158, 0.832587},
{-0.930726, 0.161549},
{-0.922595, 0.329888},
{0.707979, 0.739976},
{-0.613216, 0.766708},
{1.258353, -0.470191},
{0.927009, -0.498520},
{0.324842, 0.903055},
{0.871482, 0.453519},
{-0.054499, 0.421917},
{0.141363, 1.010463},
{0.827176, 0.712774},
{2.016852, 0.476308},
{0.929437, -0.456706},
{2.042305, 0.548997},
{1.901681, 0.163530},
{-0.930355, 0.407547},
{0.479895, -0.351491},
{1.983887, 0.347194},
{0.017671, 0.484723},
{1.639731, -0.290390},
{1.932341, 0.071913},
{0.501825, -0.281240},
{1.921311, 0.087951},
{1.272188, -0.498398},
{-0.179918, 1.051137},
{0.453132, 0.835018},
{0.576611, 0.918667},
{0.918902, 0.050946},
{1.661269, -0.274173},
{0.937542, 0.311417},
{0.432592, 0.982486},
{0.812409, 0.676360},
{1.797159, -0.225232},
{1.851369, 0.019509},
{-0.283105, 0.926137},
{-0.332006, 0.897045},
{0.697053, 0.674013},
{-0.584869, 0.754202},
{1.410478, -0.486355},
{0.287750, 0.903310},
{2.012718, 0.390410},
{1.903221, 0.379131},
{-0.196606, 1.033605},
{1.918604, 0.333567},
{-0.511178, 0.915872},
{0.251228, -0.121687},
{0.424416, -0.280077},
{-0.827322, 0.636587},
{0.723174, 0.733239},
{0.314638, 0.918349},
{-0.198637, 0.852728},
{1.403938, -0.402679},
{0.169446, 1.059232},
{1.861147, 0.020544},
{-0.875108, 0.614762},
{-0.431734, 0.877782},
{-0.473136, 0.958484},
{-0.005458, 0.493191},
{-0.779139, 0.791404},
{0.062583, 0.223050},
{1.450417, -0.321252},
{1.457999, -0.323413},
{-0.521386, 0.858724},
{1.159840, -0.501402},
{0.205773, -0.082981},
{0.452968, 0.808904},
{0.632244, 0.834704},
{0.027568, 0.405447},
{1.005634, -0.060669},
{1.173155, -0.403369},
{1.415813, -0.360574},
{-0.755428, 0.645590},
{-0.921456, 0.104213},
{0.319172, 0.959075},
{-0.721720, 0.629173},
{0.559405, -0.415354},
{1.154913, -0.486450},
{1.874627, 0.186733},
{0.129949, 1.025790},
{0.915931, -0.453787},
{0.965287, 0.047880},
{1.659713, -0.289383},
{1.058690, -0.531482},
{1.300179, -0.476471},
{1.011569, 0.049704},
{1.935927, 0.205163},
{0.647294, -0.501768},
{0.196952, -0.131321},
{0.768647, 0.625616},
{-0.268717, 0.917226},
{0.910211, -0.515727},
{1.517311, -0.313105},
{-0.896194, 0.268710},
{1.079940, -0.470747},
{0.819778, 0.514925},
{-0.945710, 0.255479},
{0.122346, 0.051894},
{1.787602, -0.139645},
{0.752995, 0.515553},
{0.180700, 0.006226},
{-0.812868, 0.575579},
{-0.233209, 0.953957},
{0.423760, -0.306385},
{-0.760465, 0.707430},
{1.752590, -0.159040},
{-0.047417, 1.142527},
{0.103935, -0.066128},
{1.716572, -0.148447},
{0.062318, -0.103880},
{-0.899097, 0.400504},
{1.183183, -0.511290},
{1.902193, 0.154401},
{-0.103015, 1.005290},
{0.300173, -0.307560},
{0.257369, 0.968842},
{1.109539, 0.205086},
{0.770578, 0.568366},
{0.934577, 0.060062},
{0.969279, 0.282622},
{1.654506, -0.246114},
{0.032389, 0.169729},
{0.050433, 0.403408},
{1.600779, -0.341651},
{-0.957760, 0.337992},
{0.855063, -0.508219},
{1.747808, -0.193790},
{0.653936, 0.794221},
{1.393704, -0.430918},
{2.026835, 0.404619},
{0.582225, 0.810004},
{0.900367, 0.247613},
{0.223586, -0.021075},
{1.913451, 0.078152},
{-0.939789, 0.600428},
{0.634625, -0.382429},
{1.185619, -0.384662},
{0.301292, -0.396078},
{0.062252, 0.188547},
{0.439219, 0.809028},
{0.114075, 0.086596},
{0.385133, 0.924554},
{0.636800, -0.372632},
{0.274617, -0.202793},
{1.972595, 0.127309},
{0.137737, 0.092172},
{-0.044042, 1.066223},
{0.546031, 0.878942},
{0.849479, 0.411200},
{0.215150, 0.099633},
{0.908682, -0.476567},
{0.495083, 0.941848},
{-0.752203, 0.614888},
{0.619550, -0.325722},
{-0.833069, 0.540707},
{1.887803, -0.164009},
{1.901957, 0.181567},
{-0.376925, 0.949594},
{0.341581, 0.966420},
{-0.073042, 0.397439},
{0.021347, 0.296053},
{-0.642642, 0.716163},
{1.937418, 0.231237},
{1.406181, -0.399618},
{0.243133, -0.237591},
{1.046156, -0.455960},
{0.196480, 0.990915},
{-0.678494, 0.746111},
{1.480257, -0.350615},
{1.495622, -0.416584},
{0.627392, 0.820522},
{-0.845936, 0.240077},
{0.176938, 0.156807},
{1.623276, -0.226135},
{0.025651, 0.264181},
{0.736717, -0.510448},
{1.759529, -0.164661},
{0.992858, 0.297352},
{1.004335, 0.050847},
{-0.329659, 0.829825},
{1.959744, 0.319912},
{1.917142, 0.079347},
{1.779574, -0.063431},
{1.956901, 0.417775},
{-0.838951, 0.550627},
{-0.312107, 0.972094},
{0.054083, 1.055564},
{1.939328, 0.029565},
{0.766661, 0.556358},
{0.994651, 0.068223},
{0.076859, 0.337722},
{-0.630298, 0.809767},
{-0.447665, 0.797417},
{-0.422787, 0.921586},
{0.199731, -0.283831},
{-1.082445, 0.130062},
{0.932234, 0.388892},
{1.795673, -0.195881},
{0.788854, 0.498824},
{0.241845, 0.906703},
{0.309588, -0.181482},
{1.393854, -0.445827},
{-0.668386, 0.729540},
{0.897551, 0.245724},
{0.079552, 0.124947},
{0.905924, 0.329091},
{0.474081, 0.860559},
{1.869998, -0.016190},
{-0.433127, 0.809947},
{1.909509, 0.029897},
{0.546231, -0.360031},
{0.040900, 0.370693}
};
static const std::vector<short> noisy_moons_labels {
0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0,
};
#include <catch.hpp>
#include <random>
#include <opencv2/core.hpp>
#include <ftl/algorithms/dbscan.hpp>
#include <ftl/profiler.hpp>
#include "data.hpp"
using std::vector;
template<typename T>
static vector<size_t> linearSearch(const vector<T> &points, size_t idx, float radius) {
vector<size_t> neighbors;
for (auto i = 0u; i < points.size(); i++) {
if (i == idx) {
continue;
}
if (cv::norm(points[idx] - points[i]) < radius) {
neighbors.push_back(i);
}
}
return neighbors;
}
TEST_CASE("DBSCAN 3D clustering (linear search)") {
vector<cv::Vec3f> points {
{1.0,2.1,3.0},
{1.0,1.9,3.0},
{1.0,2.0,3.0},
{1.0,1.9,3.0},
{1.0,2.1,3.0},
{3.0,2.1,1.0},
{3.0,2.0,1.0},
{3.0,2.0,1.0},
{3.0,2.0,1.0},
{3.0,1.9,1.0}
};
vector<cv::Vec3f> centroids;
vector<short> labels;
ftl::dbscan<cv::Vec3f>(points, linearSearch<cv::Vec3f>, 3, 1.0f, labels, centroids);
REQUIRE(centroids.size() == 2);
REQUIRE(centroids[0] == cv::Vec3f(1,2,3));
REQUIRE(centroids[1] == cv::Vec3f(3,2,1));
}
TEST_CASE("DBSCAN 3D clustering (random points)") {
std::random_device rd;
std::mt19937::result_type seed = rd();
vector<cv::Vec3f> true_centroids = {
{ 1, 5, 3},
{ 3, 5, 1},
{ 0, 0, 0},
{ 3, 3, 3},
{-3,-3,-3},
{ 7, 7, 7},
{-7,-7,-7},
};
int n_points = 16;
float sigma = 0.33;
float eps = sigma; // error threshold for test case
vector<cv::Vec3f> points;
std::mt19937 gen(seed);
for (const auto &c : true_centroids) {
std::normal_distribution<float> x{c[0], sigma};
std::normal_distribution<float> y{c[1], sigma};
std::normal_distribution<float> z{c[2], sigma};
for (int i = 0; i < n_points; i++) {
points.push_back({x(gen), y(gen), z(gen)});
}
}
vector<cv::Vec3f> centroids;
vector<short> labels;
ftl::dbscan<cv::Vec3f>(points, linearSearch<cv::Vec3f>, 8, 1.0f, labels, centroids);
REQUIRE(centroids.size() == true_centroids.size());
for (unsigned i = 0; i < true_centroids.size(); i++) {
// assumes same order as points were added (no shuffle)
REQUIRE(cv::norm(centroids[i] - true_centroids[i]) < eps);
}
}
TEST_CASE("DBSCAN 2D clustering (noisy moons)") {
vector<cv::Vec2f> centroids;
vector<short> labels;
{
//ftl::Profiler __profile(__func__, "DBSCAN 1500 points linear search", 0);
//__profile.verbosity(1);
// ~ 10ms (release)
ftl::dbscan<cv::Vec2f>(noisy_moons, linearSearch<cv::Vec2f>, 5, 0.2f, labels, centroids);
}
// assumes clustering returns same labels each time
REQUIRE(centroids.size() == 2);
REQUIRE(cv::norm(centroids[0] - cv::Vec2f(1.0, 0.0)) < 0.15); // 0.13359162681252454
REQUIRE(cv::norm(centroids[1] - cv::Vec2f(0.0, 0.5)) < 0.15); // 0.13651460122147505
for (unsigned i = 0; i < labels.size(); i++) {
if (labels[i] < 0) continue; // label: NOISE
REQUIRE(labels[i] == noisy_moons_labels[i]);
}
}
TEST_CASE("DBSCAN 2D clustering (noisy circles)") {
vector<cv::Vec2f> centroids;
vector<short> labels;
{
//ftl::Profiler __profile(__func__, "DBSCAN 1500 points linear search", 0);
//__profile.verbosity(1);
// ~10ms (release)
ftl::dbscan<cv::Vec2f>(noisy_circles, linearSearch<cv::Vec2f>, 5, 0.1f, labels, centroids);
}
// assumes clustering returns same labels each time
REQUIRE(centroids.size() == 2);
REQUIRE(cv::norm(centroids[0]) < 0.01); // 0.0008899436718976423
REQUIRE(cv::norm(centroids[0]) < 0.01); // 0.0014477936451883612
for (unsigned i = 0; i < labels.size(); i++) {
if (labels[i] < 0) continue; // label: NOISE
REQUIRE(labels[i] == noisy_circles_labels[i]);
}
}
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
......@@ -10,6 +10,8 @@ add_library(ftlrender
src/colouriser.cpp
src/colour_util.cu
src/overlay.cpp
src/gltexture.cpp
src/touch.cu
#src/assimp_render.cpp
#src/assimp_scene.cpp
)
......@@ -27,4 +29,10 @@ target_include_directories(ftlrender PUBLIC
PRIVATE src)
target_link_libraries(ftlrender ftlrgbd ftlcommon Eigen3::Eigen Threads::Threads nanogui ${NANOGUI_EXTRA_LIBS} ${OpenCV_LIBS})
#ADD_SUBDIRECTORY(test)
target_precompile_headers(ftlrender REUSE_FROM ftldata)
set_property(TARGET ftlrender PROPERTY CUDA_ARCHITECTURES OFF)
if (BUILD_TESTS)
ADD_SUBDIRECTORY(test)
endif()
#ifndef _FTL_CUDA_TOUCH_HPP_
#define _FTL_CUDA_TOUCH_HPP_
#include <ftl/cuda_common.hpp>
namespace ftl {
namespace cuda {
struct Collision {
uint screen;
float depth;
__host__ __device__ inline int x() const { return (screen >> 12) & 0x3FF; }
__host__ __device__ inline int y() const { return screen & 0x3FF; }
__host__ __device__ inline float strength() const { return float(screen >> 24) / 32.0f; }
};
void touch_merge(
ftl::cuda::TextureObject<float> &depth_in,
ftl::cuda::TextureObject<float> &depth_out,
Collision *collisions, int max_collisions,
float dist,
cudaStream_t stream);
}
}
#endif
......@@ -5,6 +5,7 @@
#include <ftl/rgbd/frameset.hpp>
#include <ftl/render/render_params.hpp>
#include <ftl/cuda/points.hpp>
#include <ftl/cuda/touch.hpp>
#include <ftl/codecs/channels.hpp>
//#include <ftl/filters/filter.hpp>
......@@ -25,13 +26,20 @@ class CUDARender : public ftl::render::FSRenderer {
void begin(ftl::rgbd::Frame &, ftl::codecs::Channel) override;
void end() override;
bool submit(ftl::rgbd::FrameSet *in, ftl::codecs::Channels<0>, const Eigen::Matrix4d &t) override;
bool submit(ftl::data::FrameSet *in, ftl::codecs::Channels<0>, const Eigen::Matrix4d &t) override;
//void setOutputDevice(int);
void render() override;
void blend(ftl::codecs::Channel) override;
void cancel() override;
/**
* Returns all inter-frameset collisions in camera coordinates.
*/
inline const std::vector<float4> &getCollisions() const { return collision_points_; }
void setViewPort(ftl::render::ViewPortMode mode, const ftl::render::ViewPort &vp) {
params_.viewport = vp;
params_.viewPortMode = mode;
......@@ -44,7 +52,8 @@ class CUDARender : public ftl::render::FSRenderer {
private:
int device_;
ftl::rgbd::Frame temp_;
ftl::data::Frame temp_d_;
ftl::rgbd::Frame &temp_;
//ftl::rgbd::Frame accum_;
ftl::cuda::TextureObject<float4> accum_; // 2 is number of channels can render together
ftl::cuda::TextureObject<int> contrib_;
......@@ -52,9 +61,15 @@ class CUDARender : public ftl::render::FSRenderer {
std::list<ftl::cuda::TextureObject<short2>*> screen_buffers_;
std::list<ftl::cuda::TextureObject<float>*> depth_buffers_;
ftl::cuda::TextureObject<float> depth_out_;
ftl::cuda::Collision *collisions_;
ftl::cuda::Collision collisions_host_[1024];
std::vector<float4> collision_points_;
float touch_dist_;
ftl::rgbd::Frame *out_;
ftl::rgbd::FrameSet *scene_;
ftl::data::FrameSet *scene_;
ftl::cuda::ClipSpace clip_;
ftl::render::Colouriser *colouriser_;
bool clipping_;
......@@ -100,7 +115,7 @@ class CUDARender : public ftl::render::FSRenderer {
void _end();
void _endSubmit();
bool _alreadySeen() const { return last_frame_ == scene_->timestamp; }
bool _alreadySeen() const { return last_frame_ == scene_->timestamp(); }
void _adjustDepthThresholds(const ftl::rgbd::Camera &fcam);
ftl::cuda::TextureObject<float> &_getDepthBuffer(const cv::Size &);
......
......@@ -6,6 +6,8 @@
#include <ftl/rgbd/frameset.hpp>
#include <nanogui/glutil.h>
struct NVGcontext;
namespace ftl {
namespace overlay {
......@@ -24,7 +26,7 @@ class Overlay : public ftl::Configurable {
//void apply(ftl::rgbd::FrameSet &fs, cv::Mat &out, ftl::rgbd::FrameState &state);
void draw(ftl::rgbd::FrameSet &fs, ftl::rgbd::FrameState &state, const Eigen::Vector2f &);
void draw(NVGcontext *, ftl::data::FrameSet &fs, ftl::rgbd::Frame &frame, const Eigen::Vector2f &, const Eigen::Vector2f &, const Eigen::Vector2f &offset, const Eigen::Matrix4d &cursor);
private:
nanogui::GLShader oShader;
......
......@@ -69,6 +69,7 @@ struct Parameters {
ftl::rgbd::Camera camera; // Virtual camera intrinsics
ftl::render::ViewPort viewport;
ftl::render::ViewPortMode viewPortMode;
ftl::rgbd::Projection projection;
ftl::render::AccumulationFunction accumulationMode;
};
......
......@@ -47,6 +47,8 @@ class Renderer : public ftl::Configurable {
virtual void blend(ftl::codecs::Channel)=0;
virtual void cancel()=0;
protected:
Stage stage_;
};
......@@ -70,7 +72,7 @@ class FSRenderer : public ftl::render::Renderer {
* together by some undefined method. Non colour channels will be converted
* to RGB colour appropriately.
*/
virtual bool submit(ftl::rgbd::FrameSet *, ftl::codecs::Channels<0>, const Eigen::Matrix4d &)=0;
virtual bool submit(ftl::data::FrameSet *, ftl::codecs::Channels<0>, const Eigen::Matrix4d &)=0;
};
}
......
#ifndef _FTL_GUI_GLTEXTURE_HPP_
#define _FTL_GUI_GLTEXTURE_HPP_
#pragma once
#include <opencv2/core/mat.hpp>
#include <cuda_runtime.h>
#include <opencv2/core.hpp>
#include <ftl/cuda_common.hpp>
struct cudaGraphicsResource;
namespace ftl {
namespace gui {
namespace utility {
class GLTexture {
public:
......@@ -18,21 +16,28 @@ class GLTexture {
Float
};
explicit GLTexture(Type);
explicit GLTexture();
~GLTexture();
void update(cv::Mat &m);
void make(int width, int height);
unsigned int texture() const;
bool isValid() const { return glid_ != std::numeric_limits<unsigned int>::max(); }
int width() const { return width_; }
int height() const { return height_; }
Type type() const { return type_; }
std::mutex& mutex() { return mtx_; }
// acquire mutex before make() or free()
void make(int width, int height, Type type);
void free();
unsigned int texture() const;
cv::cuda::GpuMat map(cudaStream_t stream);
void unmap(cudaStream_t stream);
void free();
void copyFrom(const ftl::cuda::TextureObject<uchar4> &buf, cudaStream_t stream = cudaStreamDefault);
int width() const { return width_; }
int height() const { return height_; }
void copyFrom(const cv::Mat &im, cudaStream_t stream = cudaStreamDefault);
void copyFrom(const cv::cuda::GpuMat &im, cudaStream_t stream = cudaStreamDefault);
private:
unsigned int glid_;
......@@ -40,13 +45,13 @@ class GLTexture {
int width_;
int height_;
int stride_;
bool changed_;
Type type_;
std::mutex mtx_; // for locking while in use (opengl thread calls lock() or cuda mapped)
cudaGraphicsResource *cuda_res_;
};
}
}
#endif // _FTL_GUI_GLTEXTURE_HPP_