Python OpenCV не отображает ключевые точки Cuda SIFT, завернутые в Python, преобразованные в формат ключевых точек OpenCV

Мы написали небольшую оболочку python, используя pybind11 вокруг функции ExtractSift, которая, кажется, работает нормально.

Вот как это выглядит:

std::vector<SiftPoint> extractSIFT(char* filename)
{
    int devNum = 0, imgSet = 0;
    cv::Mat img;
    cv::imread(filename, 0).convertTo(img, CV_32FC1);
    unsigned int w = img.cols;
    unsigned int h = img.rows;

    InitCuda(devNum);
    CudaImage img1;
    img1.Allocate(w, h, iAlignUp(w, 128), false, NULL, (float*)img.data);
    img1.Download();
    
    SiftData siftData1;
    float initBlur = 1.0f;
    float thresh = (imgSet ? 4.5f : 3.0f);
    InitSiftData(siftData1, 32768, true, true); 
    float *memoryTmp = AllocSiftTempMemory(w, h, 5, false);
    ExtractSift(siftData1, img1, 5, initBlur, thresh, 0.0f, false, memoryTmp);
    FreeSiftTempMemory(memoryTmp);
    return std::vector<SiftPoint>(siftData1.h_data, siftData1.h_data + siftData1.numPts);
}

PYBIND11_MODULE(pycusift, m) {
    m.doc() = "SIFT feature extractor with CUDA"; // optional module docstring

    m.def("extractSIFT", &extractSIFT, "function to extract SIFT features from image");
    py::class_<SiftPoint>(m, "SiftPoint")
    .def(py::init<>())
    .def_readwrite("xpos", &SiftPoint::xpos)
    .def_readwrite("ypos", &SiftPoint::ypos)
    .def_readwrite("sharpness", &SiftPoint::sharpness)
    .def_readwrite("edgeness", &SiftPoint::edgeness)
    .def_readwrite("ambiguity", &SiftPoint::ambiguity)
    .def_readwrite("orientation", &SiftPoint::orientation)
    .def_readwrite("score", &SiftPoint::score)
    .def_readwrite("match", &SiftPoint::match)
    .def_readwrite("match_xpos", &SiftPoint::match_xpos)
    .def_readwrite("match_ypos", &SiftPoint::match_ypos)
    .def_readwrite("match_error", &SiftPoint::match_error)
    .def_readwrite("subsampling", &SiftPoint::ypos)
    .def_readwrite("scale", &SiftPoint::scale)
    .def("getempty", &SiftPoint::getempty)
    .def("getdata", &SiftPoint::getdata);
}

Этот тип использования правильно отображает ключевые точки


import pycusift

a = pycusift.extractSIFT("001.tiff")
x = [i.xpos for i in a]
y = [i.ypos for i in a]
import matplotlib.pyplot as plt
import cv2
plt.imshow(cv2.imread("001.tiff"))
plt.scatter(x,y)
plt.show() 

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


def extract_sift_keypoints(impath, kpts):
    im = cv.imread(impath, cv.IMREAD_COLOR)
    kp = cv.KeyPoint()
    kp1 = []
    desc1 = (np.array([k.getdata() for k in kpts], dtype=np.float32))
    

    for k in kpts :
        kp.pt = (k.xpos, k.ypos)
        kp.angle = k.orientation
        kp.size = k.scale
        kp1.append(kp)

    pts = np.array([k.pt for k in kp1], dtype=np.float32)
    ors = np.array([k.angle for k in kp1], dtype=np.float32)
    scs = np.array([k.size for k in kp1], dtype=np.float32) 

    return pts, ors, scs, desc1, im, kp1

if __name__ == '__main__':
    p = argparse.ArgumentParser()

    opt = p.parse_args()
    kpts1 = pycusift.extractSIFT(opt.im1)
    k1, o1, s1, d1, im1, kps1 = extract_sift_keypoints(opt.im1,kpts1)
   
    outimg = np.empty((im1.shape[0], im1.shape[1], 3), dtype=np.uint8)
    cv.drawKeypoints(im1, kps1, outimg)
    cv.imshow("kp", outimg)
    cv.waitKey(0)    

    print(type(kps1[0].pt))
    print(kps1[0].pt)
    print(type(kps1[0].angle))
    print(kps1[0].angle)
    bf = cv.BFMatcher()
    matches = bf.knnMatch(d1,d2, k=2)

Я должен отметить, что сопоставление дескриптора knn, как я думаю, работает, поскольку оно генерирует совпадения

Вот вывод операторов печати:

‹класс 'кортеж'›

(431.0779724121094, 982.3478393554688)

‹класс 'поплавок'›

224.15390014648438


person Brothers on the Road    schedule 08.09.2020    source источник


Ответы (1)


Я нашел решение, пришлось поставить kp = cv.keypoint() внутри цикла for:

def extract_sift_keypoints(impath, kpts):
    im = cv.imread(impath, cv.IMREAD_COLOR)
    kp1 = []
    desc1 = (np.array([k.getdata() for k in kpts], dtype=np.float32))
    

    for k in kpts :
        kp = cv.KeyPoint()
        kp.pt = (k.xpos, k.ypos)
        kp.angle = k.orientation
        kp.size = k.scale
        kp1.append(kp)

    pts = np.array([k.pt for k in kp1], dtype=np.float32)
    ors = np.array([k.angle for k in kp1], dtype=np.float32)
    scs = np.array([k.size for k in kp1], dtype=np.float32) 

    return pts, ors, scs, desc1, im, kp1
person Brothers on the Road    schedule 11.09.2020