opencv检测画面刚性平移

参考:
原理:http://www.360doc.com/content/18/0301/16/18306241_733458609.shtml
使用:https://blog.csdn.net/wujuxKkoolerter/article/details/113068318

最近在弄一个图像拼接的东西,总体上类似把一个面阵相机当成线阵相机那样用,把连续拍摄的图片拼接起来。
但是难点在于拍摄的物体并不是匀速运动的,也没有编码器给出位移的脉冲信号。
所以只能够根据前后两张图片来计算被拍摄物体的位移,然后拼接了。

一开始是用各种方法来找特征、均值、最值什么的,甚至opencv的各种tracking方法都用过了,效果都不好。
然后无意中发现了这个 phaseCorrelate 函数,用了之后发现,居然有奇效。效果好、速度快,完美。

void MainWindow::phaseTest()
{
    QStringList mFileList;

    QString imgSrc;
    if(IMG_SOURCE == 0)
    {
        imgSrc = "./imgs/left";
    }
    else
    {
        imgSrc = "./imgs/right";
    }

    QDir dir(imgSrc);

    dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
    dir.setSorting(QDir::Size | QDir::Reversed);

    QFileInfoList list = dir.entryInfoList();
    for (int i = 0; i < list.size(); ++i)
    {
        QFileInfo fileInfo = list.at(i);

        mFileList.push_back(fileInfo.filePath().toUtf8());
    }

    QCollator collator;
    collator.setNumericMode(true);

    std::sort(mFileList.begin(), mFileList.end(),
              [& collator](const QString & str1, const QString & str2)
    {
        return collator.compare(str1, str2) < 0;
    }
    );

    qDebug() << mFileList;

    Mat stitchedMat;

    for(int i = 0; i < mFileList.length() - 1; i++)
    {
        Mat img1 = imread(mFileList[i].toStdString(), IMREAD_GRAYSCALE);
        Mat img2 = imread(mFileList[i + 1].toStdString(), IMREAD_GRAYSCALE);

        cv::Rect roi;
        if(IMG_SOURCE == 0)
        {
            roi = cv::Rect(650, 270, 750, 120); 
        }
        else
        {
            roi = cv::Rect(640, 194, 210, 178); 
        }

        img1 = img1(roi);
        img2 = img2(roi);

        if(stitchedMat.empty())
        {
            stitchedMat = img1.clone();
        }

        Mat pre32f, cur32f, hann;

//        img1.convertTo(pre32f, CV_32F);
//        img2.convertTo(cur32f, CV_32F);

        GaussianBlur(img1, img1, Size(5,5), 0, 0, BORDER_DEFAULT);
        GaussianBlur(img2, img2, Size(5,5), 0, 0, BORDER_DEFAULT);

        cv::Laplacian(img1, pre32f, CV_32F, 3);
        cv::Laplacian(img2, cur32f, CV_32F, 3);

        imshow("lap", pre32f);

        QTime begin = QTime::currentTime();
        auto offset2d = phaseCorrelate(pre32f, cur32f);
        qDebug() << "interval:" << begin.msecsTo(QTime::currentTime());

        qDebug() << offset2d.x << offset2d.y;

        int offset = offset2d.y + 0.5;

        if(offset > 1)
        {
            Mat out;

            OptimizeSeam(img2, stitchedMat, offset, out);

            stitchedMat = out;
        }

        imshow("img", img2);
        imshow("拼接图像", stitchedMat);

        cv::waitKey(1);
    }
}

后记:后来实际部署到产线之后,效果还是不如之前用的sobel+模板的方式好。唉,离线分析和实际生产区别还是挺大的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV 是一个开源的计算机视觉库,其提供了丰富的图像处理和计算机视觉算法。其中一个常用的功能是模板匹配,它可以在给定的图像中查找与目标模板最匹配的位置。 模板匹配通常用于在图像中定位特定的对象,例如在一张照片中找到人脸、车辆或其他特定的物体。模板匹配基于计算目标模板与输入图像各个位置的相似度,并找到最匹配的位置。 在模板匹配中,模板图像是我们要在输入图像中查找的目标对象图像。匹配过程中,模板会在输入图像的各个位置上滑动,计算模板与输入图像对应区域的相似度。常用的相似度度量方法有平方差匹配(Squared Difference)、相关性匹配(Correlation)和归一化相关性匹配(Normalized Correlation)等。 在实际应用中,模板匹配可能会出现对象旋转和平移的情况。为了解决旋转和平移带来的匹配问题,可以通过对模板图像进行旋转平移变换,使其与输入图像更好地对齐。OpenCV 提供了旋转平移变换相关的函数,如 `cv2.getRotationMatrix2D` 和 `cv2.warpAffine`,可以方便地旋转平移模板图像。 通过旋转平移变换,我们可以将模板图像校正为与输入图像对齐的形式。然后再进行模板匹配,即可得到比较准确的匹配结果。需要注意的是,在进行旋转平移变换时,需要确定旋转角度和平移距离的参数,这需要根据实际情况进行调整。 综上所述,OpenCV 提供了丰富的功能用于模板匹配,并且可以通过旋转平移变换对模板图像进行调整以适应旋转平移的情况。这些功能在计算机视觉和图像处理领域有着广泛的应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值