#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                        //¸ù¾ÝÐèÒªµ÷ÕûÕâ¸öÖµ 
 | 
#define IS_DOUBLE_ZERO(d) ((d < MIN_VALUE)&&((-d)<MIN_VALUE)) 
 | 
/* ÓãÑÛ²ÎÊý */ 
 | 
struct CameraCoeff 
 | 
{ 
 | 
    double cx, cy;                  // Ïà»ú¾µÍ·µÄ¹âÐÄ 
 | 
    double a0, a2, a3, a4;          // ÓãÑÛ¾µÍ·µÄ»û±äϵÊý 
 | 
    double sf;                      // sf¿ØÖÆÊӽǣ¬sfÔ½´óÊÓ½ÇÔ½´ó 
 | 
    double invpol[8]; 
 | 
    double big_rho[2002];           // Ô¤ÏÈÉú³ÉµÄtan(theta)ÓërhoµÄ¶ÔÓ¦±í 
 | 
    double small_rho[2001];         // Ô¤ÏÈÉú³ÉµÄcot(theta)ÓërhoµÄ¶ÔÓ¦±í 
 | 
    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¿ØÖÆÊӽǣ¬sfÔ½´óÊÓ½ÇÔ½´ó 
 | 
    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) 
 | 
        { 
 | 
            /* ´ÓУÕý×ø±ê·´ÍƵ½»û±ä×ø±ê */ 
 | 
            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; 
 | 
            // ÏÞÖÆ±ß½ç 
 | 
            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×ø±ê¶¨µã»¯ 
 | 
            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×ø±ê¶¨µã»¯ 
 | 
            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; 
 | 
  
 | 
  
 | 
    /* ¸¡µãµÄmeshÍø¸ñ */ 
 | 
    double *mapx = new double[meshSizeW * meshSizeH]; 
 | 
    double *mapy = new double[meshSizeW * meshSizeH]; 
 | 
    double *mapz = new double[meshSizeW * meshSizeH]; 
 | 
    // Æðʼµã 
 | 
    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; 
 | 
        } 
 | 
    } 
 | 
  
 | 
    /* Éú³ÉУÕýºóµÄmeshXY */ 
 | 
    SmallMeshCorrect(imgWidth, imgHeight, meshSizeW, meshSizeH, camCoeff, mapx, mapy, pMeshXY); 
 | 
  
 | 
    /* Éú³ÉpMeshXI£¬pMeshXF£¬pMeshYI£¬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; 
 | 
    } 
 | 
  
 | 
    /* ±£´æÎªbinÎļþ */ 
 | 
    /* 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) 
 | 
{ 
 | 
    /* ¸ù¾Ý»û±ä²ÎÊýÉú³Émesh±í */ 
 | 
    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;       // Èç1920->121 
 | 
    int meshSizeH = imgHeight / meshStepH + 1;      // Èç1080->136 
 | 
    unsigned short  *pMeshXY;               // remapÊý¾Ý 
 | 
    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;       // Èç1920->121 
 | 
    int meshSizeH = imgHeight / meshStepH + 1;      // Èç1080->136 
 | 
#endif 
 | 
  
 | 
    GenMeshTable(imgWidth, imgHeight, meshStepW, meshStepH, meshSizeW, meshSizeH, camCoeff, pMeshXY, pMeshXI, pMeshYI, pMeshXF, pMeshYF); 
 | 
    return 0; 
 | 
} 
 | 
#endif 
 |