Full width home advertisement

OpenCV

HTML

Post Page Advertisement [Top]

In this post I am demonstrating how 360 degree image can convert panoramic image using OpenCV C++.
fisheye image into  panorama image


Using the equation of circle we can find co-ordinate on circumference of a circle for given radius and arcLength;

    Px = centX + radius * cos( 2𝜋*(x/ arcLength));
    Py = centY + radius * sin( 2𝜋*(x/ arcLength));

     where n = 0,1,2........,arcLength

    Using above equation we can find each points inside the circle and corresponding points in panoramic output. The algorithm simply can explain like, first we took the outer perimeter of the input 360 degree image, then starch and straiten the image and then place in output image top row. Then we will come inner circle by decremented radius by 1 and take all points in the circle do the same stitching and straiten and the place on second row of output image. This will continue till the centre points and finally we will get the output unwrapped image. Here the width of the output image will be the arc-length and height will be the radius of input 360 image. The following code will give more idea about the algorithm.

Load Input image


    Mat  src = imread("img/pan9.jpg", IMREAD_COLOR);

Calculate Output Image Size


    double radius = src.rows/2; // radius will be the half height of input image
    double arcLength = 2.0*CV_PI*radius; // arcLength will be the width of the output image
    Mat dst(radius,arcLength,CV_8UC3,Scalar::all(0));
    cv::Point cent(src.cols/2, src.rows/2);

The actual Unwrap Code

    Here we will iterate through each points in output image and find corresponding points in input image, take that points and place it on output image. If the output image seems inverted just reverse the order destination points. See the commented code below.

   for(double y=0; y < radius; y++){
     for(double x=0; x < arcLength; x++){
       int xT = (int)round((double)cent.x + (y) * cos( 2*CV_PI*(x/ arcLength)));
       int yT = (int)round((double)cent.y + (y) * sin( 2*CV_PI*(x/ arcLength)));
       dst.at < Vec3b >(Point(x,radius-y-1)) = src.at < Vec3b > (Point(xT,yT));
       //dst.at < Vec3b >(Point(x,y)) = src.at < Vec3b >(Point(xT,yT)); //if image is inverted use this  
     }
   }

Display and Save the result


    imwrite("wunwrapped.jpg",dst);
    imshow("src",src);
    imshow("dst",dst);
    waitKey();

Result

360 degree image
Input 1

panorama image
Output 1


360 degree image
Input 2

panorama image
Output 2

Full Code


    //Load image and create output image
    Mat  src = imread("img/pan9.jpg", IMREAD_COLOR);
    double radius = src.rows/2;
    double arcLength = 2.0*CV_PI*radius;
    Mat dst(radius,arcLength,CV_8UC3,Scalar::all(0));
    cv::Point cent(src.cols/2, src.rows/2);

    //Unwrap image
    for(double y=0; y < radius; y++){
       for(double x=0; x < arcLength; x++){
          int xT = (int)round((double)cent.x + (y) * cos( 2*CV_PI*(x/ arcLength)));
          int yT = (int)round((double)cent.y + (y) * sin( 2*CV_PI*(x/ arcLength)));
          dst.at < Vec3b > (Point(x,radius-y-1)) = src.at < Vec3b > (Point(xT,yT));
          //dst.at < Vec3b >(Point(x,y)) = src.at < Vec3b >(Point(xT,yT)); //if image is inverted use this  
     }
    }

    //Display and save result. 
    imwrite("wunwrapped.jpg",dst);
    imshow("src",src);
    imshow("dst",dst);
    waitKey();

No comments:

Post a Comment

Bottom Ad [Post Page]

| Designed by Colorlib