【发布时间】:2018-06-08 12:04:21
【问题描述】:
我有包含短视频的文件夹和包含图片的文件夹。大多数图像是其中一个视频的截图,但它们可能并不完全相同(不同的大小、噪声、由于压缩导致的细节丢失等)。我的目标是将每张图片与从中获取的视频进行匹配。到目前为止,我使用 OpenCV 库加载一个视频并计算每个视频帧和每个图像之间的 SSIM 分数。我存储每张图像的最高 SSIM 分数。然后我会获取 SSIM 得分最高的图像,将其与视频相关联,然后再次为第二个视频运行该函数。
这是我的代码:
import cv2
import numpy as np
from skimage.measure import compare_ssim
import sqlite3
#screenshots - list that contains dict(id=screenshot id, image=jpeg image data)
#video_file - str - path to video file
def generate_matches(screenshots, video_file):
for screenshot in screenshots:
screenshot["cv_img"] = cv2.imdecode(np.fromstring(screenshot["image"], np.uint8), 0)
screenshot["best_match"] = dict(score=0, frame=0)
screenshot.pop('image', None) #remove jpg data from RAM
vidcap = cv2.VideoCapture(video_file)
success,image = vidcap.read()
count = 1
while success:
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
for screenshot in screenshots:
c_image = cv2.resize(image, screenshot["cv_img"].shape[1::-1])
score = compare_ssim(screenshot["cv_img"], c_image, full=False)
if score > screenshot["best_match"]["score"]:
screenshot["best_match"] = dict(score=score,frame=count)
count += 1
success,image = vidcap.read()
if count % 500 == 0:
print("Frame {}".format(count))
print("Last Frame {}".format(count))
for screenshot in screenshots:
c.execute("INSERT INTO matches(screenshot_id, file, match, frame) VALUE (?,?,?,?)",
(screenshot["id"], video_file, screenshot["best_match"]["score"], screenshot["best_match"]["frame"]))
generate_matches(list_of_screenshots, "video1.mp4")
generate_matches(list_of_screenshots, "video2.mp4")
...
这个算法似乎很好 - 可以将视频与图像关联起来,但它很慢,即使我会使用更多线程。有没有办法让它更快?也许不同的算法或视频和图像的一些预处理?我会很高兴有任何想法!
【问题讨论】:
-
与其在每个屏幕截图中调整每个视频的每一帧的大小,不如调整屏幕截图的大小以匹配视频的大小不是更有意义吗?
-
@DanMašek 也许,我会试试。屏幕截图的分辨率低于视频帧,所以我认为使用较小的分辨率会使 SSIM 的计算速度更快。
-
为什么不使用任何感知散列(例如 img -> 128 位),然后使用高效的 kd-trees / ball-trees 或类似的进行搜索/查找?
-
@DanMašek 我使用列表中的 10 个屏幕截图对其进行了测试,调整每一帧的大小比将屏幕截图调整为视频分辨率快约 5 倍。 (屏幕截图分辨率 - 224x450,视频分辨率 - 720x1280)
-
@sascha 哇,我不知道这些哈希值存在,我真的很喜欢它的工作方式。我会测试它tommorov,看看它是否能给我带来好的结果。 OpenCV 的 pHash 适合这个任务吗?
标签: python opencv image-processing video video-processing