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

Orientation histogram and buckets

parent 5f2019db
No related branches found
No related tags found
1 merge request!347Feature buckets experiment
Pipeline #26708 failed
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "../filters/salient_gradient.hpp" #include "../filters/salient_gradient.hpp"
#include <opencv2/highgui.hpp> #include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
struct StereoCSF::Impl { struct StereoCSF::Impl {
Array2D<uchar> l; Array2D<uchar> l;
...@@ -10,10 +11,12 @@ struct StereoCSF::Impl { ...@@ -10,10 +11,12 @@ struct StereoCSF::Impl {
Array2D<uchar> gl; Array2D<uchar> gl;
Array2D<uchar> gr; Array2D<uchar> gr;
Array2D<uchar> temp; Array2D<uchar> temp;
Bucket2D<ushort, 64> buckets_l;
Impl(int width, int height) : Impl(int width, int height) :
l(width, height), r(width, height), l(width, height), r(width, height),
gl(width, height), gr(width, height), temp(width, height) {} gl(width, height), gr(width, height), temp(width, height),
buckets_l(16, height) {}
}; };
StereoCSF::StereoCSF() : impl_(nullptr) { StereoCSF::StereoCSF() : impl_(nullptr) {
...@@ -32,13 +35,21 @@ void StereoCSF::compute(cv::InputArray l, cv::InputArray r, cv::OutputArray disp ...@@ -32,13 +35,21 @@ void StereoCSF::compute(cv::InputArray l, cv::InputArray r, cv::OutputArray disp
mat2gray(l, impl_->l); mat2gray(l, impl_->l);
mat2gray(r, impl_->r); mat2gray(r, impl_->r);
SalientGradient sg = {impl_->l.data(), impl_->gl.data(), impl_->temp.data(), impl_->l.width, impl_->l.height}; SalientGradient sgl = {impl_->l.data(), impl_->gl.data(), impl_->temp.data(), impl_->buckets_l.data(), impl_->l.width, impl_->l.height};
parallel1DWarpSM(sg, l.rows(), l.cols()); parallel1DWarpSM(sgl, l.rows(), l.cols());
//SalientGradient sgr = {impl_->r.data(), impl_->gr.data(), impl_->temp.data(), impl_->r.width, impl_->r.height};
//parallel1DWarpSM(sgr, r.rows(), r.cols());
cv::Mat tmp; cv::Mat tmp;
impl_->gl.toGpuMat().download(tmp); impl_->buckets_l.toGpuMat().download(tmp);
cv::resize(tmp,tmp, cv::Size(tmp.cols/2, tmp.rows/2)); tmp.convertTo(tmp, CV_8UC1, 4.0);
cv::imshow("Gradients", tmp); cv::resize(tmp,tmp, cv::Size(tmp.cols*40, tmp.rows/2));
cv::applyColorMap(tmp, tmp, cv::COLORMAP_TURBO);
cv::imshow("Gradients Left", tmp);
//impl_->gr.toGpuMat().download(tmp);
//cv::resize(tmp,tmp, cv::Size(tmp.cols/2, tmp.rows/2));
//cv::imshow("Gradients Right", tmp);
cudaSafeCall(cudaDeviceSynchronize()); cudaSafeCall(cudaDeviceSynchronize());
disparity.create(l.rows(), l.cols(), CV_32F); disparity.create(l.rows(), l.cols(), CV_32F);
......
#ifndef _FTL_LIBSTEREO_BUCKET2D_HPP_
#define _FTL_LIBSTEREO_BUCKET2D_HPP_
#include "memory.hpp"
template<typename T, int DEPTH>
class Bucket2D {
public:
Bucket2D() : width(0), height(0), needs_free_(false) {
data_.buckets = nullptr;
data_.counters = nullptr;
}
Bucket2D(int w, int h) : width(w), height(h), needs_free_(true) {
data_.counters = allocateMemory2D<uint>(w, h, data_.counter_pitch);
data_.buckets = allocateMemory2D<T>(w*DEPTH, h, data_.bucket_pitch);
}
~Bucket2D() {
free();
}
void free() {
if (needs_free_ && data_.buckets) {
freeMemory(data_.counters);
freeMemory(data_.buckets);
}
}
Bucket2D<T, DEPTH> &operator=(const Bucket2D<T, DEPTH> &c) {
data_ = c.data_;
width = c.width;
height = c.height;
needs_free_ = false;
return *this;
}
struct Data {
__host__ __device__ inline uint& operator() (const int y, const int x) {
return counters[x + y*counter_pitch];
}
__host__ __device__ inline const uint& operator() (const int y, const int x) const {
return counters[x + y*counter_pitch];
}
__host__ __device__ inline const T& operator() (const int y, const int x, int d) const {
return buckets[d + x*DEPTH + y*bucket_pitch];
}
__host__ __device__ inline void add (const int y, const int x, T v) {
uint ix = atomicInc(&counters[x + y*counter_pitch], DEPTH);
buckets[ix + x*DEPTH + y*bucket_pitch] = v;
}
__host__ __device__ inline uint *ptr(const int y) { return &counters[y*counter_pitch]; }
__host__ __device__ inline const uint *ptr(const int y) const { return &counters[y*counter_pitch]; }
__host__ __device__ inline const T *ptr(const int y, const int x) const { return &buckets[x*DEPTH+y*bucket_pitch]; }
uint bucket_pitch;
uint counter_pitch;
T *buckets;
uint *counters;
};
void create(int w, int h) {
if (w == width && h == height) return;
width = w;
height = h;
free();
needs_free_ = true;
data_.counters = allocateMemory2D<uint>(w, h, data_.counter_pitch);
data_.buckets = allocateMemory2D<T>(w*DEPTH, h, data_.bucket_pitch);
}
inline Data &data() { return data_; }
inline const Data &data() const { return data_; }
void toMat(cv::Mat &m) {
#ifdef USE_GPU
cv::cuda::GpuMat gm;
toGpuMat(gm);
gm.download(m);
#else
m = cv::Mat(height, width, cv::traits::Type<int>::value, data_.counters);
#endif
}
cv::Mat toMat() {
#ifdef USE_GPU
cv::cuda::GpuMat gm;
toGpuMat(gm);
cv::Mat m;
gm.download(m);
return m;
#else
return cv::Mat(height, width, cv::traits::Type<int>::value, data_.counters);
#endif
}
const cv::Mat toMat() const {
#ifdef USE_GPU
cv::cuda::GpuMat gm(height, width, cv::traits::Type<int>::value, (void*)data_.counters, size_t(size_t(data_.counter_pitch)*sizeof(uint)));
cv::Mat m;
gm.download(m);
return m;
#else
return cv::Mat(height, width, cv::traits::Type<int>::value, data_.counters);
#endif
}
void toGpuMat(cv::cuda::GpuMat &m) {
#ifdef USE_GPU
m = cv::cuda::GpuMat(height, width, cv::traits::Type<int>::value, (void*)data_.counters, size_t(size_t(data_.counter_pitch)*sizeof(uint)));
#else
// TODO
#endif
}
cv::cuda::GpuMat toGpuMat() {
#ifdef USE_GPU
return cv::cuda::GpuMat(height, width, cv::traits::Type<int>::value, (void*)data_.counters, size_t(size_t(data_.counter_pitch)*sizeof(uint)));
#else
return cv::cuda::GpuMat(height, width, cv::traits::Type<int>::value);
#endif
}
int width;
int height;
private:
Data data_;
bool needs_free_;
};
#endif
...@@ -3,11 +3,13 @@ ...@@ -3,11 +3,13 @@
#include "../util.hpp" #include "../util.hpp"
#include "../array2d.hpp" #include "../array2d.hpp"
#include "../bucket2d.hpp"
struct SalientGradient { struct SalientGradient {
Array2D<uchar>::Data image; Array2D<uchar>::Data image;
Array2D<uchar>::Data output; Array2D<uchar>::Data angle;
Array2D<uchar>::Data magnitude; Array2D<uchar>::Data magnitude;
Bucket2D<ushort, 64>::Data buckets;
int width, height; int width, height;
...@@ -48,31 +50,38 @@ struct SalientGradient { ...@@ -48,31 +50,38 @@ struct SalientGradient {
// Reset histogram // Reset histogram
//for (int i=thread.x; i < 32; i+=32) wsm.gradient_histogram[i] = 0; //for (int i=thread.x; i < 32; i+=32) wsm.gradient_histogram[i] = 0;
wsm.gradient_histogram[thread.x] = 0; wsm.gradient_histogram[thread.x] = 0;
//int maxmag = 0;
for (int x=thread.x; x<size.x; x+=stride.x) { for (int x=thread.x; x<size.x; x+=stride.x) {
auto g = calculateGradient(x,y); auto g = calculateGradient(x,y);
output(y,x) = uchar((g.y+PI2) / PI * 63.0f); angle(y,x) = uchar(min(15,int((g.y+PI2) / PI * 16.0f)));
magnitude(y,x) = uchar(g.x); magnitude(y,x) = uchar(g.x);
//maxmag = warpMax(max(maxmag,int(g.x))); //maxmag = max(maxmag,int(g.x));
atomicAdd(&wsm.gradient_histogram[min(31,int(g.x / 361.0f * 32.0f))], 1); atomicAdd(&wsm.gradient_histogram[min(31,int(g.x / 361.0f * 32.0f))], 1);
//atomicAdd(&wsm.gradient_histogram[0], 1); //atomicAdd(&wsm.gradient_histogram[0], 1);
} }
__syncwarp(); //maxmag = int(float(warpMax(maxmag)) * 0.8f);
uchar gthresh = min(255, scan(wsm.gradient_histogram, thread.x, float(width)*0.95f) * (256/32)); uchar gthresh = min(255, scan(wsm.gradient_histogram, thread.x, float(width)*0.95f) * (256/32));
// Apply threshold // Apply threshold
for (int x=thread.x; x<size.x; x+=stride.x) { for (int x=thread.x; x<size.x; x+=stride.x) {
uchar thresh = gthresh; uchar thresh = gthresh;
for (int u=-5; u<=5; ++u) { for (int u=-3; u<=3; ++u) {
thresh = (x+u >= 0 && x+u < width) ? max(thresh, magnitude(y,x+u)-abs(u)) : thresh; thresh = (x+u >= 0 && x+u < width) ? max(thresh, magnitude(y,x+u)) : thresh;
} }
uchar m = magnitude(y,x); uchar m = magnitude(y,x);
//if (m < max(thresh, uchar(float(maxmag)*0.2f))) output(y,x) = 0; //if (m < thresh) angle(y,x) = 0;
output(y,x) = (m < thresh) ? 0 : 255; //output(y,x) = (m < thresh) ? 0 : 255;
if (m >= thresh) {
int a = angle(y,x);
buckets.add(y, a, ushort(x));
buckets.add(y, (a > 0) ? a-1 : 15, ushort(x));
buckets.add(y, (a < 15) ? a+1 : 0, ushort(x));
}
} }
// Next step would be to bucket the results // Next step would be to bucket the results
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment