mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 00:03:03 +04:00
gpucalib3d module for camera calibration and stereo correspondence
This commit is contained in:
@@ -80,18 +80,6 @@ CV_EXPORTS void meanShiftProc(const GpuMat& src, GpuMat& dstr, GpuMat& dstsp, in
|
||||
CV_EXPORTS void meanShiftSegmentation(const GpuMat& src, Mat& dst, int sp, int sr, int minsize,
|
||||
TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 5, 1));
|
||||
|
||||
//! Does coloring of disparity image: [0..ndisp) -> [0..240, 1, 1] in HSV.
|
||||
//! Supported types of input disparity: CV_8U, CV_16S.
|
||||
//! Output disparity has CV_8UC4 type in BGRA format (alpha = 255).
|
||||
CV_EXPORTS void drawColorDisp(const GpuMat& src_disp, GpuMat& dst_disp, int ndisp, Stream& stream = Stream::Null());
|
||||
|
||||
//! Reprojects disparity image to 3D space.
|
||||
//! Supports CV_8U and CV_16S types of input disparity.
|
||||
//! The output is a 3- or 4-channel floating-point matrix.
|
||||
//! Each element of this matrix will contain the 3D coordinates of the point (x,y,z,1), computed from the disparity map.
|
||||
//! Q is the 4x4 perspective transformation matrix that can be obtained with cvStereoRectify.
|
||||
CV_EXPORTS void reprojectImageTo3D(const GpuMat& disp, GpuMat& xyzw, const Mat& Q, int dst_cn = 4, Stream& stream = Stream::Null());
|
||||
|
||||
//! converts image from one color space to another
|
||||
CV_EXPORTS void cvtColor(const GpuMat& src, GpuMat& dst, int code, int dcn = 0, Stream& stream = Stream::Null());
|
||||
|
||||
|
||||
@@ -183,187 +183,6 @@ namespace cv { namespace gpu { namespace cudev
|
||||
//cudaSafeCall( cudaUnbindTexture( tex_meanshift ) );
|
||||
}
|
||||
|
||||
/////////////////////////////////// drawColorDisp ///////////////////////////////////////////////
|
||||
|
||||
template <typename T>
|
||||
__device__ unsigned int cvtPixel(T d, int ndisp, float S = 1, float V = 1)
|
||||
{
|
||||
unsigned int H = ((ndisp-d) * 240)/ndisp;
|
||||
|
||||
unsigned int hi = (H/60) % 6;
|
||||
float f = H/60.f - H/60;
|
||||
float p = V * (1 - S);
|
||||
float q = V * (1 - f * S);
|
||||
float t = V * (1 - (1 - f) * S);
|
||||
|
||||
float3 res;
|
||||
|
||||
if (hi == 0) //R = V, G = t, B = p
|
||||
{
|
||||
res.x = p;
|
||||
res.y = t;
|
||||
res.z = V;
|
||||
}
|
||||
|
||||
if (hi == 1) // R = q, G = V, B = p
|
||||
{
|
||||
res.x = p;
|
||||
res.y = V;
|
||||
res.z = q;
|
||||
}
|
||||
|
||||
if (hi == 2) // R = p, G = V, B = t
|
||||
{
|
||||
res.x = t;
|
||||
res.y = V;
|
||||
res.z = p;
|
||||
}
|
||||
|
||||
if (hi == 3) // R = p, G = q, B = V
|
||||
{
|
||||
res.x = V;
|
||||
res.y = q;
|
||||
res.z = p;
|
||||
}
|
||||
|
||||
if (hi == 4) // R = t, G = p, B = V
|
||||
{
|
||||
res.x = V;
|
||||
res.y = p;
|
||||
res.z = t;
|
||||
}
|
||||
|
||||
if (hi == 5) // R = V, G = p, B = q
|
||||
{
|
||||
res.x = q;
|
||||
res.y = p;
|
||||
res.z = V;
|
||||
}
|
||||
const unsigned int b = (unsigned int)(::max(0.f, ::min(res.x, 1.f)) * 255.f);
|
||||
const unsigned int g = (unsigned int)(::max(0.f, ::min(res.y, 1.f)) * 255.f);
|
||||
const unsigned int r = (unsigned int)(::max(0.f, ::min(res.z, 1.f)) * 255.f);
|
||||
const unsigned int a = 255U;
|
||||
|
||||
return (a << 24) + (r << 16) + (g << 8) + b;
|
||||
}
|
||||
|
||||
__global__ void drawColorDisp(uchar* disp, size_t disp_step, uchar* out_image, size_t out_step, int width, int height, int ndisp)
|
||||
{
|
||||
const int x = (blockIdx.x * blockDim.x + threadIdx.x) << 2;
|
||||
const int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
|
||||
if(x < width && y < height)
|
||||
{
|
||||
uchar4 d4 = *(uchar4*)(disp + y * disp_step + x);
|
||||
|
||||
uint4 res;
|
||||
res.x = cvtPixel(d4.x, ndisp);
|
||||
res.y = cvtPixel(d4.y, ndisp);
|
||||
res.z = cvtPixel(d4.z, ndisp);
|
||||
res.w = cvtPixel(d4.w, ndisp);
|
||||
|
||||
uint4* line = (uint4*)(out_image + y * out_step);
|
||||
line[x >> 2] = res;
|
||||
}
|
||||
}
|
||||
|
||||
__global__ void drawColorDisp(short* disp, size_t disp_step, uchar* out_image, size_t out_step, int width, int height, int ndisp)
|
||||
{
|
||||
const int x = (blockIdx.x * blockDim.x + threadIdx.x) << 1;
|
||||
const int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
|
||||
if(x < width && y < height)
|
||||
{
|
||||
short2 d2 = *(short2*)(disp + y * disp_step + x);
|
||||
|
||||
uint2 res;
|
||||
res.x = cvtPixel(d2.x, ndisp);
|
||||
res.y = cvtPixel(d2.y, ndisp);
|
||||
|
||||
uint2* line = (uint2*)(out_image + y * out_step);
|
||||
line[x >> 1] = res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void drawColorDisp_gpu(const PtrStepSzb& src, const PtrStepSzb& dst, int ndisp, const cudaStream_t& stream)
|
||||
{
|
||||
dim3 threads(16, 16, 1);
|
||||
dim3 grid(1, 1, 1);
|
||||
grid.x = divUp(src.cols, threads.x << 2);
|
||||
grid.y = divUp(src.rows, threads.y);
|
||||
|
||||
drawColorDisp<<<grid, threads, 0, stream>>>(src.data, src.step, dst.data, dst.step, src.cols, src.rows, ndisp);
|
||||
cudaSafeCall( cudaGetLastError() );
|
||||
|
||||
if (stream == 0)
|
||||
cudaSafeCall( cudaDeviceSynchronize() );
|
||||
}
|
||||
|
||||
void drawColorDisp_gpu(const PtrStepSz<short>& src, const PtrStepSzb& dst, int ndisp, const cudaStream_t& stream)
|
||||
{
|
||||
dim3 threads(32, 8, 1);
|
||||
dim3 grid(1, 1, 1);
|
||||
grid.x = divUp(src.cols, threads.x << 1);
|
||||
grid.y = divUp(src.rows, threads.y);
|
||||
|
||||
drawColorDisp<<<grid, threads, 0, stream>>>(src.data, src.step / sizeof(short), dst.data, dst.step, src.cols, src.rows, ndisp);
|
||||
cudaSafeCall( cudaGetLastError() );
|
||||
|
||||
if (stream == 0)
|
||||
cudaSafeCall( cudaDeviceSynchronize() );
|
||||
}
|
||||
|
||||
/////////////////////////////////// reprojectImageTo3D ///////////////////////////////////////////////
|
||||
|
||||
__constant__ float cq[16];
|
||||
|
||||
template <typename T, typename D>
|
||||
__global__ void reprojectImageTo3D(const PtrStepSz<T> disp, PtrStep<D> xyz)
|
||||
{
|
||||
const int x = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
const int y = blockIdx.y * blockDim.y + threadIdx.y;
|
||||
|
||||
if (y >= disp.rows || x >= disp.cols)
|
||||
return;
|
||||
|
||||
const float qx = x * cq[ 0] + y * cq[ 1] + cq[ 3];
|
||||
const float qy = x * cq[ 4] + y * cq[ 5] + cq[ 7];
|
||||
const float qz = x * cq[ 8] + y * cq[ 9] + cq[11];
|
||||
const float qw = x * cq[12] + y * cq[13] + cq[15];
|
||||
|
||||
const T d = disp(y, x);
|
||||
|
||||
const float iW = 1.f / (qw + cq[14] * d);
|
||||
|
||||
D v = VecTraits<D>::all(1.0f);
|
||||
v.x = (qx + cq[2] * d) * iW;
|
||||
v.y = (qy + cq[6] * d) * iW;
|
||||
v.z = (qz + cq[10] * d) * iW;
|
||||
|
||||
xyz(y, x) = v;
|
||||
}
|
||||
|
||||
template <typename T, typename D>
|
||||
void reprojectImageTo3D_gpu(const PtrStepSzb disp, PtrStepSzb xyz, const float* q, cudaStream_t stream)
|
||||
{
|
||||
dim3 block(32, 8);
|
||||
dim3 grid(divUp(disp.cols, block.x), divUp(disp.rows, block.y));
|
||||
|
||||
cudaSafeCall( cudaMemcpyToSymbol(cq, q, 16 * sizeof(float)) );
|
||||
|
||||
reprojectImageTo3D<T, D><<<grid, block, 0, stream>>>((PtrStepSz<T>)disp, (PtrStepSz<D>)xyz);
|
||||
cudaSafeCall( cudaGetLastError() );
|
||||
|
||||
if (stream == 0)
|
||||
cudaSafeCall( cudaDeviceSynchronize() );
|
||||
}
|
||||
|
||||
template void reprojectImageTo3D_gpu<uchar, float3>(const PtrStepSzb disp, PtrStepSzb xyz, const float* q, cudaStream_t stream);
|
||||
template void reprojectImageTo3D_gpu<uchar, float4>(const PtrStepSzb disp, PtrStepSzb xyz, const float* q, cudaStream_t stream);
|
||||
template void reprojectImageTo3D_gpu<short, float3>(const PtrStepSzb disp, PtrStepSzb xyz, const float* q, cudaStream_t stream);
|
||||
template void reprojectImageTo3D_gpu<short, float4>(const PtrStepSzb disp, PtrStepSzb xyz, const float* q, cudaStream_t stream);
|
||||
|
||||
/////////////////////////////////////////// Corner Harris /////////////////////////////////////////////////
|
||||
|
||||
texture<float, cudaTextureType2D, cudaReadModeElementType> harrisDxTex(0, cudaFilterModePoint, cudaAddressModeClamp);
|
||||
|
||||
@@ -49,8 +49,6 @@ using namespace cv::gpu;
|
||||
|
||||
void cv::gpu::meanShiftFiltering(const GpuMat&, GpuMat&, int, int, TermCriteria, Stream&) { throw_no_cuda(); }
|
||||
void cv::gpu::meanShiftProc(const GpuMat&, GpuMat&, GpuMat&, int, int, TermCriteria, Stream&) { throw_no_cuda(); }
|
||||
void cv::gpu::drawColorDisp(const GpuMat&, GpuMat&, int, Stream&) { throw_no_cuda(); }
|
||||
void cv::gpu::reprojectImageTo3D(const GpuMat&, GpuMat&, const Mat&, int, Stream&) { throw_no_cuda(); }
|
||||
void cv::gpu::buildWarpPlaneMaps(Size, Rect, const Mat&, const Mat&, const Mat&, float, GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); }
|
||||
void cv::gpu::buildWarpCylindricalMaps(Size, Rect, const Mat&, const Mat&, float, GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); }
|
||||
void cv::gpu::buildWarpSphericalMaps(Size, Rect, const Mat&, const Mat&, float, GpuMat&, GpuMat&, Stream&) { throw_no_cuda(); }
|
||||
@@ -157,74 +155,6 @@ void cv::gpu::meanShiftProc(const GpuMat& src, GpuMat& dstr, GpuMat& dstsp, int
|
||||
meanShiftProc_gpu(src, dstr, dstsp, sp, sr, maxIter, eps, StreamAccessor::getStream(stream));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// drawColorDisp
|
||||
|
||||
namespace cv { namespace gpu { namespace cudev
|
||||
{
|
||||
namespace imgproc
|
||||
{
|
||||
void drawColorDisp_gpu(const PtrStepSzb& src, const PtrStepSzb& dst, int ndisp, const cudaStream_t& stream);
|
||||
void drawColorDisp_gpu(const PtrStepSz<short>& src, const PtrStepSzb& dst, int ndisp, const cudaStream_t& stream);
|
||||
}
|
||||
}}}
|
||||
|
||||
namespace
|
||||
{
|
||||
template <typename T>
|
||||
void drawColorDisp_caller(const GpuMat& src, GpuMat& dst, int ndisp, const cudaStream_t& stream)
|
||||
{
|
||||
using namespace ::cv::gpu::cudev::imgproc;
|
||||
|
||||
dst.create(src.size(), CV_8UC4);
|
||||
|
||||
drawColorDisp_gpu((PtrStepSz<T>)src, dst, ndisp, stream);
|
||||
}
|
||||
|
||||
typedef void (*drawColorDisp_caller_t)(const GpuMat& src, GpuMat& dst, int ndisp, const cudaStream_t& stream);
|
||||
|
||||
const drawColorDisp_caller_t drawColorDisp_callers[] = {drawColorDisp_caller<unsigned char>, 0, 0, drawColorDisp_caller<short>, 0, 0, 0, 0};
|
||||
}
|
||||
|
||||
void cv::gpu::drawColorDisp(const GpuMat& src, GpuMat& dst, int ndisp, Stream& stream)
|
||||
{
|
||||
CV_Assert(src.type() == CV_8U || src.type() == CV_16S);
|
||||
|
||||
drawColorDisp_callers[src.type()](src, dst, ndisp, StreamAccessor::getStream(stream));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// reprojectImageTo3D
|
||||
|
||||
namespace cv { namespace gpu { namespace cudev
|
||||
{
|
||||
namespace imgproc
|
||||
{
|
||||
template <typename T, typename D>
|
||||
void reprojectImageTo3D_gpu(const PtrStepSzb disp, PtrStepSzb xyz, const float* q, cudaStream_t stream);
|
||||
}
|
||||
}}}
|
||||
|
||||
void cv::gpu::reprojectImageTo3D(const GpuMat& disp, GpuMat& xyz, const Mat& Q, int dst_cn, Stream& stream)
|
||||
{
|
||||
using namespace cv::gpu::cudev::imgproc;
|
||||
|
||||
typedef void (*func_t)(const PtrStepSzb disp, PtrStepSzb xyz, const float* q, cudaStream_t stream);
|
||||
static const func_t funcs[2][4] =
|
||||
{
|
||||
{reprojectImageTo3D_gpu<uchar, float3>, 0, 0, reprojectImageTo3D_gpu<short, float3>},
|
||||
{reprojectImageTo3D_gpu<uchar, float4>, 0, 0, reprojectImageTo3D_gpu<short, float4>}
|
||||
};
|
||||
|
||||
CV_Assert(disp.type() == CV_8U || disp.type() == CV_16S);
|
||||
CV_Assert(Q.type() == CV_32F && Q.rows == 4 && Q.cols == 4 && Q.isContinuous());
|
||||
CV_Assert(dst_cn == 3 || dst_cn == 4);
|
||||
|
||||
xyz.create(disp.size(), CV_MAKE_TYPE(CV_32F, dst_cn));
|
||||
|
||||
funcs[dst_cn == 4][disp.type()](disp, xyz, Q.ptr<float>(), StreamAccessor::getStream(stream));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// buildWarpPlaneMaps
|
||||
|
||||
|
||||
Reference in New Issue
Block a user