284 lines
9.4 KiB
C++
284 lines
9.4 KiB
C++
#include <stdlib.h>
|
||
#include <stdio.h>
|
||
#include <string.h>
|
||
#include <errno.h>
|
||
#include <time.h>
|
||
|
||
#if OPENCV_SUPPORT
|
||
#include <Eigen/Core>
|
||
#include <opencv2/opencv.hpp>
|
||
#define MIN_VALUE 2.2204e-16 //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||
#define IS_DOUBLE_ZERO(d) ((d < MIN_VALUE)&&((-d)<MIN_VALUE))
|
||
/* <20><><EFBFBD>۲<EFBFBD><DBB2><EFBFBD> */
|
||
struct CameraCoeff
|
||
{
|
||
double cx, cy; // <20><><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD>
|
||
double a0, a2, a3, a4; // <20><><EFBFBD>۾<EFBFBD>ͷ<EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD>ϵ<EFBFBD><CFB5>
|
||
double sf; // sf<73><66><EFBFBD><EFBFBD><EFBFBD>ӽǣ<D3BD>sfԽ<66><D4BD><EFBFBD>ӽ<EFBFBD>Խ<EFBFBD><D4BD>
|
||
double invpol[8];
|
||
double big_rho[2002]; // Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD>tan(theta)<29><>rho<68>Ķ<EFBFBD>Ӧ<EFBFBD><D3A6>
|
||
double small_rho[2001]; // Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD>cot(theta)<29><>rho<68>Ķ<EFBFBD>Ӧ<EFBFBD><D3A6>
|
||
double Z[5000];
|
||
};
|
||
|
||
void SmallMeshCorrect(int imgWidth, int imgHeight, int meshSizeW, int meshSizeH, CameraCoeff camCoeff, double *mapx, double *mapy, unsigned short *pMeshXY)
|
||
{
|
||
double cx = camCoeff.cx;
|
||
double cy = camCoeff.cy;
|
||
double a0;
|
||
a0 = camCoeff.a0;
|
||
|
||
double *invpol = camCoeff.invpol;
|
||
double sf = camCoeff.sf;// sf<73><66><EFBFBD><EFBFBD><EFBFBD>ӽǣ<D3BD>sfԽ<66><D4BD><EFBFBD>ӽ<EFBFBD>Խ<EFBFBD><D4BD>
|
||
double Nz = a0 / sf;
|
||
double x1, y1, rho_1;
|
||
double theta_1, r, t_i;
|
||
double x2, y2;
|
||
int index = 0;
|
||
double temp;
|
||
int x_cnt = 0;
|
||
int y_cnt = 2 * meshSizeH * meshSizeW;
|
||
cv::Mat theta_rho = cv::Mat(meshSizeH, meshSizeW, CV_64FC1);
|
||
cv::Mat mapX = cv::Mat(meshSizeH, meshSizeW, CV_64FC1);
|
||
cv::Mat mapY = cv::Mat(meshSizeH, meshSizeW, CV_64FC1);
|
||
for (int j = 0; j < meshSizeH; ++j)
|
||
{
|
||
for (int i = 0; i < meshSizeW; ++i)
|
||
{
|
||
/* <20><>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD>귴<EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
||
x1 = mapx[index] - cx;
|
||
y1 = mapy[index] - cy;
|
||
rho_1 = sqrt(x1 * x1 + y1 * y1);
|
||
theta_1 = atan(Nz / rho_1);
|
||
theta_rho.at<double>(j, i) = theta_1;
|
||
|
||
if (IS_DOUBLE_ZERO(rho_1))
|
||
{
|
||
x2 = cx;
|
||
y2 = cy;
|
||
}
|
||
else
|
||
{
|
||
r = invpol[0];
|
||
t_i = 1;
|
||
for (int k = 1; k < 8; ++k)
|
||
{
|
||
t_i = t_i * theta_1;
|
||
r = r + invpol[k] * t_i;
|
||
}
|
||
x2 = (x1 / rho_1) * r + cx;
|
||
y2 = (y1 / rho_1) * r + cy;
|
||
}
|
||
mapX.at<double>(j, i) = x2;
|
||
mapY.at<double>(j, i) = y2;
|
||
// <20><><EFBFBD>Ʊ߽<C6B1>
|
||
if (x2 < 0) {
|
||
x2 = 0;
|
||
}
|
||
if (x2 > (imgWidth - 1)) {
|
||
x2 = (imgWidth - 1); // 1919
|
||
}
|
||
if (y2 < 0) {
|
||
y2 = 0;
|
||
}
|
||
if (y2 > (imgHeight - 1)) {
|
||
y2 = (imgHeight - 1); // 1079
|
||
}
|
||
|
||
// X<><58><EFBFBD>궨<EFBFBD>㻯
|
||
pMeshXY[x_cnt] = (unsigned short)x2;
|
||
temp = x2 - pMeshXY[x_cnt];
|
||
pMeshXY[x_cnt + 1] = unsigned short(temp * 128);
|
||
x_cnt = x_cnt + 2;
|
||
|
||
// Y<><59><EFBFBD>궨<EFBFBD>㻯
|
||
pMeshXY[y_cnt] = (unsigned short)y2;
|
||
temp = y2 - pMeshXY[y_cnt];
|
||
pMeshXY[y_cnt + 1] = unsigned short(temp * 128);
|
||
y_cnt = y_cnt + 2;
|
||
++index;
|
||
}
|
||
}
|
||
cv::Mat meshXY = cv::Mat(meshSizeH, meshSizeW, CV_8UC1, pMeshXY);
|
||
}
|
||
void GenMeshTable(int imgWidth, int imgHeight, int meshStepW, int meshStepH, int meshSizeW, int meshSizeH, CameraCoeff camCoeff,
|
||
unsigned short *pMeshXY, unsigned short *pMeshXI, unsigned short *pMeshYI, unsigned char *pMeshXF, unsigned char *pMeshYF)
|
||
{
|
||
double stride_w = meshStepW;
|
||
double stride_h = meshStepH;
|
||
|
||
|
||
/* <20><><EFBFBD><EFBFBD><EFBFBD>mesh<73><68><EFBFBD><EFBFBD> */
|
||
double *mapx = new double[meshSizeW * meshSizeH];
|
||
double *mapy = new double[meshSizeW * meshSizeH];
|
||
double *mapz = new double[meshSizeW * meshSizeH];
|
||
// <20><>ʼ<EFBFBD><CABC>
|
||
double start_w = 0;
|
||
double start_h = 0;
|
||
|
||
double a, b;
|
||
int index = 0;
|
||
b = start_h;
|
||
for (int j = 0; j < meshSizeH; ++j, b = b + stride_h)
|
||
{
|
||
a = start_w;
|
||
for (int i = 0; i < meshSizeW; ++i, a = a + stride_w)
|
||
{
|
||
mapx[index] = a;
|
||
mapy[index] = b;
|
||
mapz[index] = (double)1;
|
||
++index;
|
||
}
|
||
}
|
||
|
||
/* <20><><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD>meshXY */
|
||
SmallMeshCorrect(imgWidth, imgHeight, meshSizeW, meshSizeH, camCoeff, mapx, mapy, pMeshXY);
|
||
|
||
/* <20><><EFBFBD><EFBFBD>pMeshXI<58><49>pMeshXF<58><46>pMeshYI<59><49>pMeshYF */
|
||
unsigned short *pTmpXi = (unsigned short *)&pMeshXY[0];
|
||
unsigned short *pTmpXf = (unsigned short *)&pMeshXY[1];
|
||
unsigned short *pTmpYi = (unsigned short *)&pMeshXY[meshSizeW * meshSizeH * 2];
|
||
unsigned short *pTmpYf = (unsigned short *)&pMeshXY[meshSizeW * meshSizeH * 2 + 1];
|
||
|
||
for (int i = 0; i < meshSizeW * meshSizeH; i++)
|
||
{
|
||
pMeshXI[i] = *pTmpXi;
|
||
pTmpXi += 2;
|
||
pMeshXF[i] = (unsigned char) * pTmpXf;
|
||
pTmpXf += 2;
|
||
pMeshYI[i] = *pTmpYi;
|
||
pTmpYi += 2;
|
||
pMeshYF[i] = (unsigned char) * pTmpYf;
|
||
pTmpYf += 2;
|
||
}
|
||
|
||
/* <20><><EFBFBD><EFBFBD>Ϊbin<69>ļ<EFBFBD> */
|
||
/* MeshXY.bin */
|
||
FILE *fpMeshXY = fopen("MeshXY.bin", "wb");
|
||
if (fpMeshXY == NULL) {
|
||
printf("MeshXY.bin open error!!!");
|
||
goto err;
|
||
}
|
||
fwrite(&imgWidth, sizeof(unsigned short), 1, fpMeshXY);
|
||
fwrite(&imgHeight, sizeof(unsigned short), 1, fpMeshXY);
|
||
fwrite(&meshSizeW, sizeof(unsigned short), 1, fpMeshXY);
|
||
fwrite(&meshSizeH, sizeof(unsigned short), 1, fpMeshXY);
|
||
fwrite(&meshStepW, sizeof(unsigned short), 1, fpMeshXY);
|
||
fwrite(&meshStepH, sizeof(unsigned short), 1, fpMeshXY);
|
||
fwrite(pMeshXY, sizeof(unsigned short), meshSizeW * meshSizeH * 2 * 2, fpMeshXY);
|
||
if (fclose(fpMeshXY) != 0) {
|
||
printf("MeshXY.bin close error!!!");
|
||
goto err;
|
||
}
|
||
/* MeshXI.bin */
|
||
FILE *fpMeshXI = fopen("MeshXI.bin", "wb");
|
||
if (fpMeshXI == NULL) {
|
||
printf("MeshXI.bin open error!!!");
|
||
goto err;
|
||
}
|
||
fwrite(pMeshXI, sizeof(unsigned short), meshSizeW * meshSizeH, fpMeshXI);
|
||
if (fclose(fpMeshXI) != 0) {
|
||
printf("MeshXI.bin close error!!!");
|
||
goto err;
|
||
}
|
||
/* MeshXF.bin */
|
||
FILE *fpMeshXF = fopen("MeshXF.bin", "wb");
|
||
if (fpMeshXF == NULL) {
|
||
printf("MeshXF.bin open error!!!");
|
||
goto err;
|
||
}
|
||
fwrite(pMeshXF, sizeof(unsigned char), meshSizeW * meshSizeH, fpMeshXF);
|
||
if (fclose(fpMeshXF) != 0) {
|
||
printf("MeshXF.bin close error!!!");
|
||
goto err;
|
||
}
|
||
/* MeshYI.bin */
|
||
FILE *fpMeshYI = fopen("MeshYI.bin", "wb");
|
||
if (fpMeshYI == NULL) {
|
||
printf("MeshYI.bin open error!!!");
|
||
goto err;
|
||
}
|
||
fwrite(pMeshYI, sizeof(unsigned short), meshSizeW * meshSizeH, fpMeshYI);
|
||
if (fclose(fpMeshYI) != 0) {
|
||
printf("MeshYI.bin close error!!!");
|
||
goto err;
|
||
}
|
||
/* MeshYF.bin */
|
||
FILE *fpMeshYF = fopen("MeshYF.bin", "wb");
|
||
if (fpMeshYF == NULL) {
|
||
printf("MeshYF.bin open error!!!");
|
||
goto err;
|
||
}
|
||
fwrite(pMeshYF, sizeof(unsigned char), meshSizeW * meshSizeH, fpMeshYF);
|
||
if (fclose(fpMeshYF) != 0) {
|
||
printf("MeshYF.bin close error!!!");
|
||
goto err;
|
||
}
|
||
|
||
err:
|
||
delete[] mapx;
|
||
delete[] mapy;
|
||
delete[] mapz;
|
||
}
|
||
|
||
int gen_default_mesh_table(int imgWidth, int imgHeight, int mesh_density,
|
||
unsigned short* pMeshXI, unsigned short* pMeshYI, unsigned char* pMeshXF, unsigned char* pMeshYF)
|
||
{
|
||
/* <20><><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>mesh<73><68> */
|
||
CameraCoeff camCoeff;
|
||
camCoeff.cx = 951.813257;
|
||
camCoeff.cy = 700.761832;
|
||
camCoeff.a0 = -1.547500405530367e+03;
|
||
camCoeff.a2 = 3.399953844687639e-04;
|
||
camCoeff.a3 = -9.201736312511578e-08;
|
||
camCoeff.a4 = 6.793998839476364e-11;
|
||
camCoeff.sf = 1;
|
||
|
||
camCoeff.invpol[0] = 1350.42993320407;
|
||
camCoeff.invpol[1] = 414.478976267835;
|
||
camCoeff.invpol[2] = -871.475096726774;
|
||
camCoeff.invpol[3] = -1775.87581281456;
|
||
camCoeff.invpol[4] = -2556.70096229938;
|
||
camCoeff.invpol[5] = -1941.21355417283;
|
||
camCoeff.invpol[6] = -735.900048505591;
|
||
camCoeff.invpol[7] = -111.196712124121;
|
||
#if 0
|
||
int meshStepW = 16;
|
||
int meshStepH = 8;
|
||
if (imgWidth > 1920)
|
||
{
|
||
int mapStepW = 16;
|
||
int mapStepH = 8;
|
||
}
|
||
|
||
int imgWidth = 1920;
|
||
int imgHeight = 1080;
|
||
int meshSizeW = imgWidth / meshStepW + 1; // <20><>1920->121
|
||
int meshSizeH = imgHeight / meshStepH + 1; // <20><>1080->136
|
||
unsigned short *pMeshXY; // remap<61><70><EFBFBD><EFBFBD>
|
||
unsigned short *pMeshXI;
|
||
unsigned short *pMeshYI;
|
||
unsigned char *pMeshXF;
|
||
unsigned char *pMeshYF;
|
||
pMeshXY = new unsigned short[meshSizeW * meshSizeH * 2 * 2];
|
||
pMeshXI = new unsigned short[meshSizeW * meshSizeH];
|
||
pMeshXF = new unsigned char[meshSizeW * meshSizeH];
|
||
pMeshYI = new unsigned short[meshSizeW * meshSizeH];
|
||
pMeshYF = new unsigned char[meshSizeW * meshSizeH];
|
||
#else
|
||
int meshStepW = 32;
|
||
int meshStepH = 16;
|
||
if (mesh_density == 0)
|
||
{
|
||
int mapStepW = 16;
|
||
int mapStepH = 8;
|
||
}
|
||
int meshSizeW = imgWidth / meshStepW + 1; // <20><>1920->121
|
||
int meshSizeH = imgHeight / meshStepH + 1; // <20><>1080->136
|
||
#endif
|
||
|
||
GenMeshTable(imgWidth, imgHeight, meshStepW, meshStepH, meshSizeW, meshSizeH, camCoeff, pMeshXY, pMeshXI, pMeshYI, pMeshXF, pMeshYF);
|
||
return 0;
|
||
}
|
||
#endif
|