2015-07-23 3 views
1

J'ai deux caméras qui regardent au-dessus d'un objet carré, et je voudrais prendre les deux images et les combiner pour obtenir une image qui est (approximativement) représentative de la zone globale.Comment obtenir plus d'informations sur cv :: Stitcher failing

Les vues de mes deux caméras ressemblent à ceci:

Two camera images.

Le bord gauche de l'image gauche doit point avec le bord droit de l'image de droite, avec la ligne pointillée noire étant le point où ils se chevauchent.

Ma première tentative est de assembler les images en utilisant la technique dans ce tutoriel:

http://ramsrigoutham.com/2012/11/22/panorama-image-stitching-in-opencv/

#include <stdio.h> 
#include <iostream> 

#include "opencv2/core/core.hpp" 
#include "opencv2/features2d/features2d.hpp" 
#include "opencv2/highgui/highgui.hpp" 
#include "opencv2/nonfree/nonfree.hpp" 
#include "opencv2/calib3d/calib3d.hpp" 
#include "opencv2/imgproc/imgproc.hpp" 

using namespace cv; 

void readme(); 

/** @function main */ 
int main(int argc, char** argv) 
{ 
if(argc != 3) 
{ readme(); return -1; } 

// Load the images 
Mat image1= imread(argv[2]); 
Mat image2= imread(argv[1]); 
Mat gray_image1; 
Mat gray_image2; 
// Convert to Grayscale 
cvtColor(image1, gray_image1, CV_RGB2GRAY); 
cvtColor(image2, gray_image2, CV_RGB2GRAY); 

imshow("first image",image2); 
imshow("second image",image1); 

if(!gray_image1.data || !gray_image2.data) 
{ std::cout<< " --(!) Error reading images " << std::endl; return -1; } 

//-- Step 1: Detect the keypoints using SURF Detector 
int minHessian = 400; 

SurfFeatureDetector detector(minHessian); 

std::vector<KeyPoint> keypoints_object, keypoints_scene; 

detector.detect(gray_image1, keypoints_object); 
detector.detect(gray_image2, keypoints_scene); 

//-- Step 2: Calculate descriptors (feature vectors) 
SurfDescriptorExtractor extractor; 

Mat descriptors_object, descriptors_scene; 

extractor.compute(gray_image1, keypoints_object, descriptors_object); 
extractor.compute(gray_image2, keypoints_scene, descriptors_scene); 

//-- Step 3: Matching descriptor vectors using FLANN matcher 
FlannBasedMatcher matcher; 
std::vector<DMatch> matches; 
matcher.match(descriptors_object, descriptors_scene, matches); 

double max_dist = 0; double min_dist = 100; 

//-- Quick calculation of max and min distances between keypoints 
for(int i = 0; i < descriptors_object.rows; i++) 
{ double dist = matches[i].distance; 
if(dist < min_dist) min_dist = dist; 
if(dist > max_dist) max_dist = dist; 
} 

printf("-- Max dist : %f \n", max_dist); 
printf("-- Min dist : %f \n", min_dist); 

//-- Use only "good" matches (i.e. whose distance is less than 3*min_dist) 
std::vector<DMatch> good_matches; 

for(int i = 0; i < descriptors_object.rows; i++) 
{ if(matches[i].distance < 3*min_dist) 
{ good_matches.push_back(matches[i]); } 
} 
std::vector<Point2f> obj; 
std::vector<Point2f> scene; 

for(int i = 0; i < good_matches.size(); i++) 
{ 
//-- Get the keypoints from the good matches 
obj.push_back(keypoints_object[ good_matches[i].queryIdx ].pt); 
scene.push_back(keypoints_scene[ good_matches[i].trainIdx ].pt); 
} 

// Find the Homography Matrix 
Mat H = findHomography(obj, scene, CV_RANSAC); 
// Use the Homography Matrix to warp the images 
cv::Mat result; 
warpPerspective(image1,result,H,cv::Size(image1.cols+image2.cols,image1.rows)); 
cv::Mat half(result,cv::Rect(0,0,image2.cols,image2.rows)); 
image2.copyTo(half); 
imshow("Result", result); 

waitKey(0); 
return 0; 
} 

/** @function readme */ 
void readme() 
{ std::cout << " Usage: Panorama <img1> <img2>" << std::endl; } 

Malheureusement, cela ne fonctionne pas (toujours) avec l'erreur:

Debug Assertion Failed! Program: ....\VC\include\xmemory0 Line 106 Expression "(_Ptr_user & (_BIG_ALLOCATION_ALIGNMENT -1)) == 0" && 0

La pile d'appel indique que cela se produit pendant l'appel à std::_Deallocate<cv::KeyPoint> - p résumable lorsque les vecteurs points-clés sont libérés.

Inutile de dire que l'assemblage de l'image échoue.

J'ai essayé d'utiliser la classe cv::Stitcher, mais j'ai la même erreur.

Comment puis-je essayer d'assembler des images et obtenir des informations sur comment ou pourquoi cela échoue?

+0

Rien à voir avec la question directe, mais vous devriez noter que votre tutoriel suppose * un emplacement de l'appareil photo prendre deux photos *. Vous pouvez ne pas aimer les résultats de la tentative de couture des photos prises à partir de différents endroits. –

+0

Oh! Je n'avais pas réalisé que c'était une exigence. Existe-t-il un moyen d'identifier les caractéristiques d'une paire d'images (même manuellement), puis obtenir un point approximatif des deux images? –

+0

J'ai essayé ce code avec ces images de test, et j'ai la même erreur dans le destructeur pour 'cv :: DMatch' - https://imgur.com/a/u34NJ –

Répondre

0

Essayer d'utiliser cv::Stitcher de telle manière comme en dessous, il est le plus simple moyen de déformer les images les unes aux autres:

#include <iostream> 

#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/stitching/stitcher.hpp> 

int main(int argc, char** argv) 
{ 
    cv::Mat img1 = cv::imread("image1.jpg"); 
    cv::Mat img2 = cv::imread("image2.jpg"); 

    if (img1.empty() || img2.empty()) 
    { 
     return -1; 
    } 

    std::vector<cv::Mat> imgs; 
    imgs.push_back(img1); 
    imgs.push_back(img2); 
    // push more images here ... 

    cv::Mat panoramic; 
    cv::Stitcher stitcher = cv::Stitcher::createDefault(true); 
    stitcher.stitch(imgs, panoramic); 

    cv::imshow("Result", panoramic); 
    cv::waitKey(0); 

    return 0; 
} 
+0

Malheureusement, cela me donne la même erreur - il se bloque en essayant de libérer les vecteurs à l'intérieur de la classe Stitcher :( –

+0

Quelle version d'OpenCV utilisez-vous pour tester? Vous ne mélangez pas les DLLs de débogage/libération? – Kornel

+0

J'utilise OpenCv 2.4.11 avec Visual Studio 2015. Je Je ne mélange pas .dlls, autant que je sache - je commence à me demander si j'ai besoin de recompiler OpenCV pour VS2015 –