OpenCV python 未显示 python 包装的 Cuda SIFT 关键点转换为 OpenCV 关键点格式

OpenCV python is not displaying python wrapped Cuda SIFT Keypoints converted to OpenCV keypoint format

我们使用 pybind11 围绕 ExtractSift 函数编写了一个小型 python 包装器,它似乎工作正常。

这是它的样子:

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 显示关键点但没有显示任何关键点,我认为这可能是一个 float typecast 问题


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

我找到了解决方案,必须将 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