我将ORB描述符存储在ElasticSearch向量字段中,然后使用ElasticSearch 8.0+中的新API执行kNN搜索。
# Read the image in via URL and convert to Gray
resp = urllib.request.urlopen(URL)
image = np.asarray(bytearray(resp.read()), dtype="uint8")
image = cv2.imdecode(image, cv2.COLOR_BGR2GRAY)
# Only looking for 16 features since ElasticSearch
# will not let us index a vector larger then 1024
orb = cv2.ORB_create(nfeatures=16)
kp, des = orb.detectAndCompute(image, None)
# Flatten for saving in ElasticSearch
dsc = des.flatten()
# Finally index it in ElasticSearch
这是我对ElasticSearch的映射
mappings: {
dynamic: 'true',
properties: {
image_dense_vector: {
type: 'dense_vector',
dims: 1024,
index: true,
similarity: 'cosine'
}
}
}
最后这是我的搜索查询。
body = {
"field":"image_dense_vector",
"query_vector":dense_vector,
"k":20,
"num_candidates":10000
}
res = self.es.knn_search(index=self.index, knn=body)
数据集由~ 34000条记录组成。
如果传入的图像是精确匹配的,则返回结果。但是,如果图像有一点偏差,返回的结果甚至都不接近准确。
有什么建议吗?
首先,考虑ORB论文。
ORB使用BRIEF描述符。BRIEF发出二进制矢量.
detectAndCompute
可能会给你一个uint8
的数组,但这些字节值不是标量。这些字节仅保存位。