基于OpenCV1.1的图像拼接
2015-04-09 18:05
246 查看
最近开发基于OpenCV的图像处理,OpenCV的确强大,根据近来的所学心得,来个比较麻烦也比较有代表性的项目,图像拼接,根据图像surf特征拼接.
首先准备两张有关联的图片,或者直接把一张图片分成两半。
大概步骤如下:
直接使用OpenCV方法:cvExtractSURF( object, 0, &objectKeypoints, &objectDescriptors, storage, params );
需要计算特征向量的距离,计算欧式距离,采用最近邻(Nearest Neighbor,NN)方法对特征点进行粗匹配来判断是否匹配
_pt1 = cvMat(1, n, CV_32FC2, &pt1[0] );
_pt2 = cvMat(1, n, CV_32FC2, &pt2[0] );
单应性矩阵 cvFindHomography( &_pt1, &_pt2, &_h, CV_RANSAC, 5 )
此处用CV_RANSAC算法
计算投影图像各点的投影位置
对图像进行投影:cvWarpPerspective(object,m_projImg,&PH);
m_projImg 即是投影后的图片,待拼接
CvRect roiRect = cvRect(xMin+m_iXL,yMin+m_iYT,xMax-xMin,yMax-yMin);
cvSetImageROI(m_pBigImg,roiRect);
roiRect = cvRect(xMin,yMin,xMax-xMin,yMax-yMin);
cvSetImageROI(m_projImg,roiRect);
cvCopy(m_projImg,m_pBigImg);
暂时效果是可以,因为还没做图像融合,所以还需进一步处理,
全部代码地址:http://download.csdn.net/detail/inmiracle/8578651
欢迎大家交流学习,Q群:213700322
首先准备两张有关联的图片,或者直接把一张图片分成两半。
大概步骤如下:
1 特征提取
载入图片后,转灰度,计算图片的特征点,经典的surf算法就可以。直接使用OpenCV方法:cvExtractSURF( object, 0, &objectKeypoints, &objectDescriptors, storage, params );
2 特征点匹配
特征点的匹配的准确性直接影响投影矩阵,所以匹配要求还是要尽量去准确,采用opencv例程中的匹配算法,需要计算特征向量的距离,计算欧式距离,采用最近邻(Nearest Neighbor,NN)方法对特征点进行粗匹配来判断是否匹配
int naiveNearestNeighbor( const float* vec, int laplacian, const CvSeq* model_keypoints, const CvSeq* model_descriptors ) { int length = (int)(model_descriptors->elem_size/sizeof(float)); int i, neighbor = -1; double d, dist1 = 1e6, dist2 = 1e6; CvSeqReader reader, kreader; cvStartReadSeq( model_keypoints, &kreader, 0 ); cvStartReadSeq( model_descriptors, &reader, 0 ); for( i = 0; i < model_descriptors->total; i++ ) { const CvSURFPoint* kp = (const CvSURFPoint*)kreader.ptr; const float* mvec = (const float*)reader.ptr; CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader ); CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader ); if( laplacian != kp->laplacian ) continue; d = compareSURFDescriptors( vec, mvec, dist2, length ); if( d < dist1 ) { dist2 = dist1; dist1 = d; neighbor = i; } else if ( d < dist2 ) dist2 = d; } if ( dist1 < 0.6*dist2 ) return neighbor; return -1; }一对特征保存连续的集合中,后面计算在分别取出奇数和偶数对特征,取出特征
findPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs ); n = ptpairs.size()/2; if( n < 4 ) return 0; pt1.resize(n); pt2.resize(n); for( i = 0; i < n; i++ ) { pt1[i] = ((CvSURFPoint*)cvGetSeqElem(objectKeypoints,ptpairs[i*2]))->pt; pt2[i] = ((CvSURFPoint*)cvGetSeqElem(imageKeypoints,ptpairs[i*2+1]))->pt; }
3 特征点提纯
4 旋转矩阵
根据取出的特征,求单应性矩阵,_pt1 = cvMat(1, n, CV_32FC2, &pt1[0] );
_pt2 = cvMat(1, n, CV_32FC2, &pt2[0] );
单应性矩阵 cvFindHomography( &_pt1, &_pt2, &_h, CV_RANSAC, 5 )
此处用CV_RANSAC算法
计算投影图像各点的投影位置
for( i = 0; i < 4; i++ ) { double x = src_corners[i].x, y = src_corners[i].y; double Z = 1./(h[6]*x + h[7]*y + h[8]); double X = (h[0]*x + h[1]*y + h[2])*Z; double Y = (h[3]*x + h[4]*y + h[5])*Z; dst_corners[i] = cvPoint2D32f(X,Y/*cvRound(X), cvRound(Y)*/); }
对图像进行投影:cvWarpPerspective(object,m_projImg,&PH);
m_projImg 即是投影后的图片,待拼接
5 图像拼接
根据投影的图像,进行拼接,分别设置roi,CvRect roiRect = cvRect(xMin+m_iXL,yMin+m_iYT,xMax-xMin,yMax-yMin);
cvSetImageROI(m_pBigImg,roiRect);
roiRect = cvRect(xMin,yMin,xMax-xMin,yMax-yMin);
cvSetImageROI(m_projImg,roiRect);
cvCopy(m_projImg,m_pBigImg);
6.测试结果
大图:暂时效果是可以,因为还没做图像融合,所以还需进一步处理,
全部代码地址:http://download.csdn.net/detail/inmiracle/8578651
欢迎大家交流学习,Q群:213700322
相关文章推荐
- 特征点匹配应用——图像拼接的原理与基于OpenCV的实现
- 基于opencv的图像拼接(四): 基于stitch类的离线图像拼接
- 基于OpenCV全景图像拼接
- 基于opencv的图像拼接(二): stitch 类
- opencv2两张图像拼接融合_基于SURF特征提取
- 基于opencv的图像拼接(三): 基于stitch类的实时图像拼接
- 【OpenCV图像处理入门学习教程三】基于SIFT特征和SURF特征的微旋转图像拼接与融合生成全景图像的比较
- 基于DCMTK和OpenCV的DR图像拼接
- 基于opencv的图像拼接(一): sift特征点提取
- 基于OpenCV的图像拼接
- 基于Opencv计算图像的均值和方差
- OpenCV_基于Laplacian算子的图像边缘增强
- OpenCV基于直方图特征的图像搜索
- openCV基于图像处理的自动聚焦
- 图像拼接实现镜面效果 opencv完整代码 实现(附实验结果)
- opencv 开源图像拼接
- 图像拼接 opencv
- OpenCV-基于特征点的图像匹配
- 基于图像的碎纸拼接技术
- VS2010实现opencv基于DCT的图像压缩