gpt4 book ai didi

python - 有没有办法更快地运行 OpenCV 的 SIFT?

转载 作者:行者123 更新时间:2023-12-02 16:15:56 26 4
gpt4 key购买 nike

我有一个图像目录,其中包含许多未识别的重复项。我的目标是识别重复项。由于重复项已被裁剪、调整大小或转换为不同的图像格式,因此无法通过比较它们的哈希值来检测它们。

我编写了一个成功检测重复项的脚本,但有一个主要缺点:脚本速度很慢。在一个包含 60 个项目的文件夹的测试驱动器上,运行需要五个小时(这也可能反射(reflect)了我越来越多的错误和缓慢的计算机)。由于我的目录中有大约 66,000 张图像,我估计脚本需要 229 天才能完成。

谁能提出解决方案?我的research已经透露,您可以通过在循环完成时“释放”存储在变量中的图像来释放内存,但是有关如何执行此操作的所有信息似乎都是用 C 编写的,而不是 python。我也在考虑尝试使用 orb而不是筛选,但担心其准确性。有没有人对这两种选择中哪一种更适合提出建议?或者重写脚本以减少内存占用的方法?非常感谢。

from __future__ import division

import cv2
import numpy as np
import glob
import pandas as pd


listOfTitles1 = []
listOfTitles2 = []
listOfSimilarities = []

# Sift and Flann
sift = cv2.xfeatures2d.SIFT_create()


index_params = dict(algorithm=0, trees=5)
search_params = dict()
flann = cv2.FlannBasedMatcher(index_params, search_params)

# Load all the images1

countInner = 0
countOuter = 1

folder = r"/Downloads/images/**/*"

for a in glob.iglob(folder,recursive=True):
for b in glob.iglob(folder,recursive=True):

if not a.lower().endswith(('.jpg','.png','.tif','.tiff','.gif')):

continue

if not b.lower().endswith(('.jpg','.png','.tif','.tiff','.gif')):

continue

if b.lower().endswith(('.jpg','.png','.tif','.tiff','.gif')):

countInner += 1

print(countInner, "", countOuter)

if countInner <= countOuter:

continue

image1 = cv2.imread(a)
kp_1, desc_1 = sift.detectAndCompute(image1, None)

image2 = cv2.imread(b)
kp_2, desc_2 = sift.detectAndCompute(image2, None)

matches = flann.knnMatch(desc_1, desc_2, k=2)

good_points = []

if good_points == 0:

continue

for m, n in matches:
if m.distance < 0.6*n.distance:
good_points.append(m)

number_keypoints = 0
if len(kp_1) >= len(kp_2):
number_keypoints = len(kp_1)
else:
number_keypoints = len(kp_2)

percentage_similarity = float(len(good_points)) / number_keypoints * 100

listOfSimilarities.append(str(int(percentage_similarity)))
listOfTitles2.append(b)

listOfTitles1.append(a)

countInner = 0
if a.lower().endswith(('.jpg','.png','.tif','.tiff','.gif')):
countOuter += 1

zippedList = list(zip(listOfTitles1,listOfTitles2, listOfSimilarities))

print(zippedList)

dfObj = pd.DataFrame(zippedList, columns = ['Original', 'Title' , 'Similarity'])

dfObj.to_csv(r"/Downloads/images/DuplicateImages3.csv")

最佳答案

我认为通过简单的更改可以获得显着的性能提升:

  1. 首先,由于您对比较图像对感兴趣,因此您的循环可能如下所示:
files = ... # preload all file names with glob

for a_idx in range(len(files)):
for b_idx in range(a_idx, len(files)): # notice loop here
image_1 = cv2.imread(files[a_idx])
image_2 = cv2.imread(files[b_idx])

这会考虑所有对而不重复,例如(a, b) && (b, a)

  1. 其次,在比较每个 b 时,您不需要重新计算 a 的特征
for a_idx in range(len(files)):
image_1 = cv2.imread(files[a_idx])
kp_1, desc_1 = sift.detectAndCompute(image1, None) # never recoompute SIFT!

for b_idx in range(a_idx, len(files)):
image_2 = cv2.imread(files[b_idx])
kp_2, desc_2 = sift.detectAndCompute(image2, None)
  1. 我还会检查图片尺寸。我的猜测是有一些非常大的东西正在减慢你的内部循环。即使所有 60*60 == 3600 对也不应该花那么长时间。如果图像真的很大,您可以对其进行降采样以提高效率。

关于python - 有没有办法更快地运行 OpenCV 的 SIFT?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62766942/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com