|
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "superResolutionImg.h"
|
|
|
|
|
|
|
|
|
|
// openCV Library
|
|
|
|
|
#include <opencv2/opencv.hpp>
|
|
|
|
|
#include "opencv2/nonfree/features2d.hpp"
|
|
|
|
|
using namespace cv;
|
|
|
|
|
|
|
|
|
|
#include <deque>
|
|
|
|
|
|
|
|
|
|
#include "fuseImg.h"
|
|
|
|
|
#include "histProject.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20>Ƴ<EFBFBD>NN<4E><4E><EFBFBD>ʴ<EFBFBD><CAB4><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>ƥ<EFBFBD><C6A5>
|
|
|
|
|
int ClearMatchByKnnRatio(std::vector<std::vector<cv::DMatch>> &matches, float ratio)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// <20>Ƴ<EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
|
|
|
|
int removedCount = 0;
|
|
|
|
|
|
|
|
|
|
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
std::vector<std::vector<cv::DMatch>>::iterator DMatchIterator = matches.begin();
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>
|
|
|
|
|
for (; DMatchIterator != matches.end(); ++DMatchIterator)
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if (DMatchIterator->size() > 1)
|
|
|
|
|
{
|
|
|
|
|
// <20>ν<EFBFBD><CEBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if ((*DMatchIterator)[1].distance > 0)
|
|
|
|
|
{
|
|
|
|
|
if ((*DMatchIterator)[0].distance / (*DMatchIterator)[1].distance > ratio)
|
|
|
|
|
{
|
|
|
|
|
DMatchIterator->clear();
|
|
|
|
|
removedCount++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DMatchIterator->clear();
|
|
|
|
|
removedCount++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
{
|
|
|
|
|
DMatchIterator->clear();
|
|
|
|
|
removedCount++;
|
|
|
|
|
}
|
|
|
|
|
} // end of for
|
|
|
|
|
|
|
|
|
|
return removedCount;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><>ȡ<EFBFBD>Գ<EFBFBD>ƥ<EFBFBD><C6A5>
|
|
|
|
|
int GetSysmmetryMatch(std::vector<cv::DMatch> &sysmMatches,
|
|
|
|
|
const std::vector<std::vector<cv::DMatch>> &preMatches,
|
|
|
|
|
const std::vector<std::vector<cv::DMatch>> &nextMatches)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
sysmMatches.clear();
|
|
|
|
|
|
|
|
|
|
// <20>Գ<EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD>Ŀ
|
|
|
|
|
int sysmMatchNum = 0;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>matches1<73><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>
|
|
|
|
|
std::vector<std::vector<cv::DMatch>>::const_iterator preMatchesIterator = preMatches.begin();
|
|
|
|
|
for(; preMatchesIterator != preMatches.end(); preMatchesIterator++)
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>
|
|
|
|
|
if (preMatchesIterator->size() < 2)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>matches2<73><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>
|
|
|
|
|
std::vector<std::vector<cv::DMatch>>::const_iterator nextMatchesIterator = nextMatches.begin();
|
|
|
|
|
for(; nextMatchesIterator != nextMatches.end(); nextMatchesIterator++)
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>
|
|
|
|
|
if (nextMatchesIterator->size() < 2)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((*preMatchesIterator)[0].queryIdx == (*nextMatchesIterator)[0].trainIdx
|
|
|
|
|
&& (*preMatchesIterator)[0].trainIdx == (*nextMatchesIterator)[0].queryIdx)
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD>ӶԳ<D3B6>ƥ<EFBFBD><C6A5>
|
|
|
|
|
sysmMatches.push_back(cv::DMatch((*preMatchesIterator)[0].queryIdx, (*preMatchesIterator)[0].trainIdx, (*preMatchesIterator)[0].distance));
|
|
|
|
|
sysmMatchNum++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>ضԳ<D8B6>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD>Ŀ
|
|
|
|
|
return sysmMatchNum;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>ڡ<EFBFBD><DAA1>Լ<EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>RANSAC<41><43><EFBFBD>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
bool GetRansacBaseMatch(std::vector<cv::DMatch> &ransacMatches,
|
|
|
|
|
std::vector<cv::Point2f> &prePts,
|
|
|
|
|
std::vector<cv::Point2f> &nextPts,
|
|
|
|
|
const std::vector<cv::DMatch> &matches,
|
|
|
|
|
const std::vector<cv::KeyPoint> &preKeyPts,
|
|
|
|
|
const std::vector<cv::KeyPoint> &nextKeyPts)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD> <20>Լ<EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ8<D2AA><38><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
|
|
|
|
|
if (matches.size() > preKeyPts.size() || matches.size() > nextKeyPts.size() || matches.size() < 12)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
ransacMatches.clear();
|
|
|
|
|
prePts.clear();
|
|
|
|
|
nextPts.clear();
|
|
|
|
|
|
|
|
|
|
// ת<><D7AA>KeyPoint<6E><74><EFBFBD>͵<EFBFBD>Point2f
|
|
|
|
|
std::vector<DMatch>::const_iterator it = matches.begin();
|
|
|
|
|
for(; it != matches.end(); it++)
|
|
|
|
|
{
|
|
|
|
|
// <20>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
prePts.push_back(preKeyPts[it->queryIdx].pt);
|
|
|
|
|
|
|
|
|
|
// <20>õ<EFBFBD><C3B5>ұ<EFBFBD><D2B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
nextPts.push_back(nextKeyPts[it->trainIdx].pt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>RANSAC<41><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
std::vector<unsigned char> inliers(prePts.size(), 0);
|
|
|
|
|
cv::Mat fundementalMat; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
fundementalMat = cv::findFundamentalMat(cv::Mat(prePts), // <20><><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD>㼯1
|
|
|
|
|
cv::Mat(nextPts), // <20><><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD>㼯2
|
|
|
|
|
inliers, // <20><><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>״̬ outlier(0) inlier(1)
|
|
|
|
|
CV_FM_RANSAC, // RANSAC<41><43><EFBFBD><EFBFBD>
|
|
|
|
|
3.0, // <20><><EFBFBD><EFBFBD><EFBFBD>ߵľ<DFB5><C4BE><EFBFBD>
|
|
|
|
|
0.99); // <20><><EFBFBD>Ÿ<EFBFBD><C5B8><EFBFBD>
|
|
|
|
|
|
|
|
|
|
// <20><>ȡͨ<C8A1><CDA8><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>
|
|
|
|
|
std::vector<unsigned char>::const_iterator itInliers = inliers.begin();
|
|
|
|
|
std::vector<cv::DMatch>::const_iterator itMatches = matches.begin();
|
|
|
|
|
for (; itInliers != inliers.end(); ++itInliers,++itMatches)
|
|
|
|
|
{
|
|
|
|
|
if (*itInliers) // <20><>Чƥ<D0A7><C6A5>
|
|
|
|
|
{
|
|
|
|
|
ransacMatches.push_back((*itMatches));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>ݽ<EFBFBD><DDBD>յ<EFBFBD>ƥ<EFBFBD>䣬<EFBFBD><E4A3AC><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>fundementalMat
|
|
|
|
|
prePts.clear();
|
|
|
|
|
nextPts.clear();
|
|
|
|
|
|
|
|
|
|
std::vector<DMatch>::const_iterator itRansacMatches = ransacMatches.begin();
|
|
|
|
|
for(; itRansacMatches != ransacMatches.end(); ++itRansacMatches)
|
|
|
|
|
{
|
|
|
|
|
// <20>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
prePts.push_back(preKeyPts[itRansacMatches->queryIdx].pt);
|
|
|
|
|
|
|
|
|
|
// <20>õ<EFBFBD><C3B5>ұ<EFBFBD><D2B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
nextPts.push_back(nextKeyPts[itRansacMatches->trainIdx].pt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD>˼<EFBFBD><CBBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>任<EFBFBD><E4BBBB><EFBFBD><EFBFBD>
|
|
|
|
|
bool GetAffineTransMat(cv::Mat &result,
|
|
|
|
|
const std::vector<Point2f> &prePoints,
|
|
|
|
|
const std::vector<Point2f> &nextPoints)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
int preSize = prePoints.size();
|
|
|
|
|
int nextSize = nextPoints.size();
|
|
|
|
|
|
|
|
|
|
if (preSize < 3 || nextSize < 3 || preSize != nextSize)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
result.create(3, 3, CV_64FC1);
|
|
|
|
|
result = cv::Scalar(0);
|
|
|
|
|
|
|
|
|
|
// ƥ<><C6A5><EFBFBD><EFBFBD>Ŀ
|
|
|
|
|
int MatchNum = preSize;
|
|
|
|
|
|
|
|
|
|
/* set up matrices so we can unstack homography into X; AX = B */
|
|
|
|
|
cv::Mat A(2 * MatchNum, 6, CV_64FC1);
|
|
|
|
|
cv::Mat B(2 * MatchNum, 1, CV_64FC1);
|
|
|
|
|
cv::Mat X(6, 1, CV_64FC1);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>
|
|
|
|
|
A = cv::Scalar(0);
|
|
|
|
|
B = cv::Scalar(0);
|
|
|
|
|
X = cv::Scalar(0);
|
|
|
|
|
|
|
|
|
|
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
for(int i = 0; i < MatchNum; i++ )
|
|
|
|
|
{
|
|
|
|
|
A.at<double>(i, 0) = prePoints[i].x;
|
|
|
|
|
A.at<double>(i, 1) = prePoints[i].y;
|
|
|
|
|
A.at<double>(i, 2) = 1.0f;
|
|
|
|
|
|
|
|
|
|
A.at<double>(i + MatchNum, 3) = prePoints[i].x;
|
|
|
|
|
A.at<double>(i + MatchNum, 4) = prePoints[i].y;
|
|
|
|
|
A.at<double>(i + MatchNum, 5) = 1.0f;
|
|
|
|
|
|
|
|
|
|
B.at<double>(i, 0) = nextPoints[i].x;
|
|
|
|
|
B.at<double>(i + MatchNum, 0) = nextPoints[i].y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20>ⷽ<EFBFBD><E2B7BD>
|
|
|
|
|
cv::solve(A, B, X, CV_SVD);
|
|
|
|
|
|
|
|
|
|
// <20><>ֵ
|
|
|
|
|
result.at<double>(0, 0) = X.at<double>(0, 0);
|
|
|
|
|
result.at<double>(0, 1) = X.at<double>(1, 0);
|
|
|
|
|
result.at<double>(0, 2) = X.at<double>(2, 0);
|
|
|
|
|
result.at<double>(1, 0) = X.at<double>(3, 0);
|
|
|
|
|
result.at<double>(1, 1) = X.at<double>(4, 0);
|
|
|
|
|
result.at<double>(1, 2) = X.at<double>(5, 0);
|
|
|
|
|
result.at<double>(2, 0) = 0.0;
|
|
|
|
|
result.at<double>(2, 1) = 0.0;
|
|
|
|
|
result.at<double>(2, 2) = 1.0;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD>˼<EFBFBD><CBBC><EFBFBD><EFBFBD>ӱ任<D3B1><E4BBBB><EFBFBD><EFBFBD>
|
|
|
|
|
bool GetPerpectTransMat(cv::Mat &result,
|
|
|
|
|
const std::vector<Point2f> &prePoints,
|
|
|
|
|
const std::vector<Point2f> &nextPoints)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
int preSize = prePoints.size();
|
|
|
|
|
int nextSize = nextPoints.size();
|
|
|
|
|
|
|
|
|
|
if (preSize < 4 || nextSize < 4 || preSize != nextSize)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
result.create(3, 3, CV_64FC1);
|
|
|
|
|
result = cv::Scalar(0);
|
|
|
|
|
|
|
|
|
|
// ƥ<><C6A5><EFBFBD><EFBFBD>Ŀ
|
|
|
|
|
int MatchNum = nextSize;
|
|
|
|
|
|
|
|
|
|
/* set up matrices so we can unstack homography into X; AX = B */
|
|
|
|
|
cv::Mat A(2 * MatchNum, 8, CV_64FC1);
|
|
|
|
|
cv::Mat B(2 * MatchNum, 1, CV_64FC1);
|
|
|
|
|
cv::Mat X(8, 1, CV_64FC1);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>
|
|
|
|
|
A = cv::Scalar(0);
|
|
|
|
|
B = cv::Scalar(0);
|
|
|
|
|
X = cv::Scalar(0);
|
|
|
|
|
|
|
|
|
|
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
for(int i = 0; i < MatchNum; i++ )
|
|
|
|
|
{
|
|
|
|
|
A.at<double>(i, 0) = prePoints[i].x;
|
|
|
|
|
A.at<double>(i, 1) = prePoints[i].y;
|
|
|
|
|
A.at<double>(i, 2) = 1.0f;
|
|
|
|
|
A.at<double>(i, 6) = -prePoints[i].x * nextPoints[i].x;
|
|
|
|
|
A.at<double>(i, 7) = -prePoints[i].y * nextPoints[i].x;
|
|
|
|
|
|
|
|
|
|
A.at<double>(i + MatchNum, 3) = prePoints[i].x;
|
|
|
|
|
A.at<double>(i + MatchNum, 4) = prePoints[i].y;
|
|
|
|
|
A.at<double>(i + MatchNum, 5) = 1.0f;
|
|
|
|
|
A.at<double>(i + MatchNum, 6) = -prePoints[i].x * nextPoints[i].y;
|
|
|
|
|
A.at<double>(i + MatchNum, 7) = -prePoints[i].y * nextPoints[i].y;
|
|
|
|
|
|
|
|
|
|
B.at<double>(i, 0) = nextPoints[i].x;
|
|
|
|
|
B.at<double>(i + MatchNum, 0) = nextPoints[i].y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20>ⷽ<EFBFBD><E2B7BD>
|
|
|
|
|
cv::solve(A, B, X, CV_SVD);
|
|
|
|
|
|
|
|
|
|
// <20><>ֵ
|
|
|
|
|
result.at<double>(0, 0) = X.at<double>(0, 0);
|
|
|
|
|
result.at<double>(0, 1) = X.at<double>(1, 0);
|
|
|
|
|
result.at<double>(0, 2) = X.at<double>(2, 0);
|
|
|
|
|
result.at<double>(1, 0) = X.at<double>(3, 0);
|
|
|
|
|
result.at<double>(1, 1) = X.at<double>(4, 0);
|
|
|
|
|
result.at<double>(1, 2) = X.at<double>(5, 0);
|
|
|
|
|
result.at<double>(2, 0) = X.at<double>(6, 0);
|
|
|
|
|
result.at<double>(2, 1) = X.at<double>(7, 0);
|
|
|
|
|
result.at<double>(2, 2) = 1.0;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ
|
|
|
|
|
void CalImgAdjacentMat(std::deque<cv::Mat> &adjacentMatDeque,
|
|
|
|
|
std::deque<int> &successTagDeque,
|
|
|
|
|
const std::deque<std::vector<cv::KeyPoint>> &imgKeyptsDeque,
|
|
|
|
|
const std::deque<cv::Mat> &imgDescriptorsDeque)
|
|
|
|
|
{
|
|
|
|
|
if (imgKeyptsDeque.empty() == true
|
|
|
|
|
|| imgDescriptorsDeque.empty() == true
|
|
|
|
|
|| imgKeyptsDeque.size() != imgDescriptorsDeque.size())
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
adjacentMatDeque.clear();
|
|
|
|
|
successTagDeque.clear();
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>Ŀ
|
|
|
|
|
size_t count = imgKeyptsDeque.size();
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < (count - 1); i++)
|
|
|
|
|
{
|
|
|
|
|
// Flannƥ<6E><C6A5><EFBFBD><EFBFBD>
|
|
|
|
|
cv::FlannBasedMatcher matcher;
|
|
|
|
|
|
|
|
|
|
std::vector<cv::KeyPoint> preImgKeypts = imgKeyptsDeque.at(i);
|
|
|
|
|
std::vector<cv::KeyPoint> nextImgKeypts = imgKeyptsDeque.at(i + 1);
|
|
|
|
|
|
|
|
|
|
cv::Mat preImgDescriptors = imgDescriptorsDeque.at(i);
|
|
|
|
|
cv::Mat nextImgDescriptors = imgDescriptorsDeque.at(i + 1);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
std::vector<std::vector<cv::DMatch>> Pre2NextMatches;
|
|
|
|
|
std::vector<std::vector<cv::DMatch>> Next2PreMatches;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F>ν<EFBFBD><CEBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>
|
|
|
|
|
matcher.knnMatch(preImgDescriptors, nextImgDescriptors, Pre2NextMatches, 2); // ǰ<><C7B0>ƥ<EFBFBD><C6A5>
|
|
|
|
|
matcher.knnMatch(nextImgDescriptors, preImgDescriptors, Next2PreMatches, 2); // <20><><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>
|
|
|
|
|
|
|
|
|
|
// <20><EFBFBD><DEB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>
|
|
|
|
|
ClearMatchByKnnRatio(Pre2NextMatches, 0.65f);
|
|
|
|
|
ClearMatchByKnnRatio(Next2PreMatches, 0.65f);
|
|
|
|
|
|
|
|
|
|
// <20>Գ<EFBFBD>ƥ<EFBFBD><C6A5>
|
|
|
|
|
vector<DMatch> SysmMatches;
|
|
|
|
|
GetSysmmetryMatch(SysmMatches,
|
|
|
|
|
Pre2NextMatches,
|
|
|
|
|
Next2PreMatches);
|
|
|
|
|
|
|
|
|
|
// Ransac<61><63><EFBFBD>Լ<EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>
|
|
|
|
|
std::vector<cv::DMatch> RansacMatches;
|
|
|
|
|
std::vector<Point2f> PrePoints;
|
|
|
|
|
std::vector<Point2f> NextPoints;
|
|
|
|
|
bool MatchResult = false;
|
|
|
|
|
MatchResult = GetRansacBaseMatch(RansacMatches, // Ransacƥ<63><C6A5>
|
|
|
|
|
PrePoints,
|
|
|
|
|
NextPoints,
|
|
|
|
|
SysmMatches, // <20>Գ<EFBFBD>ƥ<EFBFBD><C6A5>
|
|
|
|
|
preImgKeypts,
|
|
|
|
|
nextImgKeypts);
|
|
|
|
|
|
|
|
|
|
if (MatchResult == false)
|
|
|
|
|
{
|
|
|
|
|
adjacentMatDeque.push_back(cv::Mat());
|
|
|
|
|
successTagDeque.push_back(0);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><>֡ͼ<D6A1><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӿ<EFBFBD><D3BE><EFBFBD>
|
|
|
|
|
bool TransResult = false;
|
|
|
|
|
cv::Mat AdjacentMat;
|
|
|
|
|
TransResult = GetPerpectTransMat(AdjacentMat, PrePoints, NextPoints);
|
|
|
|
|
|
|
|
|
|
if (TransResult == false)
|
|
|
|
|
{
|
|
|
|
|
adjacentMatDeque.push_back(cv::Mat());
|
|
|
|
|
successTagDeque.push_back(0);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
adjacentMatDeque.push_back(AdjacentMat);
|
|
|
|
|
successTagDeque.push_back(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20>Ҷ<EFBFBD>ͼ<EFBFBD><EFBFBD><F1A3A8BA><EFBFBD>ͼ<EFBFBD><EFBFBD><F1A3A9B3>ֱ<EFBFBD><D6B1>ʹ<EFBFBD><CAB9><EFBFBD>
|
|
|
|
|
int SuperResolutionImg(cv::Mat &dst, const std::deque<cv::Mat> &imgDeque, double multiple)
|
|
|
|
|
{
|
|
|
|
|
if (imgDeque.size() < 2)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>
|
|
|
|
|
if (multiple < 1)
|
|
|
|
|
{
|
|
|
|
|
multiple = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if (multiple > 2)
|
|
|
|
|
{
|
|
|
|
|
multiple = 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><> <20><>0<EFBFBD><30>ͼ<EFBFBD><CDBC>
|
|
|
|
|
cv::Size imgSize = imgDeque[0].size();
|
|
|
|
|
for (size_t i = 0; i < imgDeque.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
if (imgDeque[i].type() != CV_8UC1 || imgDeque[i].size() != imgSize) // <20>ߴ<EFBFBD><DFB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
|
|
|
|
std::deque<cv::Mat> imgUpSampleDeque;
|
|
|
|
|
for (size_t i = 0; i < imgDeque.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
// <20>ߴ<EFBFBD><DFB4>ӱ<EFBFBD>
|
|
|
|
|
cv::Mat upSampleImg;
|
|
|
|
|
cv::resize(imgDeque.at(i), upSampleImg, cv::Size(int(imgDeque.at(i).cols * multiple), int(imgDeque.at(i).rows * multiple)), 0, 0, 1);
|
|
|
|
|
imgUpSampleDeque.push_back(upSampleImg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
std::deque<std::vector<cv::KeyPoint>> imgKeyptsDeque;
|
|
|
|
|
std::deque<cv::Mat> imgDescriptorsDeque;
|
|
|
|
|
cv::SIFT sift(0, 3, 0.004); // С<><D0A1>ֵ
|
|
|
|
|
for (size_t i = 0; i < imgUpSampleDeque.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
std::vector<cv::KeyPoint> imgKeypts;
|
|
|
|
|
cv::Mat imgDescriptors;
|
|
|
|
|
sift(imgUpSampleDeque.at(i), noArray(), imgKeypts, imgDescriptors, false);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>
|
|
|
|
|
imgKeyptsDeque.push_back(imgKeypts);
|
|
|
|
|
imgDescriptorsDeque.push_back(imgDescriptors);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>
|
|
|
|
|
std::deque<cv::Mat> adjacentMatDeque;
|
|
|
|
|
std::deque<int> successTagDeque;
|
|
|
|
|
|
|
|
|
|
CalImgAdjacentMat(adjacentMatDeque, successTagDeque, imgKeyptsDeque, imgDescriptorsDeque);
|
|
|
|
|
|
|
|
|
|
// ѡ<><D1A1><EFBFBD><EFBFBD><EFBFBD>ѵ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
std::deque<int> segment;
|
|
|
|
|
for (size_t i = 0; i < successTagDeque.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
int count = 0;
|
|
|
|
|
for (size_t t = i; t < successTagDeque.size(); t++)
|
|
|
|
|
{
|
|
|
|
|
if (successTagDeque.at(t) == 1)
|
|
|
|
|
{
|
|
|
|
|
count++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
segment.push_back(count);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20>ҳ<EFBFBD><D2B3><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
|
|
|
|
|
std::deque<int> segmentCopy = segment;
|
|
|
|
|
std::sort(segmentCopy.begin(), segmentCopy.end());
|
|
|
|
|
int maxVal = segmentCopy.at(segmentCopy.size() - 1);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>3<EFBFBD><33>ͼ<EFBFBD><CDBC>
|
|
|
|
|
if (maxVal < 2)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int location = 0; // λ<><CEBB>
|
|
|
|
|
for (size_t i = 0; i < segment.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
if (maxVal == segment.at(i))
|
|
|
|
|
{
|
|
|
|
|
location = i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20>ں<EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if (maxVal == static_cast<int>(successTagDeque.size()))
|
|
|
|
|
{
|
|
|
|
|
// ͼ<><CDBC>ϸ<EFBFBD><CFB8><EFBFBD><EFBFBD>ǿ
|
|
|
|
|
for (size_t i = 0; i < imgUpSampleDeque.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
cv::Mat img;
|
|
|
|
|
imgUpSampleDeque[i].copyTo(img);
|
|
|
|
|
GNRHP(img, imgUpSampleDeque[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ں<EFBFBD>
|
|
|
|
|
for (int i = imgUpSampleDeque.size() - 2; i > -1; i--)
|
|
|
|
|
{
|
|
|
|
|
cv::Mat img_pre = imgUpSampleDeque[i];
|
|
|
|
|
cv::Mat img_next = imgUpSampleDeque[i+1];
|
|
|
|
|
|
|
|
|
|
cv::Mat img_preNext;
|
|
|
|
|
img_pre.copyTo(img_preNext);
|
|
|
|
|
|
|
|
|
|
// <20><>֡ͼ<D6A1><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӿ<EFBFBD><D3BE><EFBFBD>
|
|
|
|
|
cv::Mat m_AdjacentMat = adjacentMatDeque[i];
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>next <20>滻 pre ͼ<><CDBC>
|
|
|
|
|
double a00 = m_AdjacentMat.at<double>(0, 0);
|
|
|
|
|
double a01 = m_AdjacentMat.at<double>(0, 1);
|
|
|
|
|
double a02 = m_AdjacentMat.at<double>(0, 2);
|
|
|
|
|
double a10 = m_AdjacentMat.at<double>(1, 0);
|
|
|
|
|
double a11 = m_AdjacentMat.at<double>(1, 1);
|
|
|
|
|
double a12 = m_AdjacentMat.at<double>(1, 2);
|
|
|
|
|
double a20 = m_AdjacentMat.at<double>(2, 0);
|
|
|
|
|
double a21 = m_AdjacentMat.at<double>(2, 1);
|
|
|
|
|
double a22 = m_AdjacentMat.at<double>(2, 2);
|
|
|
|
|
|
|
|
|
|
for(int r = 0; r < img_preNext.rows; r++)
|
|
|
|
|
{
|
|
|
|
|
// #pragma omp parallel for
|
|
|
|
|
for (int c = 0; c < img_preNext.cols; c++)
|
|
|
|
|
{
|
|
|
|
|
double denominator = c * a20 + r * a21 + a22;
|
|
|
|
|
double src_x = (c * a00 + r * a01 + a02) / denominator;
|
|
|
|
|
double src_y = (c * a10 + r * a11 + a12) / denominator;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3>ٶȿ<D9B6>
|
|
|
|
|
int x_nearest = int(src_x + 0.5);
|
|
|
|
|
int y_nearest = int(src_y + 0.5);
|
|
|
|
|
|
|
|
|
|
if ( x_nearest >= 0 && y_nearest >= 0 && x_nearest < img_next.cols && y_nearest < img_next.rows)
|
|
|
|
|
{
|
|
|
|
|
img_preNext.at<unsigned char>(r, c) = img_next.at<unsigned char>(y_nearest, x_nearest);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؽ<EFBFBD><D8BD><EFBFBD>
|
|
|
|
|
|
|
|
|
|
// <20>ں<EFBFBD> img_pre <20><> img_preNext
|
|
|
|
|
cv::Mat fusion;
|
|
|
|
|
FuseImg(fusion, img_pre, img_preNext, "sym4", 10);
|
|
|
|
|
|
|
|
|
|
// <20><> fusion <20>滻 validImgUpSampleDeque[i]
|
|
|
|
|
fusion.copyTo(imgUpSampleDeque[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
imgUpSampleDeque[0].copyTo(dst);
|
|
|
|
|
|
|
|
|
|
return imgUpSampleDeque.size();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// ѡ<><D1A1><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>ͼ<EFBFBD><CDBC>Ƭ<EFBFBD><C6AC>
|
|
|
|
|
std::deque<cv::Mat> validImgUpSampleDeque(imgUpSampleDeque.begin() + location, imgUpSampleDeque.begin() + location + maxVal + 1);
|
|
|
|
|
|
|
|
|
|
// ͼ<><CDBC>ϸ<EFBFBD><CFB8><EFBFBD><EFBFBD>ǿ
|
|
|
|
|
for (size_t i = 0; i < validImgUpSampleDeque.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
cv::Mat img;
|
|
|
|
|
validImgUpSampleDeque[i].copyTo(img);
|
|
|
|
|
GNRHP(img, validImgUpSampleDeque[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::deque<cv::Mat> validAdjacentMatDeque(adjacentMatDeque.begin() + location, adjacentMatDeque.begin() + location + maxVal);
|
|
|
|
|
|
|
|
|
|
imgUpSampleDeque.clear();
|
|
|
|
|
adjacentMatDeque.clear();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ں<EFBFBD>
|
|
|
|
|
for (int i = validImgUpSampleDeque.size() - 2; i > -1; i--)
|
|
|
|
|
{
|
|
|
|
|
cv::Mat img_pre = validImgUpSampleDeque[i];
|
|
|
|
|
cv::Mat img_next = validImgUpSampleDeque[i+1];
|
|
|
|
|
|
|
|
|
|
cv::Mat img_preNext;
|
|
|
|
|
img_pre.copyTo(img_preNext);
|
|
|
|
|
|
|
|
|
|
// <20><>֡ͼ<D6A1><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӿ<EFBFBD><D3BE><EFBFBD>
|
|
|
|
|
cv::Mat m_AdjacentMat = validAdjacentMatDeque[i];
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>next <20>滻 pre ͼ<><CDBC>
|
|
|
|
|
double a00 = m_AdjacentMat.at<double>(0, 0);
|
|
|
|
|
double a01 = m_AdjacentMat.at<double>(0, 1);
|
|
|
|
|
double a02 = m_AdjacentMat.at<double>(0, 2);
|
|
|
|
|
double a10 = m_AdjacentMat.at<double>(1, 0);
|
|
|
|
|
double a11 = m_AdjacentMat.at<double>(1, 1);
|
|
|
|
|
double a12 = m_AdjacentMat.at<double>(1, 2);
|
|
|
|
|
double a20 = m_AdjacentMat.at<double>(2, 0);
|
|
|
|
|
double a21 = m_AdjacentMat.at<double>(2, 1);
|
|
|
|
|
double a22 = m_AdjacentMat.at<double>(2, 2);
|
|
|
|
|
|
|
|
|
|
for(int r = 0; r < img_preNext.rows; r++)
|
|
|
|
|
{
|
|
|
|
|
// #pragma omp parallel for
|
|
|
|
|
for (int c = 0; c < img_preNext.cols; c++)
|
|
|
|
|
{
|
|
|
|
|
double denominator = c * a20 + r * a21 + a22;
|
|
|
|
|
double src_x = (c * a00 + r * a01 + a02) / denominator;
|
|
|
|
|
double src_y = (c * a10 + r * a11 + a12) / denominator;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3>ٶȿ<D9B6>
|
|
|
|
|
int x_nearest = int(src_x + 0.5);
|
|
|
|
|
int y_nearest = int(src_y + 0.5);
|
|
|
|
|
|
|
|
|
|
if ( x_nearest >= 0 && y_nearest >= 0 && x_nearest < img_next.cols && y_nearest < img_next.rows)
|
|
|
|
|
{
|
|
|
|
|
img_preNext.at<unsigned char>(r, c) = img_next.at<unsigned char>(y_nearest, x_nearest);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؽ<EFBFBD><D8BD><EFBFBD>
|
|
|
|
|
|
|
|
|
|
// <20>ں<EFBFBD> img_pre <20><> img_preNext
|
|
|
|
|
cv::Mat fusion;
|
|
|
|
|
FuseImg(fusion, img_pre, img_preNext, "sym4", 10);
|
|
|
|
|
|
|
|
|
|
// <20><> fusion <20>滻 validImgUpSampleDeque[i]
|
|
|
|
|
fusion.copyTo(validImgUpSampleDeque[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
validImgUpSampleDeque[0].copyTo(dst);
|
|
|
|
|
|
|
|
|
|
return validImgUpSampleDeque.size();
|
|
|
|
|
}
|
|
|
|
|
}
|