1. 主函数

    void SeparableLinearFilter::apply(InputArray _src, OutputArray _dst, Stream& _stream)
{
GpuMat src = _src.getGpuMat();
CV_Assert( src.type() == srcType_ ); _dst.create(src.size(), dstType_);
GpuMat dst = _dst.getGpuMat(); ensureSizeIsEnough(src.size(), bufType_, buf_); DeviceInfo devInfo;
const int cc = devInfo.majorVersion() * + devInfo.minorVersion(); cudaStream_t stream = StreamAccessor::getStream(_stream); rowFilter_(src, buf_, rowKernel_.ptr<float>(), rowKernel_.cols, anchor_.x, rowBorderMode_, cc, stream);
columnFilter_(buf_, dst, columnKernel_.ptr<float>(), columnKernel_.cols, anchor_.y, columnBorderMode_, cc, stream);
}

the block of col is   16X16 , the block of  row is 32X8

2. COL

namespace filter
{
template <typename T, typename D>
void linearColumn(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream)
{
typedef void (*caller_t)(PtrStepSz<T> src, PtrStepSz<D> dst, const float* kernel, int anchor, int cc, cudaStream_t stream); static const caller_t callers[][] =
{
{
,
column_filter::caller< , T, D, BrdColConstant>,
column_filter::caller< , T, D, BrdColConstant>,
column_filter::caller< , T, D, BrdColConstant>,
column_filter::caller< , T, D, BrdColConstant>,
column_filter::caller< , T, D, BrdColConstant>,
column_filter::caller< , T, D, BrdColConstant>,
column_filter::caller< , T, D, BrdColConstant>,
column_filter::caller< , T, D, BrdColConstant>,
column_filter::caller< , T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>,
column_filter::caller<, T, D, BrdColConstant>
},
{
,
column_filter::caller< , T, D, BrdColReplicate>,
column_filter::caller< , T, D, BrdColReplicate>,
column_filter::caller< , T, D, BrdColReplicate>,
column_filter::caller< , T, D, BrdColReplicate>,
column_filter::caller< , T, D, BrdColReplicate>,
column_filter::caller< , T, D, BrdColReplicate>,
column_filter::caller< , T, D, BrdColReplicate>,
column_filter::caller< , T, D, BrdColReplicate>,
column_filter::caller< , T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>,
column_filter::caller<, T, D, BrdColReplicate>
},
{
,
column_filter::caller< , T, D, BrdColReflect>,
column_filter::caller< , T, D, BrdColReflect>,
column_filter::caller< , T, D, BrdColReflect>,
column_filter::caller< , T, D, BrdColReflect>,
column_filter::caller< , T, D, BrdColReflect>,
column_filter::caller< , T, D, BrdColReflect>,
column_filter::caller< , T, D, BrdColReflect>,
column_filter::caller< , T, D, BrdColReflect>,
column_filter::caller< , T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>,
column_filter::caller<, T, D, BrdColReflect>
},
{
,
column_filter::caller< , T, D, BrdColWrap>,
column_filter::caller< , T, D, BrdColWrap>,
column_filter::caller< , T, D, BrdColWrap>,
column_filter::caller< , T, D, BrdColWrap>,
column_filter::caller< , T, D, BrdColWrap>,
column_filter::caller< , T, D, BrdColWrap>,
column_filter::caller< , T, D, BrdColWrap>,
column_filter::caller< , T, D, BrdColWrap>,
column_filter::caller< , T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>,
column_filter::caller<, T, D, BrdColWrap>
},
{
,
column_filter::caller< , T, D, BrdColReflect101>,
column_filter::caller< , T, D, BrdColReflect101>,
column_filter::caller< , T, D, BrdColReflect101>,
column_filter::caller< , T, D, BrdColReflect101>,
column_filter::caller< , T, D, BrdColReflect101>,
column_filter::caller< , T, D, BrdColReflect101>,
column_filter::caller< , T, D, BrdColReflect101>,
column_filter::caller< , T, D, BrdColReflect101>,
column_filter::caller< , T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>,
column_filter::caller<, T, D, BrdColReflect101>
}
}; callers[brd_type][ksize]((PtrStepSz<T>)src, (PtrStepSz<D>)dst, kernel, anchor, cc, stream);
}
}
    template <int KSIZE, typename T, typename D, template<typename> class B>
void caller(PtrStepSz<T> src, PtrStepSz<D> dst, const float* kernel, int anchor, int cc, cudaStream_t stream)
{
int BLOCK_DIM_X;
int BLOCK_DIM_Y;
int PATCH_PER_BLOCK; if (cc >= )
{
BLOCK_DIM_X = 16;
BLOCK_DIM_Y = 16;
PATCH_PER_BLOCK = 4;
}
else
{
BLOCK_DIM_X = 16;
BLOCK_DIM_Y = 8;
PATCH_PER_BLOCK = 2;
} const dim3 block(BLOCK_DIM_X, BLOCK_DIM_Y);
const dim3 grid(divUp(src.cols, BLOCK_DIM_X), divUp(src.rows, BLOCK_DIM_Y * PATCH_PER_BLOCK)); B<T> brd(src.rows); linearColumnFilter<KSIZE, T, D><<<grid, block, , stream>>>(src, dst, kernel, anchor, brd); cudaSafeCall( cudaGetLastError() ); if (stream == )
cudaSafeCall( cudaDeviceSynchronize() );
}
}
    #define MAX_KERNEL_SIZE 32

    template <int KSIZE, typename T, typename D, typename B>
__global__ void linearColumnFilter(const PtrStepSz<T> src, PtrStep<D> dst, const float* kernel, const int anchor, const B brd)
{
#if defined(__CUDA_ARCH__) && (__CUDA_ARCH__ >= 200)
const int BLOCK_DIM_X = ;
const int BLOCK_DIM_Y = ;
const int PATCH_PER_BLOCK = ;
const int HALO_SIZE = KSIZE <= ? : ;
#else
const int BLOCK_DIM_X = ;
const int BLOCK_DIM_Y = ;
const int PATCH_PER_BLOCK = ;
const int HALO_SIZE = ;
#endif typedef typename TypeVec<float, VecTraits<T>::cn>::vec_type sum_t; __shared__ sum_t smem[(PATCH_PER_BLOCK + * HALO_SIZE) * BLOCK_DIM_Y][BLOCK_DIM_X]; const int x = blockIdx.x * BLOCK_DIM_X + threadIdx.x; if (x >= src.cols)
return; const T* src_col = src.ptr() + x; const int yStart = blockIdx.y * (BLOCK_DIM_Y * PATCH_PER_BLOCK) + threadIdx.y; if (blockIdx.y > )
{
//Upper halo
#pragma unroll
for (int j = ; j < HALO_SIZE; ++j)
smem[threadIdx.y + j * BLOCK_DIM_Y][threadIdx.x] = saturate_cast<sum_t>(src(yStart - (HALO_SIZE - j) * BLOCK_DIM_Y, x));
}
else
{
//Upper halo
#pragma unroll
for (int j = ; j < HALO_SIZE; ++j)
smem[threadIdx.y + j * BLOCK_DIM_Y][threadIdx.x] = saturate_cast<sum_t>(brd.at_low(yStart - (HALO_SIZE - j) * BLOCK_DIM_Y, src_col, src.step));
} if (blockIdx.y + < gridDim.y)
{
//Main data
#pragma unroll
for (int j = ; j < PATCH_PER_BLOCK; ++j)
smem[threadIdx.y + HALO_SIZE * BLOCK_DIM_Y + j * BLOCK_DIM_Y][threadIdx.x] = saturate_cast<sum_t>(src(yStart + j * BLOCK_DIM_Y, x)); //Lower halo
#pragma unroll
for (int j = ; j < HALO_SIZE; ++j)
smem[threadIdx.y + (PATCH_PER_BLOCK + HALO_SIZE) * BLOCK_DIM_Y + j * BLOCK_DIM_Y][threadIdx.x] = saturate_cast<sum_t>(src(yStart + (PATCH_PER_BLOCK + j) * BLOCK_DIM_Y, x));
}
else
{
//Main data
#pragma unroll
for (int j = ; j < PATCH_PER_BLOCK; ++j)
smem[threadIdx.y + HALO_SIZE * BLOCK_DIM_Y + j * BLOCK_DIM_Y][threadIdx.x] = saturate_cast<sum_t>(brd.at_high(yStart + j * BLOCK_DIM_Y, src_col, src.step)); //Lower halo
#pragma unroll
for (int j = ; j < HALO_SIZE; ++j)
smem[threadIdx.y + (PATCH_PER_BLOCK + HALO_SIZE) * BLOCK_DIM_Y + j * BLOCK_DIM_Y][threadIdx.x] = saturate_cast<sum_t>(brd.at_high(yStart + (PATCH_PER_BLOCK + j) * BLOCK_DIM_Y, src_col, src.step));
} __syncthreads(); #pragma unroll
for (int j = ; j < PATCH_PER_BLOCK; ++j)
{
const int y = yStart + j * BLOCK_DIM_Y; if (y < src.rows)
{
sum_t sum = VecTraits<sum_t>::all(); #pragma unroll
for (int k = ; k < KSIZE; ++k)
sum = sum + smem[threadIdx.y + HALO_SIZE * BLOCK_DIM_Y + j * BLOCK_DIM_Y - anchor + k][threadIdx.x] * kernel[k]; dst(y, x) = saturate_cast<D>(sum);
}
}
}

3.  ROW

namespace filter
{
template <typename T, typename D>
void linearRow(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream)
{
typedef void (*caller_t)(PtrStepSz<T> src, PtrStepSz<D> dst, const float* kernel, int anchor, int cc, cudaStream_t stream); static const caller_t callers[][] =
{
{
,
row_filter::caller< , T, D, BrdRowConstant>,
row_filter::caller< , T, D, BrdRowConstant>,
row_filter::caller< , T, D, BrdRowConstant>,
row_filter::caller< , T, D, BrdRowConstant>,
row_filter::caller< , T, D, BrdRowConstant>,
row_filter::caller< , T, D, BrdRowConstant>,
row_filter::caller< , T, D, BrdRowConstant>,
row_filter::caller< , T, D, BrdRowConstant>,
row_filter::caller< , T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>,
row_filter::caller<, T, D, BrdRowConstant>
},
{
,
row_filter::caller< , T, D, BrdRowReplicate>,
row_filter::caller< , T, D, BrdRowReplicate>,
row_filter::caller< , T, D, BrdRowReplicate>,
row_filter::caller< , T, D, BrdRowReplicate>,
row_filter::caller< , T, D, BrdRowReplicate>,
row_filter::caller< , T, D, BrdRowReplicate>,
row_filter::caller< , T, D, BrdRowReplicate>,
row_filter::caller< , T, D, BrdRowReplicate>,
row_filter::caller< , T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>,
row_filter::caller<, T, D, BrdRowReplicate>
},
{
,
row_filter::caller< , T, D, BrdRowReflect>,
row_filter::caller< , T, D, BrdRowReflect>,
row_filter::caller< , T, D, BrdRowReflect>,
row_filter::caller< , T, D, BrdRowReflect>,
row_filter::caller< , T, D, BrdRowReflect>,
row_filter::caller< , T, D, BrdRowReflect>,
row_filter::caller< , T, D, BrdRowReflect>,
row_filter::caller< , T, D, BrdRowReflect>,
row_filter::caller< , T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>,
row_filter::caller<, T, D, BrdRowReflect>
},
{
,
row_filter::caller< , T, D, BrdRowWrap>,
row_filter::caller< , T, D, BrdRowWrap>,
row_filter::caller< , T, D, BrdRowWrap>,
row_filter::caller< , T, D, BrdRowWrap>,
row_filter::caller< , T, D, BrdRowWrap>,
row_filter::caller< , T, D, BrdRowWrap>,
row_filter::caller< , T, D, BrdRowWrap>,
row_filter::caller< , T, D, BrdRowWrap>,
row_filter::caller< , T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>,
row_filter::caller<, T, D, BrdRowWrap>
},
{
,
row_filter::caller< , T, D, BrdRowReflect101>,
row_filter::caller< , T, D, BrdRowReflect101>,
row_filter::caller< , T, D, BrdRowReflect101>,
row_filter::caller< , T, D, BrdRowReflect101>,
row_filter::caller< , T, D, BrdRowReflect101>,
row_filter::caller< , T, D, BrdRowReflect101>,
row_filter::caller< , T, D, BrdRowReflect101>,
row_filter::caller< , T, D, BrdRowReflect101>,
row_filter::caller< , T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>,
row_filter::caller<, T, D, BrdRowReflect101>
}
}; callers[brd_type][ksize]((PtrStepSz<T>)src, (PtrStepSz<D>)dst, kernel, anchor, cc, stream);
}
}
    template <int KSIZE, typename T, typename D, template<typename> class B>
void caller(PtrStepSz<T> src, PtrStepSz<D> dst, const float* kernel, int anchor, int cc, cudaStream_t stream)
{
int BLOCK_DIM_X;
int BLOCK_DIM_Y;
int PATCH_PER_BLOCK; if (cc >= )
{
BLOCK_DIM_X = 32;
BLOCK_DIM_Y = 8;
PATCH_PER_BLOCK = 4;
}
else
{
BLOCK_DIM_X = ;
BLOCK_DIM_Y = ;
PATCH_PER_BLOCK = ;
} const dim3 block(BLOCK_DIM_X, BLOCK_DIM_Y);
const dim3 grid(divUp(src.cols, BLOCK_DIM_X * PATCH_PER_BLOCK), divUp(src.rows, BLOCK_DIM_Y)); B<T> brd(src.cols); linearRowFilter<KSIZE, T, D><<<grid, block, , stream>>>(src, dst, kernel, anchor, brd);
cudaSafeCall( cudaGetLastError() ); if (stream == )
cudaSafeCall( cudaDeviceSynchronize() );
}
    #define MAX_KERNEL_SIZE 32

    template <int KSIZE, typename T, typename D, typename B>
__global__ void linearRowFilter(const PtrStepSz<T> src, PtrStep<D> dst, const float* kernel, const int anchor, const B brd)
{
#if defined(__CUDA_ARCH__) && (__CUDA_ARCH__ >= 200)
const int BLOCK_DIM_X = ;
const int BLOCK_DIM_Y = ;
const int PATCH_PER_BLOCK = ;
const int HALO_SIZE = ;
#else
const int BLOCK_DIM_X = ;
const int BLOCK_DIM_Y = ;
const int PATCH_PER_BLOCK = ;
const int HALO_SIZE = ;
#endif typedef typename TypeVec<float, VecTraits<T>::cn>::vec_type sum_t; __shared__ sum_t smem[BLOCK_DIM_Y][(PATCH_PER_BLOCK + * HALO_SIZE) * BLOCK_DIM_X]; const int y = blockIdx.y * BLOCK_DIM_Y + threadIdx.y; if (y >= src.rows)
return; const T* src_row = src.ptr(y); const int xStart = blockIdx.x * (PATCH_PER_BLOCK * BLOCK_DIM_X) + threadIdx.x; if (blockIdx.x > )
{
//Load left halo
#pragma unroll
for (int j = ; j < HALO_SIZE; ++j)
smem[threadIdx.y][threadIdx.x + j * BLOCK_DIM_X] = saturate_cast<sum_t>(src_row[xStart - (HALO_SIZE - j) * BLOCK_DIM_X]);
}
else
{
//Load left halo
#pragma unroll
for (int j = ; j < HALO_SIZE; ++j)
smem[threadIdx.y][threadIdx.x + j * BLOCK_DIM_X] = saturate_cast<sum_t>(brd.at_low(xStart - (HALO_SIZE - j) * BLOCK_DIM_X, src_row));
} if (blockIdx.x + < gridDim.x)
{
//Load main data
#pragma unroll
for (int j = ; j < PATCH_PER_BLOCK; ++j)
smem[threadIdx.y][threadIdx.x + HALO_SIZE * BLOCK_DIM_X + j * BLOCK_DIM_X] = saturate_cast<sum_t>(src_row[xStart + j * BLOCK_DIM_X]); //Load right halo
#pragma unroll
for (int j = ; j < HALO_SIZE; ++j)
smem[threadIdx.y][threadIdx.x + (PATCH_PER_BLOCK + HALO_SIZE) * BLOCK_DIM_X + j * BLOCK_DIM_X] = saturate_cast<sum_t>(src_row[xStart + (PATCH_PER_BLOCK + j) * BLOCK_DIM_X]);
}
else
{
//Load main data
#pragma unroll
for (int j = ; j < PATCH_PER_BLOCK; ++j)
smem[threadIdx.y][threadIdx.x + HALO_SIZE * BLOCK_DIM_X + j * BLOCK_DIM_X] = saturate_cast<sum_t>(brd.at_high(xStart + j * BLOCK_DIM_X, src_row)); //Load right halo
#pragma unroll
for (int j = ; j < HALO_SIZE; ++j)
smem[threadIdx.y][threadIdx.x + (PATCH_PER_BLOCK + HALO_SIZE) * BLOCK_DIM_X + j * BLOCK_DIM_X] = saturate_cast<sum_t>(brd.at_high(xStart + (PATCH_PER_BLOCK + j) * BLOCK_DIM_X, src_row));
} __syncthreads(); #pragma unroll
for (int j = ; j < PATCH_PER_BLOCK; ++j)
{
const int x = xStart + j * BLOCK_DIM_X; if (x < src.cols)
{
sum_t sum = VecTraits<sum_t>::all(); #pragma unroll
for (int k = ; k < KSIZE; ++k)
sum = sum + smem[threadIdx.y][threadIdx.x + HALO_SIZE * BLOCK_DIM_X + j * BLOCK_DIM_X - anchor + k] * kernel[k]; dst(y, x) = saturate_cast<D>(sum);
}
}
}

opencv 源码分析 CUDA可分离滤波器设计 ( 发现OpenCV的cuda真TM慢 )的更多相关文章

  1. OpenCV源码分析:RGB到其他色彩空间的转换

    1.流程调用图 2.部分代码分析 //模板函数进行颜色空间的转换 template <typename Cvt> void CvtColorLoop(const Mat& src, ...

  2. jQuery源码分析系列

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...

  3. Redis学习——ae事件处理源码分析

    0. 前言 Redis在封装事件的处理采用了Reactor模式,添加了定时事件的处理.Redis处理事件是单进程单线程的,而经典Reator模式对事件是串行处理的.即如果有一个事件阻塞过久的话会导致整 ...

  4. [转]jQuery源码分析系列

    文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...

  5. jQuery源码分析系列——来自Aaron

    jQuery源码分析系列——来自Aaron 转载地址:http://www.cnblogs.com/aaronjs/p/3279314.html 版本截止到2013.8.24 jQuery官方发布最新 ...

  6. MQTT再学习 -- MQTT 客户端源码分析

    MQTT 源码分析,搜索了一下发现网络上讲的很少,多是逍遥子的那几篇. 参看:逍遥子_mosquitto源码分析系列 参看:MQTT libmosquitto源码分析 参看:Mosquitto学习笔记 ...

  7. Visual Studio调试到OpenCV源码中

    TL;DR VS2015下,build-farm/vs2015-x64/bin/Debug/目录,*.pdb文件,都拷贝到install/x64/vc14/bin目录,就可以调试进去opencv源码了 ...

  8. springmvc拦截器入门及其执行顺序源码分析

    springmvc拦截器是偶尔会用到的一个功能,本案例来演示一个较简单的springmvc拦截器的使用,并通过源码来分析拦截器的执行顺序的控制.具体操作步骤为:1.maven项目引入spring依赖2 ...

  9. druid 源码分析与学习(含详细监控设计思路的彩蛋)(转)

    原文路径:http://herman-liu76.iteye.com/blog/2308563  Druid是阿里巴巴公司的数据库连接池工具,昨天突然想学习一下阿里的druid源码,于是下载下来分析了 ...

随机推荐

  1. Linux+Tomcat环境下安装SSL证书

    1.将申请好的证书(4个文件)文件放入/home/tomcat/apache-tomcat-9.0.12/conf/cert文件夹下2.(或者)将申请好的证书(4个文件)文件放入/home/tomca ...

  2. 面试问我 Java 逃逸分析,瞬间被秒杀了。。

    记得几年前有一次栈长去面试,问到了这么一个问题: Java中的对象都是在堆中分配吗?说明为什么! 当时我被问得一脸蒙逼,瞬间被秒杀得体无完肤,当时我压根就不知道他在考什么知识点,难道对象不是在堆中分配 ...

  3. 微信小程序之页面导航栏

    效果图: 页面有点丑,作为初次学习,页面可以要求不那么美观,先学会再说.毕竟后面可以优化的很漂亮. 代码实例如下: <view class="section btn-area" ...

  4. [Beta]第二次 Scrum Meeting

    [Beta]第二次 Scrum Meeting 写在前面 会议时间 会议时长 会议地点 2019/5/6 22:00 30min 大运村公寓6F楼道 附Github仓库:WEDO 例会照片 工作情况总 ...

  5. 如何查看Linux服务器是32位还是64位?

    使用命令 “getconf LONG_BIT” 如果返回的是32,那么就是32位 如果返回的是64,那么就是64位

  6. matlab学习笔记8 基本绘图命令-基本绘图操作

    一起来学matlab-matlab学习笔记8 基本绘图命令_2基本绘图操作 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考书籍 <matlab 程序设计与综合应用>张德丰等著 ...

  7. Docker实践之03-Dockerfile指令详解

    目录 FROM,指定基础镜像 RUN,执行命令 COPY,复制文件 ADD,复制并解压文件 CMD,容器启动命令 ENTRYPOINT,入口点 ENV,设置环境变量 ARG,构建参数 VOLUME,定 ...

  8. css几个优先级测试和!important

    css样式不加!important情况下的有默认优先级 ,用!important提高优先级,最常见的css样式选择器的优先级测试.之前博文里也用到了提升优先级的方法: 测试结果:加了!importan ...

  9. Linux配置AndroidSDK&Jenkins远程部署

    最近将公司的项目部署了Jenkins持续集成,遇到了几个麻烦的点,其中之一就是将Android SDK进行配置在远程服务器(总结下来还是自己对Linux命令还不够熟悉),特此记录. 系统: Ubunt ...

  10. webbench源码学习笔记

    学习内容 一共五百多行代码,其中包含了linux编程常用的API.可以通过学习源码,把不熟悉的API练习练习. 1 如何使用webbench (1)查看参数帮助 (2)运行方法 即以上模拟30个客户端 ...