intel / libxcam

libXCam is a project for extended camera(not limited in camera) features and focus on image quality improvement and video analysis. There are lots features supported in image pre-processing, image post-processing and smart analysis. This library makes GPU/CPU/ISP working together to improve image quality. OpenCL is used to improve performance in different platforms.
Other
589 stars 229 forks source link

Is there any way to correct the fisheye of a single image? #815

Closed Adarine99 closed 1 year ago

Adarine99 commented 1 year ago

Hi Everyone, I need to correct the fisheye of a single image,how to get the result in this project? Thanks

brmarkus commented 1 year ago

Do you find an example (e.g. ffmpeg or gstreamer) under the "https://github.com/intel/libxcam/wiki/Tests" Test section, with de-warping?

zongwave commented 1 year ago

You can use unit tests (GLES and CPU version) to do fisheye correction. you probably need to create a map table according to your camera.

https://github.com/intel/libxcam/wiki/Tests#4-test-gles-handler 2) Remap test $ test-gles-handler --type remap --input0 input0.nv12 --output output.nv12 --in-w 1280 --in-h 800 --out-w 1280 --out-h 800 --save true --loop 1000

https://github.com/intel/libxcam/wiki/Tests#6-test-soft-image 1) Remap test $ test-soft-image --type remap --input0 input0.nv12 --output output.nv12 --in-w 1280 --in-h 800 --out-w 1280 --out-h 800 --save true --loop 1000

Adarine99 commented 1 year ago

Hi, In "test-gles-handler " remap means to flip the image,so I'm trying to do some change as below:

static void calc_undistortion_table (uint32_t width, uint32_t height, struct ocam_model *ocam_model,PointFloat2 *&map_table,float sf)
{
    int i,j;
    float Nxc = height/2.0;
    float Nyc = width/2.0;
    float Nz  = -width/sf;
    double M[3];
    double m[2];
    for (i=0; i<height; i++)
    {
        PointFloat2 *lineT = &map_table[i * width];
        for (j=0; j<width; j++)
        {   
            M[0] = (i - Nxc);
            M[1] = (j - Nyc);
            M[2] = Nz;
            world2cam(m, M, ocam_model);
            lineT[j].x  = (float) m[1];
            lineT[j].y  = (float) m[0];
        }
    }
}
struct ocam_model
{
        double pol[MAX_POL_LENGTH];    // the polynomial coefficients: pol[0] + x"pol[1] + x^2*pol[2] + ... + x^(N-1)*pol[N-1]
        int length_pol;                // length of polynomial
        double invpol[MAX_POL_LENGTH]; // the coefficients of the inverse polynomial
        int length_invpol;             // length of inverse polynomial
        double xc;         // row coordinate of the center
        double yc;         // column coordinate of the center
        double c;          // affine parameter
        double d;          // affine parameter
        double e;          // affine parameter
        int width;         // image width
        int height;        // image height
};
void world2cam(double point2D[2], double point3D[3], struct ocam_model *myocam_model)
{
   double *invpol     = myocam_model->invpol; 
   double xc          = (myocam_model->xc);
   double yc          = (myocam_model->yc); 
   double c           = (myocam_model->c);
   double d           = (myocam_model->d);
   double e           = (myocam_model->e);
   int width          = (myocam_model->width);
   int height         = (myocam_model->height);
   int length_invpol  = (myocam_model->length_invpol);
   double norm        = sqrt(point3D[0]*point3D[0] + point3D[1]*point3D[1]);
   double theta       = atan(point3D[2]/norm);
   double t, t_i;
   double rho, x, y;
   double invnorm;
   int i;
   if (norm != 0) 
   {
        invnorm = 1/norm;
        t  = theta;
        rho = invpol[0];
        t_i = 1; 
        for (i = 1; i < length_invpol; i++)
        {
            t_i *= t;
            rho += t_i*invpol[i];
        }
        x = point3D[0]*invnorm*rho;
        y = point3D[1]*invnorm*rho;      
        point2D[0] = x*c + y*d + xc;
        point2D[1] = x*e + y   + yc;
   }
    else
    {
        point2D[0] = xc;
        point2D[1] = yc;
    }
}

use "calc_undistortion_table" to replace "calc_hor_flip_table",but got wrong result. I may have created the wrong map table,some advice? Thanks

Adarine99 commented 1 year ago

Hi Everyone: Some advice? grateful!

zongwave commented 1 year ago

Please read this page how to use OCamCalib camera calibration toolbox https://sites.google.com/site/scarabotix/ocamcalib-omnidirectional-camera-calibration-toolbox-for-matlab

Adarine99 commented 1 year ago

Hi, Sorry to bother you,but want to know whether there is a difference between the function "remap" in opencv and "GLGeoMapHandler::remap" in this project.Thank you so much!

zongwave commented 1 year ago

Hi, Sorry to bother you,but want to know whether there is a difference between the function "remap" in opencv and "GLGeoMapHandler::remap" in this project.Thank you so much!

function "GLGeoMapHandler::remap" apply geometrical transformation to input image by GLES shader program. the map table is set by function GLGeoMapHandler::set_lut_buf https://github.com/intel/libxcam/blob/master/modules/gles/gl_geomap_handler.cpp#L760

opencv remap function is similar, here's the definition https://docs.opencv.org/3.4/da/d54/group__imgproc__transform.html#gab75ef31ce5cdfb5c44b6da5f3b908ea4