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

Implements #151 alternate minimums

parent 42677890
No related branches found
No related tags found
No related merge requests found
...@@ -399,6 +399,8 @@ __device__ inline float warpMin(float e) { ...@@ -399,6 +399,8 @@ __device__ inline float warpMin(float e) {
return e; return e;
} }
#define ENERGY_THRESHOLD 0.1f
/* /*
* Pass 2: Determine depth buffer with enough accuracy for a visibility test in pass 2. * Pass 2: Determine depth buffer with enough accuracy for a visibility test in pass 2.
...@@ -418,6 +420,12 @@ __device__ inline float warpMin(float e) { ...@@ -418,6 +420,12 @@ __device__ inline float warpMin(float e) {
const int x = (blockIdx.x*blockDim.x + threadIdx.x) / WARP_SIZE; const int x = (blockIdx.x*blockDim.x + threadIdx.x) / WARP_SIZE;
const int y = blockIdx.y*blockDim.y + threadIdx.y; const int y = blockIdx.y*blockDim.y + threadIdx.y;
// Starting point for surface minimum
float clusterBase = params.camera.m_sensorDepthWorldMin;
// Loop to a deeper surface if not on the first one selected...
while (clusterBase < params.camera.m_sensorDepthWorldMax) {
const int lane = tid % WARP_SIZE; const int lane = tid % WARP_SIZE;
if (lane == 0) { if (lane == 0) {
minimum[warp] = 100000000; minimum[warp] = 100000000;
...@@ -428,6 +436,8 @@ __device__ inline float warpMin(float e) { ...@@ -428,6 +436,8 @@ __device__ inline float warpMin(float e) {
__syncwarp(); __syncwarp();
// Search for a valid minimum neighbour // Search for a valid minimum neighbour
// TODO: Should this really be minimum or the median of a depth cluster?
// cluster median seems very hard to calculate...
for (int i=lane; i<NEIGHBOR_WINDOW; i+=WARP_SIZE) { for (int i=lane; i<NEIGHBOR_WINDOW; i+=WARP_SIZE) {
const int u = (i % (2*NEIGHBOR_RADIUS_2+1)) - NEIGHBOR_RADIUS_2; const int u = (i % (2*NEIGHBOR_RADIUS_2+1)) - NEIGHBOR_RADIUS_2;
const int v = (i / (2*NEIGHBOR_RADIUS_2+1)) - NEIGHBOR_RADIUS_2; const int v = (i / (2*NEIGHBOR_RADIUS_2+1)) - NEIGHBOR_RADIUS_2;
...@@ -435,7 +445,11 @@ __device__ inline float warpMin(float e) { ...@@ -435,7 +445,11 @@ __device__ inline float warpMin(float e) {
const float3 camPos = params.camera.kinectDepthToSkeleton(x, y, point.z); const float3 camPos = params.camera.kinectDepthToSkeleton(x, y, point.z);
// If it is close enough... // If it is close enough...
if (point.z > params.camera.m_sensorDepthWorldMin && point.z < params.camera.m_sensorDepthWorldMax && length(point - camPos) <= 0.02f) { // TODO: smoothing / strength should be determined by a number of factors including:
// 1) Depth from original source
// 2) Colour contrast in underlying RGB
// 3) Estimated noise levels in depth values
if (point.z > clusterBase && point.z < params.camera.m_sensorDepthWorldMax && length(point - camPos) <= 0.04f) {
atomicMin(&minimum[warp], point.z*1000.0f); atomicMin(&minimum[warp], point.z*1000.0f);
} }
} }
...@@ -457,7 +471,7 @@ __device__ inline float warpMin(float e) { ...@@ -457,7 +471,7 @@ __device__ inline float warpMin(float e) {
const float3 point = params.camera.kinectDepthToSkeleton(x+u, y+v, float(point_in.tex2D(x+u, y+v)) / 1000.0f); const float3 point = params.camera.kinectDepthToSkeleton(x+u, y+v, float(point_in.tex2D(x+u, y+v)) / 1000.0f);
// If it is close enough... // If it is close enough...
if (point.z > params.camera.m_sensorDepthWorldMin && point.z < params.camera.m_sensorDepthWorldMax && length(point - minPos) <= 0.02f) { if (point.z > params.camera.m_sensorDepthWorldMin && point.z < params.camera.m_sensorDepthWorldMax && length(point - minPos) <= 0.04f) {
// Append to neighbour list // Append to neighbour list
//unsigned int idx = atomicInc(&nidx[warp], MAX_NEIGHBORS_2-1); //unsigned int idx = atomicInc(&nidx[warp], MAX_NEIGHBORS_2-1);
unsigned int idx = atomicAdd(&nidx[warp], 1); unsigned int idx = atomicAdd(&nidx[warp], 1);
...@@ -469,9 +483,6 @@ __device__ inline float warpMin(float e) { ...@@ -469,9 +483,6 @@ __device__ inline float warpMin(float e) {
__syncwarp(); __syncwarp();
// FIXME: What if minDepth fails energy test, an alternate min is needed.
// Perhaps a second pass can be used?
const float maxDepth = float(maximum[warp])/1000.0f; const float maxDepth = float(maximum[warp])/1000.0f;
const float interval = (maxDepth - minDepth) / float(MAX_ITERATIONS); const float interval = (maxDepth - minDepth) / float(MAX_ITERATIONS);
...@@ -506,8 +517,9 @@ __device__ inline float warpMin(float e) { ...@@ -506,8 +517,9 @@ __device__ inline float warpMin(float e) {
maxenergy = newenergy; maxenergy = newenergy;
} }
// Search for first energy maximum above a threshold // If enough energy was found and this thread was the one that found the best
if (bestdepth > 0.0f && maxenergy >= 0.1f) { // then output the depth that this energy occured at.
if (bestdepth > 0.0f && maxenergy >= ENERGY_THRESHOLD) {
//printf("E D %f %f\n", maxenergy, bestdepth); //printf("E D %f %f\n", maxenergy, bestdepth);
const unsigned int cx = x; const unsigned int cx = x;
const unsigned int cy = y; const unsigned int cy = y;
...@@ -517,6 +529,28 @@ __device__ inline float warpMin(float e) { ...@@ -517,6 +529,28 @@ __device__ inline float warpMin(float e) {
//depth(cx,cy) = bestdepth * 1000.0f; //depth(cx,cy) = bestdepth * 1000.0f;
} }
} }
// TODO: Could the threshold depend upon the number of points? Fewer points
// due to distance is incorrect since really there may not be fewer points
// Perhaps the best option is to make it depend on depth ... really close
// and really far both has lower thresholds due to point densities. Other
// option is smoothing factor and surface distances alter with distance to
// vary the number of points used ... smoothing factor could be a multiple
// of pixel size at given distance. Density from original source is also
// an influencer of smoothing factor and thresholds. Colour contrast also
// has a weighting influence, high contrast is high certainty in the
// disparity so such points should have a high influence over choice of
// surface location.
//
// Magnitude vs dispersion factor in the energy function ...
// * Mag is certainty of surface location
// * Dispersion is how far to propagate that certainty,
if (maxenergy >= ENERGY_THRESHOLD) return;
// Move to next possible surface...
clusterBase = minDepth + 0.04f;
};
} }
// ===== Pass 2 and 3 : Attribute contributions ================================ // ===== Pass 2 and 3 : Attribute contributions ================================
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment