Я собираюсь завершить пользовательский интерфейс несколькими элементами управления, но у меня есть проблема, с которой я боролся некоторое время.В QGraphicsView (слева) у меня есть изображение (например, черно-белое), скажем, Image A. В другом QGraphicsView (справа) у меня есть такое же изображение, скажем, Image B, которое я преобразую из RGB в черно-белое.Как только я нажимаю на левое представление, я фиксирую точку, а на правом изображении я пытаюсь найти то же совпадение. На рисунке ниже показано, что происходит сейчас :
Алгоритм работает и находит совпадение, но он очень медленный,Я пытаюсь ограничить область поиска так, чтобы на изображении B она начинала смотреть с интервала, который идет от A до B, вместо поиска по всей строке. Ниже желаемого результата :
Ниже я прилагаю основную часть кода, который выполняет поиск и сопоставление:
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;
}
Спасибо за пролить свет наэтот вопрос или указывает в правильном направлении