1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// Copyright (c) 2012-2017 VideoStitch SAS
// Copyright (c) 2018 stitchEm
#pragma once
/* Procedure used to generate the inverse warping function
* Terminologies:
* - Input : image captured by the camera
* - Intermediate : projection of "Input" to an intermediate sphere of radius = 1
* - Output: an equi-rectangular projection of the Intermediate sphere onto a cylinder
*/
#define WARPCOORD_INPUT_TO_OUTPUT_KERNEL(fromInputToSphere, isWithin, inverseDistortionMetersTransform, \
inverseRadialPixelsTransform) \
__global__ void \
warpCoordInputToOutputKernel_##fromInputToSphere##_##isWithin##_##inverseDistortionMetersTransform##_##inverseRadialPixelsTransform( \
float2* g_odata, int outputWidth, int outputHeight, int inputImgWidth, int inputImgHeight, int cropImgLeft, \
int cropImgRight, int cropImgTop, int cropImgBottom, int inputWidth, int inputHeight, const int id, \
const float2* g_idata, const uint32_t* g_iMask, const float2 panoScale, const vsfloat3x4 poseInverse, \
const float rigSphereRadius, const float2 inputScale, const vsDistortion distortion, \
const float2 centerShift) { \
/* calculate normalized texture coordinates */ \
const int x = blockIdx.x * blockDim.x + threadIdx.x; \
const int y = blockIdx.y * blockDim.y + threadIdx.y; \
if (x >= inputWidth || y >= inputHeight) return; \
\
float2 uv = g_idata[y * inputWidth + x]; \
int mask = g_iMask[y * inputWidth + x]; \
if (mask != (1 << id)) { \
return; \
} \
if (isWithin(uv, (float)inputImgWidth, (float)inputImgHeight, (float)cropImgLeft, (float)cropImgRight, \
(float)cropImgTop, (float)cropImgBottom)) { \
uv += make_float2(0.5, 0.5); \
uv.x -= inputImgWidth / 2.0f; \
uv.y -= inputImgHeight / 2.0f; \
uv = \
mapInputToPanorama_##fromInputToSphere##_##inverseDistortionMetersTransform##_##inverseRadialPixelsTransform( \
uv, panoScale, poseInverse, rigSphereRadius, inputScale, distortion, centerShift); \
\
/** \
* Move to center-based coordinate \
*/ \
uv.x += outputWidth / 2.0f; \
uv.y += outputHeight / 2.0f; \
\
if (isWithinRect(uv, (float)outputWidth, (float)outputHeight)) { \
g_odata[(y * inputWidth + x)] = uv; \
} \
} \
}
#define WARPCOORD_INPUT_TO_OUTPUT_KERNEL2(INV_RADIAL1, INV_RADIAL2) \
WARPCOORD_INPUT_TO_OUTPUT_KERNEL(RectToSphere, isWithinCropRect, INV_RADIAL1, INV_RADIAL2) \
WARPCOORD_INPUT_TO_OUTPUT_KERNEL(ErectToSphere, isWithinCropRect, INV_RADIAL1, INV_RADIAL2) \
WARPCOORD_INPUT_TO_OUTPUT_KERNEL(FisheyeToSphere, isWithinCropRect, INV_RADIAL1, INV_RADIAL2) \
WARPCOORD_INPUT_TO_OUTPUT_KERNEL(ExternalToSphere, isWithinCropRect, INV_RADIAL1, INV_RADIAL2) \
WARPCOORD_INPUT_TO_OUTPUT_KERNEL(StereoToSphere, isWithinCropRect, INV_RADIAL1, INV_RADIAL2) \
WARPCOORD_INPUT_TO_OUTPUT_KERNEL(RectToSphere, isWithinCropCircle, INV_RADIAL1, INV_RADIAL2) \
WARPCOORD_INPUT_TO_OUTPUT_KERNEL(ErectToSphere, isWithinCropCircle, INV_RADIAL1, INV_RADIAL2) \
WARPCOORD_INPUT_TO_OUTPUT_KERNEL(FisheyeToSphere, isWithinCropCircle, INV_RADIAL1, INV_RADIAL2) \
WARPCOORD_INPUT_TO_OUTPUT_KERNEL(ExternalToSphere, isWithinCropCircle, INV_RADIAL1, INV_RADIAL2) \
WARPCOORD_INPUT_TO_OUTPUT_KERNEL(StereoToSphere, isWithinCropCircle, INV_RADIAL1, INV_RADIAL2)