QGraphicsRectItem无法与OpenCV一起正常使用

时间:2018-12-09 21:55:32

标签: c++ opencv qt5 qt4 opencv3.0

我即将完成一个带有多个控件的用户界面,但是我有一个问题,我已经苦苦挣扎了一段时间。在QGraphicsView(左)上有一个图像(例如,黑白),例如图像A。在另一个QGraphicsView(右)上,我具有相同的图像,例如图像B,我将其从RGB转换为黑白。 一旦我单击左视图,便捕获了一个点,然后在右视图中,我试图找到相同的匹配项。 下图中是现在正在发生的事情

enter image description here

该算法可以工作并找到匹配项,但是速度很慢。我试图限制搜索区域,以便在图像B上从从A到B的间隔开始查找,而不是在整行中搜索。 低于预期的结果

enter image description here

下面,我附上进行搜索和匹配的代码的主要部分:

windowingDialog::windowingDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::windowingDialog)
{
    ui->setupUi(this);
    viewerScene = new WinGraphicsScene();
    ui->graphicsA->setScene(viewerScene);
    viewerSceneRight = new WinGraphicsScene();
    ui->graphicsB->setScene(viewerSceneRight);
    searchArea = new QGraphicsRectItem(0, 0, 0, 0);
    searchArea->setPen(QPen(QBrush(Qt::red), 20));
    viewerScene->addItem(searchArea);
    ui->graphicsA->show();

    searchingArea = new QGraphicsRectItem(0, 0, 0, 0);
    searchingArea->setPen(QPen(QBrush(Qt::red), 20));
    viewerSceneRight->addItem(searchingArea);
    ui->graphicsB->show();
}

bool windowingDialog::matchImages(QPointF point) {
    StereoCal match;
    match.readFile("/path/to/file.yml");

    StereoImage imagePair = listPtr->getImage(ui->listWidgetGraphA->currentRow());
    imagePair.getA().toGrey();
    imagePair.getA().to8Bit();
    imagePair.getB().toGrey();
    imagePair.getB().to8Bit();
    match.rectifyImages(imagePair);
    match.setRegionSize(ui->regionSizeSpinBox->value());
    match.clickPoint.x = (int)point.x();
    match.clickPoint.y = (int)point.y();

    cv::Point updatedPoint=match.checkPoint(match.clickPoint.x, match.clickPoint.y);

    // Area to search for on the second image
    searchArea->setRect(updatedPoint.x-ui->regionSizeSpinBox->value()/2, updatedPoint.y-ui->regionSizeSpinBox->value()/2, ui->regionSizeSpinBox->value(), ui->regionSizeSpinBox->value());
    searchArea->setZValue(1);
    ui->graphicsA->show();

    // Area we're searching on the second image
    searchingArea->setRect(0, updatedPoint.y-ui->regionSizeSpinBox->value()/2, ui->regionSizeSpinBox->value(), ui->regionSizeSpinBox->value());
    searchingArea->setZValue(1);
    ui->graphicsB->show();

    QApplication::processEvents();

    BestMatch best = match.findMatchedRegion(ui->matchProgressBarLeft, searchingArea, point.x(),point.y());
    ui->bestMatchPositionLineEdit->setText(QString::number(best.best));
    searchingArea->setPos(QPointF(best.best, searchingArea->pos().y()));
}

stereocal.h

void setRegionSize(int sz){regionSize=sz; km = (regionSize-1)/2;}
BestMatch findMatchedRegion(QProgressBar* progress, QGraphicsRectItem* target, int u, int v);

stereocal.cpp

//Find match for rectified image pairs
// Where I click automatically the region is set around the click.
BestMatch StereoCal::findMatchedRegion(QProgressBar* progress, QGraphicsRectItem* target, int u, int v){
    cv::Point updatedPoint=checkPoint(u, v);
    int xa = updatedPoint.y;
    int ya = updatedPoint.x;
    std::vector<double> errorVect;
    if(progress != NULL)
        progress->setRange(0, currentImages.getB().getBitmap().size().width-km);
    for(size_t i=km; i<currentImages.getB().getBitmap().size().width-km; i++){
        double error;
        error=getError(xa, ya, i, ya);
        errorVect.push_back(error);
        if(progress != NULL)
            progress->setValue(i);
        target->setPos(QPointF(i, target->pos().y()));
        QApplication::processEvents();
    }
    if(progress != NULL)
        progress->setValue(progress->value()+1);
    // we have to add km to take into account the serach started at k.
    // adjusts position in your vector back to pixel coordinate
    int best=getMin1D(errorVect, xa) +km;
    // the center of clicked point will be over the row
    int disparity = xa-best;

        cv::Point2f ptA, ptB;
        ptA.x=xa; ptA.y=ya;
        ptB.x=best; ptB.y=ya;
        std::vector<cv::Point2f> vA, nvA, vB, nvB;
        vA.push_back(ptA);vB.push_back(ptB);
        cropMatches(xa, ya, best, ya);
        cv::Vec3d adjpoint = triangulatePoints(vA,vB);
        BestMatch returnMatch;
        returnMatch.best = best;
        returnMatch.errvec = errorVect[best];
        returnMatch.disparity = disparity;
        returnMatch.fullError = errorVect;
        returnMatch.calculatedPoint = adjpoint;
        return returnMatch;
    }
    //Calculate SSD for pixel-centered regions
    double StereoCal::getError(int xa, int ya, int xb /* xb is the only changing for now*/, int yb){
        double error=0.0;
        Image aT,bT;
        cv::Mat a,b;
        aT=currentImages.getA();
        if(aT.getBitmap().channels() > 2) {
            aT.toGrey();
        }
        aT.getBitmap().convertTo(a, CV_32F);
        bT=currentImages.getB();
        if(bT.getBitmap().channels() > 2) {
            bT.toGrey();
        }
        bT.getBitmap().convertTo(b, CV_32F);
            for (int kx = -km; kx <= km; kx++){
                for(int ky = -km; ky <= km; ky++){
                    error += std::pow((a.at<float>(ya+kx,xa+ky)-b.at<float>(yb+kx,xb+ky)),2);
                }
            }
        return error;
    }

    // Min error along epipolar line
    int StereoCal::getMin1D(std::vector<double> vec, int x){
        int pos=0;
        double min = vec[0];
        for(int i=1; i< vec.size(); i++){
            if(vec[i]<min){
                    pos=i;
                    min =vec[i];
            }
        }
        return pos;
    }

感谢您对此问题的理解或指出正确的方向

0 个答案:

没有答案