热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于OpenCV1.1的图像拼接

最近开发基于OpenCV的图像处理,OpenCV的确强大,根据近来的所学心得,来个比较麻烦也比较有代表性的项目,图像拼接,根据图像surf特征拼接.首先准备两张有关联的图片,或者直接把

最近开发基于OpenCV的图像处理,OpenCV的确强大,根据近来的所学心得,来个比较麻烦也比较有代表性的项目,图像拼接,根据图像surf特征拼接.

首先准备两张有关联的图片,或者直接把一张图片分成两半。

大概步骤如下:

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 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 一对特征保存连续的集合中,后面计算在分别取出奇数和偶数对特征,取出特征 
 

    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 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





推荐阅读
  • Spring Boot + RabbitMQ 消息确认机制详解
    本文详细介绍如何在 Spring Boot 项目中使用 RabbitMQ 的消息确认机制,包括消息发送确认和消息接收确认,帮助开发者解决在实际操作中可能遇到的问题。 ... [详细]
  • ipsec 加密流程(二):ipsec初始化操作
    《openswan》专栏系列文章主要是记录openswan源码学习过程中的笔记。Author:叨陪鲤Email:vip_13031075266163.comDate:2020.1 ... [详细]
  • PBO(PixelBufferObject),将像素数据存储在显存中。优点:1、快速的像素数据传递,它采用了一种叫DMA(DirectM ... [详细]
  • iOS snow animation
    CTSnowAnimationView.hCTMyCtripCreatedbyalexon1614.Copyright©2016年ctrip.Allrightsreserved.# ... [详细]
  • Cookie学习小结
    Cookie学习小结 ... [详细]
  • 零拷贝技术是提高I/O性能的重要手段,常用于Java NIO、Netty、Kafka等框架中。本文将详细解析零拷贝技术的原理及其应用。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 本文介绍了如何利用 Delphi 中的 IdTCPServer 和 IdTCPClient 控件实现高效的文件传输。这些控件在默认情况下采用阻塞模式,并且服务器端已经集成了多线程处理,能够支持任意大小的文件传输,无需担心数据包大小的限制。与传统的 ClientSocket 相比,Indy 控件提供了更为简洁和可靠的解决方案,特别适用于开发高性能的网络文件传输应用程序。 ... [详细]
  • 在 Linux 环境下,多线程编程是实现高效并发处理的重要技术。本文通过具体的实战案例,详细分析了多线程编程的关键技术和常见问题。文章首先介绍了多线程的基本概念和创建方法,然后通过实例代码展示了如何使用 pthreads 库进行线程同步和通信。此外,还探讨了多线程程序中的性能优化技巧和调试方法,为开发者提供了宝贵的实践经验。 ... [详细]
  • 本文探讨了 Kafka 集群的高效部署与优化策略。首先介绍了 Kafka 的下载与安装步骤,包括从官方网站获取最新版本的压缩包并进行解压。随后详细讨论了集群配置的最佳实践,涵盖节点选择、网络优化和性能调优等方面,旨在提升系统的稳定性和处理能力。此外,还提供了常见的故障排查方法和监控方案,帮助运维人员更好地管理和维护 Kafka 集群。 ... [详细]
  • 【转】强大的矩阵奇异值分解(SVD)及其应用
    在工程实践中,经常要对大矩阵进行计算,除了使用分布式处理方法以外,就是通过理论方法,对矩阵降维。一下文章,我在 ... [详细]
  • java解析json转Map前段时间在做json报文处理的时候,写了一个针对不同格式json转map的处理工具方法,总结记录如下:1、单节点单层级、单节点多层级json转mapim ... [详细]
  • 本文详细介绍了在 CentOS 7 系统中配置 fstab 文件以实现开机自动挂载 NFS 共享目录的方法,并解决了常见的配置失败问题。 ... [详细]
  • 本文详细探讨了Oracle数据库中Number和Float数据类型的特性和使用方法。通过对比分析,解释了Number类型在精度和范围上的优势,以及Float类型在处理科学计算时的灵活性。文章还介绍了Number数据类型的语法结构及其在实际应用中的最佳实践,帮助读者更好地理解和选择合适的数据类型以满足不同的业务需求。 ... [详细]
author-avatar
墨镜猛女班长
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有