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. 前端VScode推荐插件

    Auto Close Tag 自动添加HTML / XML关闭标签 Auto Rename Tag 自动重命名配对的HTML / XML标签 Beautify 格式化代码 [必须]Bracket Pa ...

  2. Mysql问题1862

    使用Navicat连接MySQL数据库出现1862错误(1862:Your password has expired.To log in you must change it change it us ...

  3. 剑指offer:二叉搜索树与双向链表

    题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 思路分析: 这道题一开始的思路是借用队列结构,首先中序遍历二叉树,按顺序 ...

  4. SpringBoot使用jasypt加解密密码

    在我们的服务中不可避免的需要使用到一些秘钥(数据库.redis等) 开发和测试环境还好,但生产如果采用明文配置讲会有安全问题,jasypt是一个通用的加解密库,我们可以使用它. <depende ...

  5. python2中的unicode()函数在python3中会报错:

    python2中的unicode()函数在python3中会报错:NameError: name 'unicode' is not defined There is no such name in P ...

  6. java 多线程 面试

    1.多线程有什么用? (1)发挥多核CPU的优势: 当前,应用服务器至少也都是双核的,4核.8核甚至16核的也都不少见,如果是单线程的程序,那么在双核CPU上就浪费了50%,在4核CPU上就浪费了75 ...

  7. maven设置阿里云仓库

    到maven安装目录的conf下setting.xml文件 找到mirrors标签中添加 <mirror> <id>nexus-aliyun</id> <mi ...

  8. 获取apk的Activity和Package

    2.查看包名和activity adb logcat|grep -i activitymanager 获取当前界面的activity 1.adb shell dumpsys window window ...

  9. windows下大数据开发环境搭建(1)——Java环境搭建

    一.Java 8下载 https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 下载之后 ...

  10. OpenGL入门学习--超级好的资料

    近几天,由于工作项目需要利用openGL显示STL格式的三维模型,分享下面的BOOK,这个老外写得真是TMD太好了,资料免费! http://www.glprogramming.com/red/ind ...