Утверждение не удалось во время розыгрыша совпадения ключевых точек BF BRISK+FREAK

Я пытаюсь сшить два изображения, используя BRISK+FREAK

Вот код, когда я пытаюсь нарисовать спички, я получаю сообщение об ошибке

ошибка: OpenCV (4.1.2) /io/opencv/modules/features2d/src/draw.cpp:225: ошибка: (-215: утверждение не удалось) i1 ›= 0 && i1 ‹ static_cast(keypoints1.size()) в функция 'drawMatches'

import cv2
import numpy as np
import matplotlib.pyplot as plt

trainImg = cv2.imread('/content/img1.JPG')
trainImg_gray = cv2.cvtColor(trainImg, cv2.COLOR_BGR2GRAY)

queryImg = cv2.imread('/content/img2.JPG')
queryImg_gray = cv2.cvtColor(queryImg, cv2.COLOR_BGR2GRAY)

def detectAndDescribe(image, method=None):
    """
    Compute key points and feature descriptors using an specific method
    """
    
    descriptor = cv2.BRISK_create()
    # get keypoints and descriptors
    (kps, features) = descriptor.detectAndCompute(image, None)

    freakExtractor = cv2.xfeatures2d.FREAK_create()
    keypoints,descriptors= freakExtractor.compute(image,kps)

    return (keypoints, features)

method = 'brisk'
feature_extractor = 'brisk'
feature_matching = 'bf'
kpsA, featuresA = detectAndDescribe(trainImg_gray, method=feature_extractor)
kpsB, featuresB = detectAndDescribe(queryImg_gray, method=feature_extractor)

"Create and return a Matcher Object"
createMatcher = lambda crossCheck :  cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=crossCheck)

def matchKeyPointsBF(featuresA, featuresB, method):
    bf = createMatcher(crossCheck=True)
        
    # Match descriptors.
    best_matches = bf.match(featuresA,featuresB)
    
    # Sort the features in order of distance.
    # The points with small distance (more similarity) are ordered first in the vector
    rawMatches = sorted(best_matches, key = lambda x:x.distance)
    print("Raw matches (Brute force):", len(rawMatches))
    return rawMatches

print("Using: {} feature matcher".format(feature_matching))

fig = plt.figure(figsize=(20,8))

matches = matchKeyPointsBF(featuresA, featuresB, method=feature_extractor)
img3 = cv2.drawMatches(trainImg,kpsA,queryImg,kpsB,matches,None,flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
    

plt.imshow(img3)
plt.show()

Это полная ошибка, которую я получаю

Использование: bf feature matcher Необработанные совпадения (грубая сила): 1967 ------------------------------------- -------------------------------------- ошибка Traceback (последний последний вызов) в () 4 5 совпадений = matchKeyPointsBF(featuresA, featuresB, method=feature_extractor) ----> 6 img3 = cv2.drawMatches(trainImg,kpsA,queryImg,kpsB,matches,None,flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS) 7 8

ошибка: OpenCV (4.1.2) /io/opencv/modules/features2d/src/draw.cpp:225: ошибка: (-215: утверждение не удалось) i1 ›= 0 && i1 ‹ static_cast(keypoints1.size()) в функция 'drawMatches'

Кажется, я не знаю, что здесь происходит, нашел это OpenCV Sift/Surf/Orb: функция drawMatch работает неправильно не могу понять, как это исправить


person Santhosh Dhaipule Chandrakanth    schedule 17.06.2021    source источник
comment
связанный: форум. opencv.org/t/   -  person Christoph Rackwitz    schedule 17.06.2021
comment
@ChristophRackwitz Да, это я. Лучше опубликовать на обоих, чтобы быстро получить более четкую картину   -  person Santhosh Dhaipule Chandrakanth    schedule 18.06.2021


Ответы (1)


Вы смешиваете keypoints из FREAK с features из BRISK:

Внимательно посмотрите на код detectAndDescribe:

def detectAndDescribe(image, method=None):
    """
    Compute key points and feature descriptors using an specific method
    """
    
    descriptor = cv2.BRISK_create()
    # get keypoints and descriptors
    (kps, features) = descriptor.detectAndCompute(image, None)

    freakExtractor = cv2.xfeatures2d.FREAK_create()
    keypoints,descriptors= freakExtractor.compute(image,kps)

    return (keypoints, features)  # <------ keypoints from freakExtractor.compute and features from descriptor.detectAndCompute

Сообщаемое исключение выглядит случайным, поэтому найти проблему было сложно...


Вы можете реализовать detectAndDescribe следующим образом:

  • Обнаружение ключевых точек с помощью BRISK
  • Передайте обнаруженные ключевые точки FREAK
  • Возвращает вывод freakExtractor.compute

Предлагаемая реализация:

def detectAndDescribe(image, method=None):
    descriptor = cv2.BRISK_create()
    kps = descriptor.detect(image) # kps, features = descriptor.detectAndCompute(image, None)
    freakExtractor = cv2.xfeatures2d.FREAK_create()
    keypoints, descriptors= freakExtractor.compute(image, kps)
    return (keypoints, descriptors)
person Rotem    schedule 17.06.2021
comment
Дескриптор FREAK с Opencv Python в этом сообщении указывается на необходимость отдельной функции дескрипторы BRIEF (Binary Robust Independent Elementary Features), чтобы получить keypoints, который нам нужно передать в FREAK, так как kps должен быть обнаружен, но ваше решение kps, features= freakExtractor.compute(image,kps) выдаст ошибку - person Santhosh Dhaipule Chandrakanth; 18.06.2021
comment
@SanthoshDhaipuleChandrakanth Вы правы (у меня не было ошибки, потому что мой тест так и не достиг FREAK_create части). Я не знаю всех ограничений. Код работает при обнаружении ключевых точек с помощью BRISK и передаче ключевых точек в качестве входных данных для FREAK. Обновил пост, спасибо. - person Rotem; 18.06.2021