2016-10-20 12 views
1

Я пытаюсь найти способ сшивания двух изображений, которые находятся в двух камерах с рыбным окошком. Но я не знаю, как исправить исходные изображения. Я попытался сделать это с помощью класса fisheye в opencv3.0, но у него большая потеря зрения, так что у меня нет достаточной информации, чтобы сшить на следующем шаге. Так есть идея решить эту проблему? Мне повезло, если бы вы могли показать мне определенную стратегию. Большое спасибо!Как сохранить вид после неуверенности камеры

ответ

0

Использование этого link как ссылка. Я смог исправить искажение рыб изображений. Вот пример кода

#include <iostream> 
#include <sstream> 
#include <time.h> 
#include <stdio.h> 
#include <opencv2/core/core.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 
#include <opencv2/calib3d/calib3d.hpp> 
#include <opencv2/highgui/highgui.hpp> 
using namespace std; 
using namespace cv; 
#define PI 3.1415926536 
#define CHANNELS 3 
#define BORDER_TO_USE BORDER_REFLECT 
/* 
#define OUT_WIDTH 1920 
#define OUT_HEIGHT 1513 
*/ 
Point2f getInputPoint(int x, int y,int srcwidth, int srcheight,int hFov,int vFov) 
{ 
    Point2f pfish; 
    float theta,phi,r; 
    Point3f psph; 
    //float FOV = PI; 
    float FOV =(float)PI/180 * hFov; 
    float FOV2 = (float)PI/180 * vFov; 

    float width = srcwidth; 

    float height = srcheight; 
    theta = PI * (x/width - 0.5); // -pi to pi 
    phi = PI * (y/height - 0.5); // -pi/2 to pi/2 
    psph.x = cos(phi) * sin(theta); 
    psph.y = cos(phi) * cos(theta); 
    psph.z = sin(phi); 
    theta = atan2(psph.z,psph.x); 
    phi = atan2(sqrt(psph.x*psph.x+psph.z*psph.z),psph.y); 
    r = width * phi/FOV; 
    float r2 = height * phi/FOV2; 
    pfish.x = 0.5 * width + r * cos(theta); 
    pfish.y = 0.5 * height + r2 * sin(theta); 
    return pfish; 
} 

void getMatColorValue(Mat src,const int& x, const int& y, 
     int& val1, int& val2, int& val3) 
    { 
     if (x < 0 || x >= src.cols || y < 0 || y >= src.rows) 
     { 
      val1 = 0; 
      val2 = 0; 
      val3 = 0; 
     } 
     else 
     { 
      val1 = src.ptr(y)[x * CHANNELS]; 
      val2 = src.ptr(y)[x * CHANNELS + 1]; 
      val3 = src.ptr(y)[x * CHANNELS + 2]; 
     } 
    } 

Vec3b BilinearInterpolation(Point2f inP,Mat src) 
{ 
    // Bilinear interpolation 

    int tXi = floor(inP.x); 
    int tYi = floor(inP.y); 

    float dX = inP.x - tXi; // differential 
    float dY = inP.y - tYi; 

    int rgbValues[4][3]; 

    int val1,val2,val3; 
    getMatColorValue(src, tXi, tYi,  rgbValues[0][0], rgbValues[0][1], rgbValues[0][2]); 
    getMatColorValue(src, tXi+1, tYi, rgbValues[1][0], rgbValues[1][1], rgbValues[1][2]); 
    getMatColorValue(src, tXi, tYi+1, rgbValues[2][0], rgbValues[2][1], rgbValues[2][2]); 
    getMatColorValue(src, tXi+1, tYi+1, rgbValues[3][0], rgbValues[3][1], rgbValues[3][2]); 

    float x; 

    // Update val1 
    x = rgbValues[0][0] * (1-dX) * (1-dY) + 
     rgbValues[1][0] * (dX) * (1-dY) + 
     rgbValues[2][0] * (1-dX) * (dY) + 
     rgbValues[3][0] * (dX) * (dY); 
    if (x < 0) 
     val1 = 0; 
    else if (x > (unsigned char)(-1)) 
     val1 = (unsigned char)(-1); 
    else 
     val1 = x; 

    // Update val2 
    x = rgbValues[0][1] * (1-dX) * (1-dY) + 
     rgbValues[1][1] * (dX) * (1-dY) + 
     rgbValues[2][1] * (1-dX) * (dY) + 
     rgbValues[3][1] * (dX) * (dY); 
    if (x < 0) 
     val2 = 0; 
    else if (x > (unsigned char)(-1)) 
     val2 = (unsigned char)(-1); 
    else 
     val2 = x; 

    // Update val3 
    x = rgbValues[0][2] * (1-dX) * (1-dY) + 
     rgbValues[1][2] * (dX) * (1-dY) + 
     rgbValues[2][2] * (1-dX) * (dY) + 
     rgbValues[3][2] * (dX) * (dY); 
    if (x < 0) 
     val3 = 0; 
    else if (x > (unsigned char)(-1)) 
     val3 = (unsigned char)(-1); 
    else 
     val3 = x; 
    Vec3b color; 
    color.val[0] = val1; 
    color.val[1] = val2; 
    color.val[2] = val3; 
    return color; 
} 
/*Vec3b getColorSubpix(const cv::Mat& img, cv::Point2f pt) 
{ 

    int x = (int)pt.x; 
    int y = (int)pt.y; 

    int x0 = cv::borderInterpolate(x, img.cols, BORDER_TO_USE); 
    int x1 = cv::borderInterpolate(x + 1, img.cols, BORDER_TO_USE); 
    int y0 = cv::borderInterpolate(y, img.rows, BORDER_TO_USE); 
    int y1 = cv::borderInterpolate(y + 1, img.rows, BORDER_TO_USE); 

    float a = pt.x - (float)x; 
    float c = pt.y - (float)y; 

    uchar b = (uchar)cvRound((img.at<cv::Vec3b>(y0, x0)[0] * (1.f - a) + img.at<cv::Vec3b>(y0, x1)[0] * a) * (1.f - c) 
     + (img.at<cv::Vec3b>(y1, x0)[0] * (1.f - a) + img.at<cv::Vec3b>(y1, x1)[0] * a) * c); 
    uchar g = (uchar)cvRound((img.at<cv::Vec3b>(y0, x0)[1] * (1.f - a) + img.at<cv::Vec3b>(y0, x1)[1] * a) * (1.f - c) 
     + (img.at<cv::Vec3b>(y1, x0)[1] * (1.f - a) + img.at<cv::Vec3b>(y1, x1)[1] * a) * c); 
    uchar r = (uchar)cvRound((img.at<cv::Vec3b>(y0, x0)[2] * (1.f - a) + img.at<cv::Vec3b>(y0, x1)[2] * a) * (1.f - c) 
     + (img.at<cv::Vec3b>(y1, x0)[2] * (1.f - a) + img.at<cv::Vec3b>(y1, x1)[2] * a) * c); 

    return cv::Vec3b(b, g, r); 
}*/ 
void CropBlackArea(Mat image,int &top,int &bottom) 
{ 
    Mat slider; 
    Mat gray; 
    cvtColor(image,gray,CV_BGR2GRAY); 
    int i=0; 
    for(i=0; i<image.rows-1;i++) 
    { 
     slider = gray(Rect(0,i,gray.cols,1)); 
     if(countNonZero(slider) == 0) 
      continue; 
     else 
      break; 
    } 
    top = i; 
    i=0; 
    for(i=image.rows-1; i>=0;i--) 
    { 

     slider = gray(Rect(0,i,gray.cols,1)); 
     if(countNonZero(slider) == 0) 
      continue; 
     else 
      break; 

    } 
    bottom = i; 
} 
int main(int argc, char **argv) 
{ 
    /*Arguments should be 1-input_image_path 2-Output_image_path 3-Horizontal fov(Field of view) of the lense 4-Vertical fov of the lense*/ 
    if(argc< 5) 
     return 0; 
    FileStorage fsx("FishEyeConversionXmap.yml", FileStorage::WRITE); 
    FileStorage fsy("FishEyeConversionYmap.yml", FileStorage::WRITE); 
    Mat orignalImage = imread(argv[1]); 
    int hFov = atoi(argv[3]); 
    int vFov = atoi(argv[4]); 
    //resize(orignalImage,orignalImage,Size(720,1280)); 
    if(orignalImage.empty()) 
    { 
     cout<<"Empty image\n"; 
     return 0; 
    } 
    Mat outImage(orignalImage.rows,orignalImage.cols,CV_8UC3); 
    Mat xMap(orignalImage.rows,orignalImage.cols,CV_32FC1); 
    Mat yMap(orignalImage.rows,orignalImage.cols,CV_32FC1); 
     //getInputPoint(0,5,10,10); 
    namedWindow("result",CV_WINDOW_NORMAL); 
    for(int i=0; i<outImage.cols; i++) 
    { 
     for(int j=0; j<outImage.rows; j++) 
     { 
      Point2f inP = getInputPoint(i,j,orignalImage.cols,orignalImage.rows,hFov,vFov); 

      xMap.at<float>(j,i) = inP.x; 
      yMap.at<float>(j,i) = inP.y; 
      Point inP2((int)inP.x,(int)inP.y); 
      if(inP2.x >= orignalImage.cols || inP2.y >= orignalImage.rows) 
       continue; 
      if(inP2.x < 0 || inP2.y < 0) 
       continue; 

      //Vec3b color = getColorSubpix(orignalImage,inP); 
      //Vec3b color = orignalImage.at<cv::Vec3b>(inP2.y,inP2.x); 
      Vec3b color = BilinearInterpolation(inP,orignalImage); 
      outImage.at<Vec3b>(Point(i,j)) = color; 
     } 
    } 
    int top,bottom; 
    CropBlackArea(outImage,top,bottom); 
    cout<<"Croping "<<top<<","<<bottom<<"\n"; 
    cout<<outImage.size()<<endl; 
    Rect r(0,top,outImage.cols,(bottom-top)); 
    cout<<r<<endl; 
    outImage = outImage(r); 
    xMap = xMap(r); 
    yMap = yMap(r); 
    /* resize(outImage,outImage,Size(OUT_WIDTH,OUT_HEIGHT)); 
    resize(outImage,outImage,Size(OUT_WIDTH,OUT_HEIGHT)); 
    resize(xMap,xMap,Size(OUT_WIDTH,OUT_HEIGHT)); 
    resize(yMap,yMap,Size(OUT_WIDTH,OUT_HEIGHT));*/ 

    fsx << "xMap" << xMap; 
    fsy << "yMap" << yMap; 
    fsx.release(); 
    fsy.release(); 
    imshow("result",outImage); 
    imwrite(argv[2],outImage); 
    waitKey(0); 
} 
+0

Спасибо за ваш ответ! Я отмечаю, что этот метод не основан на внутренних параметрах камеры рыбьего глаза, восстанавливает изображение неисторического изображения в 3D-пространстве, но исправляет изображение только в 2D. Это может привести к уродливому представлению, которое не такое же, как у человека. Итак, есть ли способ исказить изображение в перспективе и сохранить FOV камеры? –