2011-05-03 9 views
6

Estoy intentando usar OpenCV para tomar pares de imágenes estéreo ... es decir, una imagen izquierda y otra derecha del mismo tema ... y luego corregirlos para rotación y traducción sin conocer ninguna de las propiedades de la cámara. Una vez que se corrijan las imágenes, debería ser capaz de mostrarlas al usuario.Corrección de par de imágenes estéreo OpenCV ... mostrando los resultados

Hasta ahora he combinado dos programas de demostración del directorio de muestras de OpenCV, mal por el momento ... Limpiaré el código y lo arreglaré más cómodamente cuando lo haga funcionar ... y parece que está funcionando Sin embargo, cuando intento mostrar los resultados, el programa falla con un error de depuración. En la ventana de comandos dice "Error de OpenCV: la aserción falló (scn == 1 & & (dcn == 3 || dcn == 4)) en la función desconocida en el archivo ........ \ opencv \ modules \ imgproc \ src \ color.cpp, línea 2453 "

Comentar varias partes del código para mostrar los resultados solo da como resultado diferentes errores de OpenCV. Aquí está mi código. Si alguien puede ayudar, te amaré por siempre.

#include "stdafx.h" 
#include "opencv2/highgui/highgui.hpp" 
#include "opencv2/calib3d/calib3d.hpp" 
#include "opencv2/imgproc/imgproc.hpp" 
#include "opencv2/features2d/features2d.hpp" 

#include <iostream> 

using namespace cv; 
using namespace std; 

void help(char** argv) 
{ 
    cout << "\nThis program demonstrates keypoint finding and matching between 2 images using features2d framework.\n" 
    << "Example of usage:\n" 
    << argv[0] << " [detectorType] [descriptorType] [image1] [image2] [ransacReprojThreshold]\n" 
    << "\n" 
    << "Matches are filtered using homography matrix if ransacReprojThreshold>=0\n" 
    << "Example:\n" 
    << "./descriptor_extractor_matcher SURF SURF cola1.jpg cola2.jpg 3\n" 
    << "\n" 
    << "Possible detectorType values: see in documentation on createFeatureDetector().\n" 
    << "Possible descriptorType values: see in documentation on createDescriptorExtractor().\n" << endl; 
} 

const string winName = "rectified"; 

void crossCheckMatching(Ptr<DescriptorMatcher>& descriptorMatcher, 
         const Mat& descriptors1, const Mat& descriptors2, 
         vector<DMatch>& filteredMatches12, int knn=1) 
{ 
    filteredMatches12.clear(); 
    vector<vector<DMatch> > matches12, matches21; 
    descriptorMatcher->knnMatch(descriptors1, descriptors2, matches12, knn); 
    descriptorMatcher->knnMatch(descriptors2, descriptors1, matches21, knn); 
    for(size_t m = 0; m < matches12.size(); m++) 
    { 
     bool findCrossCheck = false; 
     for(size_t fk = 0; fk < matches12[m].size(); fk++) 
     { 
      DMatch forward = matches12[m][fk]; 

      for(size_t bk = 0; bk < matches21[forward.trainIdx].size(); bk++) 
      { 
       DMatch backward = matches21[forward.trainIdx][bk]; 
       if(backward.trainIdx == forward.queryIdx) 
       { 
        filteredMatches12.push_back(forward); 
        findCrossCheck = true; 
        break; 
       } 
      } 
      if(findCrossCheck) break; 
     } 
    } 
} 

void doIteration(const Mat& leftImg, Mat& rightImg, 
        vector<KeyPoint>& keypoints1, const Mat& descriptors1, 
        Ptr<FeatureDetector>& detector, Ptr<DescriptorExtractor>& descriptorExtractor, 
        Ptr<DescriptorMatcher>& descriptorMatcher, 
        double ransacReprojThreshold) 
{ 
    assert(!leftImg.empty()); 
    Mat H12; 
    assert(!rightImg.empty()/* && rightImg.cols==leftImg.cols && rightImg.rows==leftImg.rows*/); 

    cout << endl << "< Extracting keypoints from second image..." << endl; 
    vector<KeyPoint> keypoints2; 
    detector->detect(rightImg, keypoints2); 
    cout << keypoints2.size() << " points" << endl << ">" << endl; 

    cout << "< Computing descriptors for keypoints from second image..." << endl; 
    Mat descriptors2; 
    descriptorExtractor->compute(rightImg, keypoints2, descriptors2); 
    cout << ">" << endl; 

    cout << "< Matching descriptors..." << endl; 
    vector<DMatch> filteredMatches; 
    crossCheckMatching(descriptorMatcher, descriptors1, descriptors2, filteredMatches, 1); 
    cout << ">" << endl; 

    vector<int> queryIdxs(filteredMatches.size()), trainIdxs(filteredMatches.size()); 
    for(size_t i = 0; i < filteredMatches.size(); i++) 
    { 
     queryIdxs[i] = filteredMatches[i].queryIdx; 
     trainIdxs[i] = filteredMatches[i].trainIdx; 
    } 

    cout << "< Computing homography (RANSAC)..." << endl; 
    vector<Point2f> points1; KeyPoint::convert(keypoints1, points1, queryIdxs); 
    vector<Point2f> points2; KeyPoint::convert(keypoints2, points2, trainIdxs); 
    H12 = findHomography(Mat(points1), Mat(points2), CV_RANSAC, ransacReprojThreshold); 
    cout << ">" << endl; 

    //Mat drawImg; 
    if(!H12.empty()) // filter outliers 
    { 
     vector<char> matchesMask(filteredMatches.size(), 0); 
     vector<Point2f> points1; KeyPoint::convert(keypoints1, points1, queryIdxs); 
     vector<Point2f> points2; KeyPoint::convert(keypoints2, points2, trainIdxs); 
     Mat points1t; perspectiveTransform(Mat(points1), points1t, H12); 
     for(size_t i1 = 0; i1 < points1.size(); i1++) 
     { 
      if(norm(points2[i1] - points1t.at<Point2f>((int)i1,0)) < 4) // inlier 
       matchesMask[i1] = 1; 
     } 
     /* draw inliers 
     drawMatches(leftImg, keypoints1, rightImg, keypoints2, filteredMatches, drawImg, CV_RGB(0, 255, 0), CV_RGB(0, 0, 255), matchesMask, 2); */ 
    } 

    Size imageSize = leftImg.size(); 
    Mat F = findFundamentalMat(Mat(points1), Mat(points2), FM_8POINT, 0, 0); 
    Mat H1, H2; 
    stereoRectifyUncalibrated(Mat(points1), Mat(points2), F, imageSize, H1, H2, 3); 

    Mat cameraMatrix[2], distCoeffs[2], R1, R2, P1, P2, rmap[2][2]; 
    cameraMatrix[0] = Mat::eye(3, 3, CV_64F); 
    cameraMatrix[1] = Mat::eye(3, 3, CV_64F); 
    R1 = cameraMatrix[0].inv()*H1*cameraMatrix[0]; 
    R2 = cameraMatrix[1].inv()*H2*cameraMatrix[1]; 
    P1 = cameraMatrix[0]; 
    P2 = cameraMatrix[1]; 

    initUndistortRectifyMap(cameraMatrix[0], distCoeffs[0], R1, P1, imageSize, CV_16SC2, rmap[0][0], rmap[0][1]); 
    initUndistortRectifyMap(cameraMatrix[1], distCoeffs[1], R2, P2, imageSize, CV_16SC2, rmap[1][0], rmap[1][1]); 

    Mat canvas, img; 
    double sf; 
    int i, j, w, h; 

    sf = 600./MAX(imageSize.width, imageSize.height); 
    w = cvRound(imageSize.width*sf); 
    h = cvRound(imageSize.height*sf); 
    canvas.create(h, w*2, CV_8UC3); 

    for (i = 0; i < 2; i++) 
    { 
     if (i == 0) 
      img = leftImg; 
     else 
      img = rightImg; 

     Mat rimg, cimg; 
     remap(img, rimg, rmap[i][0], rmap[i][1], CV_INTER_LINEAR); 
     cvtColor(rimg, cimg, CV_GRAY2BGR); 
     Mat canvasPart = canvas(Rect(w*i, 0, w, h)); 
     resize(cimg, canvasPart, canvasPart.size(), 0, 0, CV_INTER_AREA); 
    } 

     for(j = 0; j < canvas.rows; j += 16) 
     { 
      line(canvas, Point(0, j), Point(canvas.cols, j), Scalar(0, 255, 0), 1, 8); 
     } 

     imshow(winName, canvas); 
} 


int main(int argc, char** argv) 
{ 
    if(argc != 6) 
    { 
     help(argv); 
     return -1; 
    } 
    double ransacReprojThreshold = atof(argv[5]); 


    cout << "< Creating detector, descriptor extractor and descriptor matcher ..." << endl; 
    Ptr<FeatureDetector> detector = FeatureDetector::create(argv[1]); 
    Ptr<DescriptorExtractor> descriptorExtractor = DescriptorExtractor::create(argv[2]); 
    Ptr<DescriptorMatcher> descriptorMatcher = DescriptorMatcher::create("FlannBased"); 
    cout << ">" << endl; 
    if(detector.empty() || descriptorExtractor.empty() || descriptorMatcher.empty() ) 
    { 
     cout << "Can not create detector or descriptor extractor or descriptor matcher of given types" << endl; 
     return -1; 
    } 

    cout << "< Reading the images..." << endl; 
    Mat leftImg = imread(argv[3]); 
    Mat rightImg = imread(argv[4]); 
    cout << ">" << endl; 
    if(leftImg.empty() || (rightImg.empty())) 
    { 
     cout << "Can not read images" << endl; 
     return -1; 
    } 

    cout << endl << "< Extracting keypoints from first image..." << endl; 
    vector<KeyPoint> keypoints1; 
    detector->detect(leftImg, keypoints1); 
    cout << keypoints1.size() << " points" << endl << ">" << endl; 

    cout << "< Computing descriptors for keypoints from first image..." << endl; 
    Mat descriptors1; 
    descriptorExtractor->compute(leftImg, keypoints1, descriptors1); 
    cout << ">" << endl; 

    namedWindow(winName, CV_WINDOW_NORMAL); 
    doIteration(leftImg, rightImg, keypoints1, descriptors1, 
       detector, descriptorExtractor, descriptorMatcher, 
       ransacReprojThreshold); 
    for(;;) 
    { 
     char c = (char)waitKey(0); 
     if(c == '\x1b') // esc 
     { 
      cout << "Exiting ..." << endl; 
      return 0; 
     } 
    } 
    waitKey(0); 
    return 0; 
} 

El objetivo principal debe ser probablemente alrededor del método doIteration, pero he puesto el resto de ella allí para que pueda ver exactamente lo que está pasando.

Respuesta

0

Quizás sea demasiado tarde;) No he revisado su código. Pero me parece que olvidó convertir la imagen en estilo gris.

Cuestiones relacionadas