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+模板的方式好。唉,离线分析和实际生产区别还是挺大的。

你可能感兴趣的:(opencv)