29 #include <opencv2/core/version.hpp>
31 #if CV_MAJOR_VERSION >= 3
32 # include <opencv2/imgcodecs.hpp>
34 # include <opencv2/highgui/highgui.hpp>
37 #include <opencv2/calib3d/calib3d.hpp>
38 #include <opencv2/imgproc/imgproc.hpp>
51 #define CHECK_STATUS(STMT) \
54 VPIStatus status = (STMT); \
55 if (status != VPI_SUCCESS) \
57 char buffer[VPI_MAX_STATUS_MESSAGE_LENGTH]; \
58 vpiGetLastStatusMessage(buffer, sizeof(buffer)); \
59 std::ostringstream ss; \
60 ss << vpiStatusGetName(status) << ": " << buffer; \
61 throw std::runtime_error(ss.str()); \
65 static void PrintUsage(
const char *progname, std::ostream &out)
67 out <<
"Usage: " << progname <<
" <-c W,H> [-s win] <image1> [image2] [image3] ...\n"
69 <<
" W,H\tcheckerboard with WxH squares\n"
70 <<
" win\tsearch window width around checkerboard vertex used\n"
71 <<
"\tin refinement, default is 0 (disable refinement)\n"
72 <<
" imageN\tinput images taken with a fisheye lens camera" << std::endl;
75 static char *my_basename(
char *path)
78 char *name = strrchr(path,
'\\');
80 char *name = strrchr(path,
'/');
96 std::vector<const char *> images;
99 static Params ParseParameters(
int argc,
char *argv[])
105 for (
int i = 1; i < argc; ++i)
107 if (argv[i][0] ==
'-')
109 if (strlen(argv[i] + 1) == 1)
114 PrintUsage(my_basename(argv[0]), std::cout);
120 throw std::invalid_argument(
"Option -c must be followed by checkerboard width and height");
123 if (sscanf(argv[++i],
"%d,%d", &cbSize.width, &cbSize.height) != 2)
125 throw std::invalid_argument(
"Error parsing checkerboard information");
130 params.vtxCount.width = cbSize.width - 1;
131 params.vtxCount.height = cbSize.height - 1;
137 throw std::invalid_argument(
"Option -s must be followed by search window size");
139 if (sscanf(argv[++i],
"%d", ¶ms.searchWinSize) != 1)
141 throw std::invalid_argument(
"Error parsing search window size");
143 if (params.searchWinSize < 0)
145 throw std::invalid_argument(
"Search window size must be >= 0");
150 throw std::invalid_argument(std::string(
"Option -") + (argv[i] + 1) +
" not recognized");
155 throw std::invalid_argument(std::string(
"Option -") + (argv[i] + 1) +
" not recognized");
160 params.images.push_back(argv[i]);
164 if (params.images.empty())
166 throw std::invalid_argument(
"At least one image must be defined");
169 if (cbSize.width <= 3 || cbSize.height <= 3)
171 throw std::invalid_argument(
"Checkerboard size must have at least 3x3 squares");
174 if (params.searchWinSize == 1)
176 throw std::invalid_argument(
"Search window size must be 0 (default) or >= 2");
182 int main(
int argc,
char *argv[])
191 VPIImage tmpIn = NULL, tmpOut = NULL;
199 Params params = ParseParameters(argc, argv);
200 if (params.images.empty())
206 cv::Size imgSize = {};
207 cv::Mat firstImg = cv::imread(params.images[0]);
208 if (firstImg.empty())
210 throw std::runtime_error(
"Can't read " + std::string(params.images[0]));
212 imgSize = firstImg.size();
215 using Mat3 = cv::Matx<double, 3, 3>;
216 Mat3 camMatrix = Mat3::eye();
217 std::vector<double> coeffs(4);
220 coeffs[0] = -0.073234;
221 coeffs[1] = 0.121251;
222 coeffs[2] = -0.120230;
223 coeffs[3] = 0.038480;
226 camMatrix(0, 0) = 440.956750;
227 camMatrix(0, 2) = 659.822931;
228 camMatrix(1, 1) = 439.322113;
229 camMatrix(1, 2) = 451.685233;
230 camMatrix(2, 2) = 1.0;
233 printf(
"Using pre-defined calibration values:\n");
234 printf(
"Fisheye coefficients: %lf %lf %lf %lf\n", coeffs[0], coeffs[1], coeffs[2], coeffs[3]);
235 printf(
"Camera matrix:\n");
236 printf(
"[%lf %lf %lf; %lf %lf %lf; %lf %lf %lf]\n", camMatrix(0, 0), camMatrix(0, 1), camMatrix(0, 2),
237 camMatrix(1, 0), camMatrix(1, 1), camMatrix(1, 2), camMatrix(2, 0), camMatrix(2, 1), camMatrix(2, 2));
253 distModel.
k1 = coeffs[0];
254 distModel.
k2 = coeffs[1];
255 distModel.
k3 = coeffs[2];
256 distModel.
k4 = coeffs[3];
260 for (
int i = 0; i < 2; ++i)
262 for (
int j = 0; j < 3; ++j)
264 K[i][j] = camMatrix(i, j);
270 X[0][0] = X[1][1] = X[2][2] = 1;
291 for (
unsigned i = 0; i < params.images.size(); ++i)
294 cvImage = cv::imread(params.images[i]);
295 assert(!cvImage.empty());
324 snprintf(buf,
sizeof(buf),
"undistort_%03d.jpg", i);
325 imwrite(buf, cvImage);
328 catch (std::exception &e)
330 std::cerr <<
"Error: " << e.what() << std::endl;
331 PrintUsage(my_basename(argv[0]), std::cerr);
Functions and structures for dealing with VPI images.
Declares functions to generate warp maps based on common lens distortion models.
Functions for handling OpenCV interoperability with VPI.
Declares functions that implement the Remap algorithm.
Declaration of VPI status codes handling functions.
Declares functions dealing with VPI streams.
void vpiImageDestroy(VPIImage img)
Destroy an image instance.
struct VPIImageImpl * VPIImage
A handle to an image.
VPIStatus vpiImageCreate(int32_t width, int32_t height, VPIImageFormat fmt, uint64_t flags, VPIImage *img)
Create an empty image instance with the specified flags.
VPIFisheyeMapping mapping
Mapping between pixel angle and pixel distance to image center.
VPIStatus vpiWarpMapGenerateFromFisheyeLensDistortionModel(const VPICameraIntrinsic Kin, const VPICameraExtrinsic X, const VPICameraIntrinsic Kout, const VPIFisheyeLensDistortionModel *distModel, VPIWarpMap *warpMap)
Generates a mapping that corrects image distortions caused by fisheye lenses.
float VPICameraExtrinsic[3][4]
Camera extrinsic matrix.
float VPICameraIntrinsic[2][3]
Camera intrinsic matrix.
@ VPI_FISHEYE_EQUIDISTANT
Specifies the equidistant fisheye mapping.
Holds coefficients for fisheye lens distortion model.
VPIStatus vpiImageCreateWrapperOpenCVMat(const cv::Mat &mat, VPIImageFormat fmt, uint64_t flags, VPIImage *img)
Wraps a cv::Mat in an VPIImage with the given image format.
VPIStatus vpiImageSetWrappedOpenCVMat(VPIImage img, const cv::Mat &mat)
Redefines the wrapped cv::Mat of an existing VPIImage wrapper.
struct VPIPayloadImpl * VPIPayload
A handle to an algorithm payload.
void vpiPayloadDestroy(VPIPayload payload)
Deallocates the payload object and all associated resources.
VPIStatus vpiSubmitRemap(VPIStream stream, uint64_t backend, VPIPayload payload, VPIImage input, VPIImage output, VPIInterpolationType interp, VPIBorderExtension border, uint64_t flags)
Submits a Remap operation to the stream.
VPIStatus vpiCreateRemap(uint64_t backends, const VPIWarpMap *warpMap, VPIPayload *payload)
Create a payload for Remap algorithm.
struct VPIStreamImpl * VPIStream
A handle to a stream.
VPIStatus vpiStreamSync(VPIStream stream)
Blocks the calling thread until all submitted commands in this stream queue are done (queue is empty)...
void vpiStreamDestroy(VPIStream stream)
Destroy a stream instance and deallocate all HW resources.
VPIStatus vpiStreamCreate(uint64_t flags, VPIStream *stream)
Create a stream instance.
@ VPI_BACKEND_CUDA
CUDA backend.
@ VPI_BORDER_ZERO
All pixels outside the image are considered to be zero.
@ VPI_INTERP_CATMULL_ROM
Catmull-Rom cubic interpolation.
int8_t numHorizRegions
Number of regions horizontally.
VPIWarpGrid grid
Warp grid control point structure definition.
int16_t horizInterval[VPI_WARPGRID_MAX_HORIZ_REGIONS_COUNT]
Horizontal spacing between control points within a given region.
int8_t numVertRegions
Number of regions vertically.
int16_t vertInterval[VPI_WARPGRID_MAX_VERT_REGIONS_COUNT]
Vertical spacing between control points within a given region.
int16_t regionWidth[VPI_WARPGRID_MAX_HORIZ_REGIONS_COUNT]
Width of each region.
int16_t regionHeight[VPI_WARPGRID_MAX_VERT_REGIONS_COUNT]
Height of each region.
void vpiWarpMapFreeData(VPIWarpMap *warpMap)
Deallocates the warp map control points allocated by vpiWarpMapAllocData.
VPIStatus vpiWarpMapAllocData(VPIWarpMap *warpMap)
Allocates the warp map's control point array for a given warp grid.
Defines the mapping between input and output images' pixels.