Я думаю, что это связано с ключевыми точками границы.Детектор обнаруживает ключевые точки, но для того чтобы дескриптор SURF возвращал согласованные значения, ему нужны данные пикселей в блоке пикселей вокруг него, который недоступен в граничных пикселях.Вы можете использовать следующий фрагмент кода, чтобы удалить граничные точки после обнаружения ключевых точек, но до вычисления дескрипторов.Я предлагаю использовать borderSize от 20 или более.
removeBorderKeypoints( vector<cv::KeyPoint>& keypoints, const cv::Size imageSize, const boost::int32_t borderSize )
{
if( borderSize > 0)
{
keypoints.erase( remove_if(keypoints.begin(), keypoints.end(),
RoiPredicatePic((float)borderSize, (float)borderSize,
(float)(imageSize.width - borderSize),
(float)(imageSize.height - borderSize))),
keypoints.end() );
}
}
Где RoiPredicatePic реализован как:
struct RoiPredicatePic
{
RoiPredicatePic(float _minX, float _minY, float _maxX, float _maxY)
: minX(_minX), minY(_minY), maxX(_maxX), maxY(_maxY)
{}
bool operator()( const cv::KeyPoint& keyPt) const
{
cv::Point2f pt = keyPt.pt;
return (pt.x < minX) || (pt.x >= maxX) || (pt.y < minY) || (pt.y >= maxY);
}
float minX, minY, maxX, maxY;
};
Кроме того, индексация приблизительного ближайшего соседа не лучший способ сопоставления объектов между парамиизображений.Я бы посоветовал вам попробовать другие более простые совпадения.