added support of gamama_correction parameter into gpu::HOGDescriptor, updated tests
This commit is contained in:
@@ -1076,6 +1076,7 @@ namespace cv
|
||||
double win_sigma;
|
||||
double threshold_L2hys;
|
||||
int nlevels;
|
||||
bool gamma_correction;
|
||||
|
||||
protected:
|
||||
void computeBlockHistograms(const GpuMat& img);
|
||||
@@ -1084,8 +1085,6 @@ namespace cv
|
||||
static int numPartsWithin(int size, int part_size, int stride);
|
||||
static Size numPartsWithin(Size size, Size part_size, Size stride);
|
||||
|
||||
bool gamma_correction;
|
||||
|
||||
// Coefficients of the separating plane
|
||||
float free_coef;
|
||||
GpuMat detector;
|
||||
|
@@ -522,7 +522,7 @@ void extract_descrs_by_cols(int win_height, int win_width, int block_stride_y, i
|
||||
// Gradients computation
|
||||
|
||||
|
||||
template <int nthreads>
|
||||
template <int nthreads, int correct_gamma>
|
||||
__global__ void compute_gradients_8UC4_kernel(int height, int width, const PtrElemStep img,
|
||||
float angle_scale, PtrElemStepf grad, PtrElemStep qangle)
|
||||
{
|
||||
@@ -533,11 +533,10 @@ __global__ void compute_gradients_8UC4_kernel(int height, int width, const PtrEl
|
||||
__shared__ float sh_row[(nthreads + 2) * 3];
|
||||
|
||||
uchar4 val;
|
||||
if (x < width)
|
||||
val = row[x];
|
||||
else if (x == width)
|
||||
val = row[x - 2];
|
||||
// Othrewise we do not read variable 'val' at all
|
||||
if (x < width)
|
||||
val = row[x];
|
||||
else
|
||||
val = row[width - 2];
|
||||
|
||||
sh_row[threadIdx.x + 1] = val.x;
|
||||
sh_row[threadIdx.x + 1 + (nthreads + 2)] = val.y;
|
||||
@@ -545,7 +544,7 @@ __global__ void compute_gradients_8UC4_kernel(int height, int width, const PtrEl
|
||||
|
||||
if (threadIdx.x == 0)
|
||||
{
|
||||
val = x > 0 ? row[x - 1] : row[1];
|
||||
val = row[max(x - 1, 1)];
|
||||
sh_row[0] = val.x;
|
||||
sh_row[(nthreads + 2)] = val.y;
|
||||
sh_row[2 * (nthreads + 2)] = val.z;
|
||||
@@ -553,7 +552,7 @@ __global__ void compute_gradients_8UC4_kernel(int height, int width, const PtrEl
|
||||
|
||||
if (threadIdx.x == blockDim.x - 1)
|
||||
{
|
||||
val = (x < width - 1) ? row[x + 1] : row[width - 2];
|
||||
val = row[min(x + 1, width - 2)];
|
||||
sh_row[blockDim.x + 1] = val.x;
|
||||
sh_row[blockDim.x + 1 + (nthreads + 2)] = val.y;
|
||||
sh_row[blockDim.x + 1 + 2 * (nthreads + 2)] = val.z;
|
||||
@@ -571,9 +570,12 @@ __global__ void compute_gradients_8UC4_kernel(int height, int width, const PtrEl
|
||||
a.y = sh_row[threadIdx.x + (nthreads + 2)];
|
||||
a.z = sh_row[threadIdx.x + 2 * (nthreads + 2)];
|
||||
|
||||
float3 dx = make_float3(sqrtf(b.x) - sqrtf(a.x),
|
||||
sqrtf(b.y) - sqrtf(a.y),
|
||||
sqrtf(b.z) - sqrtf(a.z));
|
||||
float3 dx;
|
||||
if (correct_gamma)
|
||||
dx = make_float3(sqrtf(b.x) - sqrtf(a.x), sqrtf(b.y) - sqrtf(a.y), sqrtf(b.z) - sqrtf(a.z));
|
||||
else
|
||||
dx = make_float3(b.x - a.x, b.y - a.y, b.z - a.z);
|
||||
|
||||
float3 dy = make_float3(0.f, 0.f, 0.f);
|
||||
|
||||
if (blockIdx.y > 0 && blockIdx.y < height - 1)
|
||||
@@ -584,9 +586,10 @@ __global__ void compute_gradients_8UC4_kernel(int height, int width, const PtrEl
|
||||
val = ((const uchar4*)img.ptr(blockIdx.y + 1))[x];
|
||||
b = make_float3(val.x, val.y, val.z);
|
||||
|
||||
dy = make_float3(sqrtf(b.x) - sqrtf(a.x),
|
||||
sqrtf(b.y) - sqrtf(a.y),
|
||||
sqrtf(b.z) - sqrtf(a.z));
|
||||
if (correct_gamma)
|
||||
dy = make_float3(sqrtf(b.x) - sqrtf(a.x), sqrtf(b.y) - sqrtf(a.y), sqrtf(b.z) - sqrtf(a.z));
|
||||
else
|
||||
dy = make_float3(b.x - a.x, b.y - a.y, b.z - a.z);
|
||||
}
|
||||
|
||||
float best_dx = dx.x;
|
||||
@@ -623,20 +626,25 @@ __global__ void compute_gradients_8UC4_kernel(int height, int width, const PtrEl
|
||||
|
||||
|
||||
void compute_gradients_8UC4(int nbins, int height, int width, const DevMem2D& img,
|
||||
float angle_scale, DevMem2Df grad, DevMem2D qangle)
|
||||
float angle_scale, DevMem2Df grad, DevMem2D qangle, bool correct_gamma)
|
||||
{
|
||||
const int nthreads = 256;
|
||||
|
||||
dim3 bdim(nthreads, 1);
|
||||
dim3 gdim(div_up(width, bdim.x), div_up(height, bdim.y));
|
||||
|
||||
compute_gradients_8UC4_kernel<nthreads><<<gdim, bdim>>>(height, width, img, angle_scale,
|
||||
grad, qangle);
|
||||
if (correct_gamma)
|
||||
compute_gradients_8UC4_kernel<nthreads, 1><<<gdim, bdim>>>(
|
||||
height, width, img, angle_scale, grad, qangle);
|
||||
else
|
||||
compute_gradients_8UC4_kernel<nthreads, 0><<<gdim, bdim>>>(
|
||||
height, width, img, angle_scale, grad, qangle);
|
||||
|
||||
cudaSafeCall(cudaThreadSynchronize());
|
||||
}
|
||||
|
||||
|
||||
template <int nthreads>
|
||||
template <int nthreads, int correct_gamma>
|
||||
__global__ void compute_gradients_8UC1_kernel(int height, int width, const PtrElemStep img,
|
||||
float angle_scale, PtrElemStepf grad, PtrElemStep qangle)
|
||||
{
|
||||
@@ -647,24 +655,36 @@ __global__ void compute_gradients_8UC1_kernel(int height, int width, const PtrEl
|
||||
__shared__ float sh_row[nthreads + 2];
|
||||
|
||||
if (x < width)
|
||||
sh_row[threadIdx.x + 1] = row[x];
|
||||
else if (x == width)
|
||||
sh_row[threadIdx.x + 1] = row[x - 2];
|
||||
sh_row[threadIdx.x + 1] = row[x];
|
||||
else
|
||||
sh_row[threadIdx.x + 1] = row[width - 2];
|
||||
|
||||
if (threadIdx.x == 0)
|
||||
sh_row[0] = x > 0 ? row[x - 1] : row[1];
|
||||
sh_row[0] = row[max(x - 1, 1)];
|
||||
|
||||
if (threadIdx.x == blockDim.x - 1)
|
||||
sh_row[blockDim.x + 1] = (x < width - 1) ? row[x + 1] : row[width - 2];
|
||||
sh_row[blockDim.x + 1] = row[min(x + 1, width - 2)];
|
||||
|
||||
__syncthreads();
|
||||
if (x < width)
|
||||
{
|
||||
float dx = sqrtf(sh_row[threadIdx.x + 2]) - sqrtf(sh_row[threadIdx.x]);
|
||||
float dx;
|
||||
|
||||
if (correct_gamma)
|
||||
dx = sqrtf(sh_row[threadIdx.x + 2]) - sqrtf(sh_row[threadIdx.x]);
|
||||
else
|
||||
dx = sh_row[threadIdx.x + 2] - sh_row[threadIdx.x];
|
||||
|
||||
float dy = 0.f;
|
||||
if (blockIdx.y > 0 && blockIdx.y < height - 1)
|
||||
dy = sqrtf(((const unsigned char*)img.ptr(blockIdx.y + 1))[x]) -
|
||||
sqrtf(((const unsigned char*)img.ptr(blockIdx.y - 1))[x]);
|
||||
{
|
||||
float a = ((const unsigned char*)img.ptr(blockIdx.y + 1))[x];
|
||||
float b = ((const unsigned char*)img.ptr(blockIdx.y - 1))[x];
|
||||
if (correct_gamma)
|
||||
dy = sqrtf(a) - sqrtf(b);
|
||||
else
|
||||
dy = a - b;
|
||||
}
|
||||
float mag = sqrtf(dx * dx + dy * dy);
|
||||
|
||||
float ang = (atan2f(dy, dx) + CV_PI_F) * angle_scale - 0.5f;
|
||||
@@ -679,15 +699,20 @@ __global__ void compute_gradients_8UC1_kernel(int height, int width, const PtrEl
|
||||
|
||||
|
||||
void compute_gradients_8UC1(int nbins, int height, int width, const DevMem2D& img,
|
||||
float angle_scale, DevMem2Df grad, DevMem2D qangle)
|
||||
float angle_scale, DevMem2Df grad, DevMem2D qangle, bool correct_gamma)
|
||||
{
|
||||
const int nthreads = 256;
|
||||
|
||||
dim3 bdim(nthreads, 1);
|
||||
dim3 gdim(div_up(width, bdim.x), div_up(height, bdim.y));
|
||||
|
||||
compute_gradients_8UC1_kernel<nthreads><<<gdim, bdim>>>(height, width, img, angle_scale,
|
||||
grad, qangle);
|
||||
if (correct_gamma)
|
||||
compute_gradients_8UC1_kernel<nthreads, 1><<<gdim, bdim>>>(
|
||||
height, width, img, angle_scale, grad, qangle);
|
||||
else
|
||||
compute_gradients_8UC1_kernel<nthreads, 0><<<gdim, bdim>>>(
|
||||
height, width, img, angle_scale, grad, qangle);
|
||||
|
||||
cudaSafeCall(cudaThreadSynchronize());
|
||||
}
|
||||
|
||||
|
@@ -85,9 +85,9 @@ void extract_descrs_by_cols(int win_height, int win_width, int block_stride_y, i
|
||||
cv::gpu::DevMem2Df descriptors);
|
||||
|
||||
void compute_gradients_8UC1(int nbins, int height, int width, const cv::gpu::DevMem2D& img,
|
||||
float angle_scale, cv::gpu::DevMem2Df grad, cv::gpu::DevMem2D qangle);
|
||||
float angle_scale, cv::gpu::DevMem2Df grad, cv::gpu::DevMem2D qangle, bool correct_gamma);
|
||||
void compute_gradients_8UC4(int nbins, int height, int width, const cv::gpu::DevMem2D& img,
|
||||
float angle_scale, cv::gpu::DevMem2Df grad, cv::gpu::DevMem2D qangle);
|
||||
float angle_scale, cv::gpu::DevMem2Df grad, cv::gpu::DevMem2D qangle, bool correct_gamma);
|
||||
|
||||
void resize_8UC1(const cv::gpu::DevMem2D& src, cv::gpu::DevMem2D dst);
|
||||
void resize_8UC4(const cv::gpu::DevMem2D& src, cv::gpu::DevMem2D dst);
|
||||
@@ -118,8 +118,6 @@ cv::gpu::HOGDescriptor::HOGDescriptor(Size win_size, Size block_size, Size block
|
||||
|
||||
CV_Assert(cell_size == Size(8, 8));
|
||||
|
||||
CV_Assert(gamma_correction == true);
|
||||
|
||||
Size cells_per_block = Size(block_size.width / cell_size.width,
|
||||
block_size.height / cell_size.height);
|
||||
CV_Assert(cells_per_block == Size(2, 2));
|
||||
@@ -194,10 +192,10 @@ void cv::gpu::HOGDescriptor::computeGradient(const GpuMat& img, GpuMat& grad, Gp
|
||||
float angleScale = (float)(nbins / CV_PI);
|
||||
switch (img.type()) {
|
||||
case CV_8UC1:
|
||||
hog::compute_gradients_8UC1(nbins, img.rows, img.cols, img, angleScale, grad, qangle);
|
||||
hog::compute_gradients_8UC1(nbins, img.rows, img.cols, img, angleScale, grad, qangle, gamma_correction);
|
||||
break;
|
||||
case CV_8UC4:
|
||||
hog::compute_gradients_8UC4(nbins, img.rows, img.cols, img, angleScale, grad, qangle);
|
||||
hog::compute_gradients_8UC4(nbins, img.rows, img.cols, img, angleScale, grad, qangle, gamma_correction);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user