python - OpenCV python不显示转换为OpenCV关键点格式的python包装的Cuda SIFT关键点
问题描述
我们使用 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 显示关键点,但没有显示关键点,我认为这可能是浮点类型转换问题
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
推荐阅读
- omnet++ - 我们如何在 OMNeT++ 模拟的日志视图中查看完整的历史记录
- reactjs - ag-Grid - 捕获过滤器
- rust - 在无头环境中渲染 Rust 龟
- mongodb - Nuxtjs:对 Mongo 的 Ajax 调用成功,但连续调用并不总是有效
- php - 如果生成 cookie 的处理时间过长,php 脚本是否会挂起并且无法设置 cookie?
- networkx - 在不包含 k 团的 n 个顶点中有效地生成所有可能的无向图
- python - 基于 pandas 条件的每台机器的每日活动计数
- python-3.6 - python mlxtend详尽的特征选择器局部变量'best_subset'在赋值之前引用
- isabelle - 有没有办法命名和引用 Isabelle apply-scripts 中的假设?
- html - 边框底部不显示在图像下方,但显示在同一 div 中的文本下方