我正在用其他视频中的帧替换视频的某些部分。我希望所选的替换帧尽可能与原始帧相似。
我使用这个函数来寻找最接近该部分的帧:
import functools
import cv2
@functools.cache
def closest_frame(frame, frames):
return min(
frames, key=lambda x: cv2.norm(frame, x, cv2.NORM_L2)
)
这是一个昂贵的计算,因为帧非常长。所以我添加了functools缓存。但是,OpenCV帧不能像这样缓存:unhashable type: 'numpy.ndarray'
我该怎么解决这个问题?
1条答案
按热度按时间gjmwrych1#
若要明确回答“如何让ndarray成为可杂凑的”问题:将ndarray中的每个数组(包括最外层的)转换为元组。由于这些元组是不可变的,因此结果将是可哈希的。您可以简单地使用以下代码:
hash_frame = tuple(tuple(sub) for sub in frame)
,然后在函数中返回此值。但是,只有当您使用的查询帧在第一个视频中重复时,这才能解决您的问题,因为这些帧将被散列。
在这种情况下,散列的工作方式应该是:我有一个散列函数,它可以为正在访问的数据集中的所有图像生成关键字,基于一些函数,使用这些函数,你可以客观地确定两个图像的“相似”程度。对正在使用的查询图像也这样做。然后,这些散列值可以进行比较,从而给予“最接近”的图像。
给定查询图像,从图像集合中快速找到“最相似”图像的问题可以以两种方式解决:
1.使用适当的散列函数来生成给定特定数据点(图像)的有用键。这里可以有两种类型:first,当每个图像都可以用来创建一个唯一的键,在这种情况下,当我们查询时,我们会首先使用与我们的查询相同的函数,得到一个键值,然后使用一种高效的方法该高速缓存中找到相同/最近的键(例如:另一种情况可能是当数据集中的不同图像使用哈希函数产生相同的键时。在这种情况下,当我们查询时,我们将能够在
O(1)
时间内找到最相似图像的“批次”。然后可以进一步查询这一小批图像,以在摊余常数时间内找到最合适的图像。1.首先使用类似KD-Tree的方法为第二个视频中的所有帧创建一个层次结构配置(花费
O(nlog(n))
时间),然后每次使用您的每个查询帧查询树。在最坏的情况下,每帧查询将花费O(log(n))
时间。在这两种方法中,您都必须决定使用什么方法来量化图像,在某种基础上,以便可以创建哈希Map或树。
基于算法的用于为每个图像创建有用的且可散列的表示的一些流行函数可以是:LBP、HOG、颜色直方图、SIFT等。您甚至可以使用预先训练的CNN从每个图像中获得特征表示。
你可以查找Python的KD-Tree实现库,比如scikit-learn。
干杯干杯干杯