Сопоставление функций Opencv не соответствует правильно для обрезанных изображений разных размеров и изображений, взятых из разных источников?

Я пытаюсь сопоставить два изображения, одно из которых - снимок экрана мобильного экрана, а изображение шаблона - любой значок приложения. Если я сопоставляю исходный код и шаблон, обрезанный из одних и тех же изображений, он идеально совпадает. Но когда я использую значок приложения, обрезанный с другого мобильного экрана, это не соответствует должным образом.

Для сопоставления изображений я работаю над следующим кодом:

int main( int argc, char** argv )
{

Mat objectImg = imread("source.jpg", cv::IMREAD_GRAYSCALE);
Mat sceneImg = imread("note4-3.jpg", cv::IMREAD_GRAYSCALE);

//cv::resize(sceneImg,sceneImg,objectImg.size(),0,0,CV_INTER_CUBIC);

if( !objectImg.data || !sceneImg.data )
{
    printf( " No image data \n " );
    return -1337;
}

std::vector<cv::KeyPoint> objectKeypoints;
std::vector<cv::KeyPoint> sceneKeypoints;
cv::Mat objectDescriptors;
cv::Mat sceneDescriptors;

Ptr<FeatureDetector> detector;
detector = cv::MSER::create();
detector->detect(objectImg, objectKeypoints);
detector->detect(sceneImg, sceneKeypoints);

Ptr<DescriptorExtractor> extractor = cv::ORB::create();
extractor->compute( objectImg, objectKeypoints, objectDescriptors );
extractor->compute( sceneImg, sceneKeypoints, sceneDescriptors );

if(objectDescriptors.type()!=CV_32F) {
objectDescriptors.convertTo(objectDescriptors, CV_32F);
}

if(sceneDescriptors.type()!=CV_32F) {
sceneDescriptors.convertTo(sceneDescriptors, CV_32F);
}

vector< vector<DMatch> > matches;
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce");
matcher->knnMatch( objectDescriptors, sceneDescriptors, matches, 8 );

double max_dist = 0; double min_dist = 100;

//-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < objectDescriptors.rows; i++ )
{ 
    double dist = matches[i][0].distance;
    if( dist < min_dist ) min_dist = dist;
    if( dist > max_dist ) max_dist = dist;
}

std::vector<cv::DMatch> good_matches;

for( int i = 0; i < objectDescriptors.rows; i++ )
{ 
    if( matches[i][0].distance <= max(2*min_dist, 0.02) ) {
        good_matches.push_back( matches[i][0]); 
    }

}

//look whether the match is inside a defined area of the image
//only 25% of maximum of possible distance
/*double tresholdDist = 0.50 * sqrt(double(sceneImg.size().height*sceneImg.size().height + sceneImg.size().width*sceneImg.size().width));

vector< DMatch > good_matches2;
good_matches2.reserve(matches.size());  
for (size_t i = 0; i < matches.size(); ++i)
{ 
    for (int j = 0; j < matches[i].size(); j++)
    {
        Point2f from = objectKeypoints[matches[i][j].queryIdx].pt;
        Point2f to = sceneKeypoints[matches[i][j].trainIdx].pt;

        //calculate local distance for each possible match
        double dist = sqrt((from.x - to.x) * (from.x - to.x) + (from.y - to.y) * (from.y - to.y));

        //save as best match if local distance is in specified area and on same height
        if (dist < tresholdDist && abs(from.y-to.y)<5)
        {
            good_matches2.push_back(matches[i][j]);
            j = matches[i].size();
        }
    }
}*/

Mat allmatchs;
   drawMatches(objectImg,objectKeypoints,sceneImg,sceneKeypoints,good_matches,allmatchs,Scalar::all(-1), Scalar::all(-1),vector<char>(),0);
namedWindow("Matchs" , CV_WINDOW_NORMAL);
imshow( "Matchs",allmatchs);

waitKey(0);

}

[Неверное совпадение при кадрировании из другого источника][1]

Приведенный выше результат получается при сопоставлении источника с одного снимка экрана мобильного устройства и шаблона с другого снимка экрана.

Я использую opencv3.0

Пожалуйста, помогите, если я внес изменения в код или мне нужно использовать сопоставление шаблонов или какой-либо другой метод. Я не могу использовать детекторы SUR, так как у меня нет платных версий из-за конфликтов лицензий ??

Примеры изображений:

Исходное изображение

Шаблон


person Alagiri    schedule 04.01.2016    source источник
comment
как вы можете видеть на своем изображении, источник и цель не содержат одни и те же ключевые точки. Вам придется найти детектор признаков, более надежный для вашего типа изображений. Кроме того, возможно, не так уж и разумно объединять все иконки шаблонов в одно большое изображение, потому что, если ключевые точки обнаруживаются в большом масштабе, дескриптор ключевой точки в одном значке может также включать в себя части соседних значков. Чтобы проанализировать это, вы также должны нарисовать размер / масштаб ключевых точек.   -  person Micka    schedule 04.01.2016
comment
Если ваши ключевые точки вообще не обрабатывают масштаб (я не знаю MSER), дескрипторы, очевидно, не работают для разных размеров источника и цели.   -  person Micka    schedule 04.01.2016
comment
не могли бы вы уточнить то же самое и предоставить подробную информацию о том, где можно изменить изменения @Micka   -  person Alagiri    schedule 04.01.2016
comment
просто попробуйте комбинацию обнаружения/описания инвариантных к масштабу функций, предложенную nbsrujan. Может быть, попробовать SURF в начале. Я знаю, что вы не можете использовать SURF для своего продукта, но если он работает лучше, у вас есть намек на то, что это, скорее всего, проблема вашей комбинации детектор-дескриптор, а не проблема ваших изображений.   -  person Micka    schedule 04.01.2016
comment
Но STAR и BRIEF недоступны в opencv3.0, как я могу их использовать, я пробовал все другие комбинации и должен использовать только opencv 3.0 @Micka   -  person Alagiri    schedule 04.01.2016
comment
это работает с SURF? Вы пробовали ORB как для обнаружения, так и для описания? (Класс, реализующий детектор ключевых точек ORB (ориентированный BRIEF) и экстрактор дескрипторов, описанный в [RRKB11]. Алгоритм использует FAST в пирамидах для обнаружения устойчивых ключевых точек, выбирает самые сильные признаки с помощью FAST или отклика Харриса, находит их ориентацию с использованием моментов первого порядка. и вычисляет дескрипторы, используя BRIEF (где координаты случайных пар точек (или k-кортежей) поворачиваются в соответствии с измеренной ориентацией).)   -  person Micka    schedule 04.01.2016
comment
Я пытался использовать ORB, но по сравнению с комбинацией ORB MSER и ORB дает более точные результаты, но могу ли я изменить параметры инициализации ORB и MSER, пожалуйста, я новичок в opencv, пожалуйста, уточните ответ Заранее спасибо @Micka   -  person Alagiri    schedule 04.01.2016
comment
в таких сложных задачах, как поиск изображений, вы должны попытаться понять, что вы делаете. Одно из предложений: если ваши значки не меняются и у вас есть идеальные изображения (например, скриншоты вместо фотографий), вы, вероятно, лучше справитесь с сопоставлением шаблонов, чем с сопоставлением функций. Попробуйте функцию cv::matchTemplate, и вы должны получить неплохие результаты (если вы можете исключить фон)   -  person Micka    schedule 04.01.2016
comment
Я не использовал SURF из-за проблем с лицензией   -  person Alagiri    schedule 04.01.2016
comment
Нет, сначала мы использовали только сопоставление шаблонов, но оно дает много ложных срабатываний и не является инвариантным к масштабу, поэтому мы пытаемся использовать обнаружение на основе признаков.   -  person Alagiri    schedule 04.01.2016
comment
@Micka, не могли бы вы внести изменения в приведенный выше пример кода для сопоставления изображений такого типа?   -  person Alagiri    schedule 04.01.2016
comment
возможно, если вы предоставите образцы изображений (которые можно использовать в качестве входных данных), но у меня мало времени.   -  person Micka    schedule 04.01.2016
comment
я предоставлю образцы изображений, пожалуйста, попробуйте это   -  person Alagiri    schedule 04.01.2016
comment
У меня есть исходный код и изображение шаблона, не могли бы вы попробовать это?   -  person Alagiri    schedule 04.01.2016
comment
@Micka, вы тестировали код с другими возможными комбинациями ??   -  person Alagiri    schedule 04.01.2016
comment
нет времени, извините, только протестировал matchTemplate в нескольких масштабах, что дает многообещающие результаты.   -  person Micka    schedule 04.01.2016
comment
если я масштабирую изображение шаблона, могу ли я получить совпадения на основе вашего предложения, и нет проблем, спасибо за ваши усилия @Micka   -  person Alagiri    schedule 04.01.2016
comment
@Micka Is GenericDescriptorMatcher удален в opencv3.0   -  person Alagiri    schedule 06.01.2016


Ответы (2)


Глядя на изображение, которое вы предоставили, я могу предложить некоторые изменения, которые помогут вам.

  • Удалите выбор хороших совпадений, это создает проблемы при наличии резких элементов. Острые черты имеют очень меньшую дистанцию ​​хэмминга по сравнению с другими хорошими совпадениями. Когда вы выбираете 2*min_dist , вы косвенно игнорируете возможные хорошие совпадения.
  • Убедитесь, что на изображении объекта имеется разумное количество характерных точек.
  • Если эта комбинация детектора функций и дескриптора не работает, выберите другой детектор функций и дескрипторы, такие как STAR-BRIEF, SURF, которые намного лучше, чем MSER-ORB.
  • В вашей ситуации детектор-сопоставитель не обязательно должен быть инвариантным к вращению, он должен быть инвариантным к масштабу. Поэтому попробуйте изменить размер изображения объекта

Надеюсь, мои предложения помогут вам

person nbsrujan    schedule 04.01.2016
comment
Вместо хороших совпадений, какой лучший способ отфильтровать хорошие совпадения, и я не могу использовать SURF, не могли бы вы предложить какую-то другую комбинацию и как я могу убедиться, что в изображении объекта достаточно точек, а STAR и BRIEF недоступны в opencv 3.0 - person Alagiri; 04.01.2016
comment
У других детекторов @Alagiri есть возможность выбрать нет. функций, которые должны присутствовать в изображении. Таким образом, установка порога будет достаточной. - person nbsrujan; 04.01.2016
comment
не могли бы вы изменить этот код и опубликовать его или написать мне по адресу [email protected], я должен отправить код, не могли бы вы @nbsrujan - person Alagiri; 04.01.2016

Я получил лучшие совпадения с помощью следующих комбинаций: детектор Kaze экстрактор Kaze сопоставитель BruteForce-L1 в сочетании с сопоставлением перекрестной проверки, указанным в следующей ссылке

http://ecee.colorado.edu/~siewerts/extra/ecen5043/ecen5043_code/sift/descriptor_extractor_matcher.cpp

person Alagiri    schedule 08.01.2016