Documentation Index Fetch the complete documentation index at: https://mintlify.com/opencv/opencv/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Stitching module provides a complete pipeline for creating panoramas from multiple images. It handles:
Feature detection and matching
Camera parameter estimation
Image warping
Exposure compensation
Seam finding
Image blending
Quick Start
Simple Panorama
#include <opencv2/stitching.hpp>
using namespace cv ;
int main () {
// Load images
std ::vector < Mat > images;
images . push_back ( imread ( "img1.jpg" ));
images . push_back ( imread ( "img2.jpg" ));
images . push_back ( imread ( "img3.jpg" ));
// Create stitcher
Ptr < Stitcher > stitcher = Stitcher :: create (
Stitcher ::PANORAMA
);
// Stitch images
Mat pano;
Stitcher ::Status status = stitcher -> stitch (images, pano);
if (status == Stitcher ::OK) {
imwrite ( "panorama.jpg" , pano);
} else {
std ::cerr << "Stitching failed: " << status << std ::endl;
}
return 0 ;
}
Stitcher Modes
PANORAMA Mode
For regular camera photos:
Ptr < Stitcher > stitcher = Stitcher :: create ( Stitcher ::PANORAMA);
Features :
Expects perspective transformations
Uses homography-based estimation
Projects to spherical surface
Applies exposure compensation
SCANS Mode
For scanned images or documents:
Ptr < Stitcher > stitcher = Stitcher :: create ( Stitcher ::SCANS);
Features :
Expects affine transformations
No exposure compensation
Better for flat scans
Stitching Pipeline
Step-by-Step Process
// 1. Create stitcher
Ptr < Stitcher > stitcher = Stitcher :: create ();
// 2. Configure (optional)
stitcher -> setRegistrationResol ( 0.6 ); // Resolution for registration
stitcher -> setSeamEstimationResol ( 0.1 ); // Resolution for seam finding
stitcher -> setCompositingResol ( - 1 ); // Use original resolution
stitcher -> setPanoConfidenceThresh ( 1 ); // Confidence threshold
// 3. Estimate transformations
Stitcher ::Status status = stitcher -> estimateTransform (images);
if (status != Stitcher ::OK) {
std ::cerr << "Transform estimation failed \n " ;
return - 1 ;
}
// 4. Compose panorama
Mat pano;
status = stitcher -> composePanorama (pano);
Advanced Configuration
Feature Detection
// Use ORB features (faster)
Ptr < ORB > orb = ORB :: create ( 500 );
stitcher -> setFeaturesFinder (orb);
// Use SIFT features (better quality)
Ptr < SIFT > sift = SIFT :: create ();
stitcher -> setFeaturesFinder (sift);
Feature Matching
using namespace cv :: detail ;
// Best of 2 nearest matcher
Ptr < BestOf2NearestMatcher > matcher =
makePtr < BestOf2NearestMatcher >( false , 0.3 f );
stitcher -> setFeaturesMatcher (matcher);
// Affine matcher (for SCANS mode)
Ptr < AffineBestOf2NearestMatcher > affineMatcher =
makePtr < AffineBestOf2NearestMatcher >();
stitcher -> setFeaturesMatcher (affineMatcher);
Warping
// Spherical warper (default for PANORAMA)
Ptr < SphericalWarper > warper =
makePtr < SphericalWarper >();
stitcher -> setWarper (warper);
// Cylindrical warper
Ptr < CylindricalWarper > cylindrical =
makePtr < CylindricalWarper >();
stitcher -> setWarper (cylindrical);
// Plane warper
Ptr < PlaneWarper > plane =
makePtr < PlaneWarper >();
stitcher -> setWarper (plane);
Exposure Compensation
using namespace cv :: detail ;
// Block-based gain compensation
Ptr < BlocksGainCompensator > compensator =
makePtr < BlocksGainCompensator >();
stitcher -> setExposureCompensator (compensator);
// No compensation
Ptr < NoExposureCompensator > noComp =
makePtr < NoExposureCompensator >();
stitcher -> setExposureCompensator (noComp);
Seam Finding
using namespace cv :: detail ;
// Graph cut seam finder (best quality)
Ptr < GraphCutSeamFinder > seamFinder =
makePtr < GraphCutSeamFinder >( GraphCutSeamFinder ::COST_COLOR);
stitcher -> setSeamFinder (seamFinder);
// Voronoi seam finder (faster)
Ptr < VoronoiSeamFinder > voronoi =
makePtr < VoronoiSeamFinder >();
stitcher -> setSeamFinder (voronoi);
Blending
using namespace cv :: detail ;
// Multi-band blending (best quality)
Ptr < MultiBandBlender > blender =
makePtr < MultiBandBlender >( false , 5 );
stitcher -> setBlender (blender);
// Feather blending (faster)
Ptr < FeatherBlender > feather =
makePtr < FeatherBlender >( 0.01 f );
stitcher -> setBlender (feather);
Resolution Control
// Set resolutions (megapixels)
stitcher -> setRegistrationResol ( 0.6 ); // Feature detection
stitcher -> setSeamEstimationResol ( 0.1 ); // Seam finding
stitcher -> setCompositingResol ( - 1 ); // Final output (-1 = original)
// Use original resolution everywhere
stitcher -> setRegistrationResol ( Stitcher ::ORIG_RESOL);
stitcher -> setSeamEstimationResol ( Stitcher ::ORIG_RESOL);
stitcher -> setCompositingResol ( Stitcher ::ORIG_RESOL);
Error Handling
Stitcher ::Status status = stitcher -> stitch (images, pano);
switch (status) {
case Stitcher :: OK :
std ::cout << "Stitching successful \n " ;
break ;
case Stitcher :: ERR_NEED_MORE_IMGS :
std ::cerr << "Need more images \n " ;
break ;
case Stitcher :: ERR_HOMOGRAPHY_EST_FAIL :
std ::cerr << "Homography estimation failed \n " ;
break ;
case Stitcher :: ERR_CAMERA_PARAMS_ADJUST_FAIL :
std ::cerr << "Camera parameter adjustment failed \n " ;
break ;
}
Complete Example: Custom Pipeline
#include <opencv2/stitching.hpp>
#include <opencv2/features2d.hpp>
using namespace cv ;
using namespace cv :: detail ;
int main () {
// Load images
std ::vector < Mat > images;
for ( int i = 1 ; i <= 5 ; i ++ ) {
images . push_back (
imread ( "img" + std :: to_string (i) + ".jpg" )
);
}
// Create and configure stitcher
Ptr < Stitcher > stitcher = Stitcher :: create (
Stitcher ::PANORAMA
);
// Use SIFT features
Ptr < SIFT > sift = SIFT :: create ( 1000 );
stitcher -> setFeaturesFinder (sift);
// Configure resolution
stitcher -> setRegistrationResol ( 0.6 );
stitcher -> setSeamEstimationResol ( 0.1 );
stitcher -> setCompositingResol ( 1.0 );
// Graph cut seam finder
Ptr < GraphCutSeamFinder > seamFinder =
makePtr < GraphCutSeamFinder >(
GraphCutSeamFinder ::COST_COLOR
);
stitcher -> setSeamFinder (seamFinder);
// Multi-band blending
stitcher -> setBlender (
makePtr < MultiBandBlender >( false , 5 )
);
// Estimate transforms
Stitcher ::Status status =
stitcher -> estimateTransform (images);
if (status != Stitcher ::OK) {
std ::cerr << "Transform estimation failed: "
<< status << std ::endl;
return - 1 ;
}
// Get camera parameters
std ::vector < CameraParams > cameras =
stitcher -> cameras ();
std ::cout << "Found " << cameras . size ()
<< " cameras \n " ;
// Compose panorama
Mat pano;
status = stitcher -> composePanorama (pano);
if (status == Stitcher ::OK) {
imwrite ( "panorama.jpg" , pano);
std ::cout << "Panorama size: "
<< pano . size () << std ::endl;
}
return 0 ;
}
Best Practices
Overlapping Images 30-50% overlap between adjacent images
Consistent Exposure Use manual exposure or lock exposure
Fixed Focal Length Avoid zooming between shots
Steady Camera Use tripod for best results
// Reduce resolution for speed
stitcher -> setRegistrationResol ( 0.3 ); // Lower = faster
stitcher -> setSeamEstimationResol ( 0.05 );
// Use faster algorithms
stitcher -> setFeaturesFinder ( ORB :: create ( 500 ));
stitcher -> setSeamFinder (
makePtr < VoronoiSeamFinder >()
);
stitcher -> setBlender (
makePtr < FeatherBlender >( 0.01 f )
);
Troubleshooting
Stitching Fails
Check image overlap (needs 30%+)
Ensure similar lighting
Try different feature detectors
Increase confidence threshold
Poor Quality
Increase registration resolution
Use graph cut seam finder
Use multi-band blending
Enable exposure compensation
See Also