Семантический поиск видео
Я пытаюсь расширить функциональность CLIP OpenAI для семантического поиска видео. По сути, моя цель — ввести текстовый запрос и получить соответствующие видеофрагменты/клипы, соответствующие семантическому содержанию текстового запроса. Вот что я подумал до сих пор:
- Извлекайте кадры из видео через определенные промежутки времени.
- Используйте CLIP для создания вложений этих кадров и текстового запроса.
- Сравните внедренные текстовые запросы с внедренными видеокадрами, чтобы найти совпадения.
Однако этот подход кажется довольно наивным, и я считаю, что он может не эффективно улавливать контекст видео из-за потери временной информации.
Может ли кто-нибудь поделиться советом по улучшению этого подхода? Есть ли более эффективный способ реализации семантического поиска видео с помощью CLIP OpenAI? Кроме того, меня интересуют любые шаги предварительной обработки, возможные стратегии оптимизации или библиотеки, которые могут быть полезны для этой задачи.
Любая помощь или руководство будут очень признательны. Спасибо!
1 ответ
Вот упрощенный шаг за шагом:
Разбейте видео на интервалы в 1 секунду.
Чтобы разделить видео на куски по 1 секунде, вы обычно используете такую библиотеку, как
moviepy
илиopencv
.import cv2 video = cv2.VideoCapture('your_video.mp4') fps = video.get(cv2.CAP_PROP_FPS) frames = [] while(video.isOpened()): ret, frame = video.read() if ret: frames.append(frame) else: break video.release() cv2.destroyAllWindows() # Now chunk into 1-second intervals chunks = [frames[i:i+int(fps)] for i in range(0, len(frames), int(fps))]
Генерация вложений
Для каждого 1-секундного фрагмента генерируется серия изображений, а встраивания рассчитываются с использованием модели OpenAI CLIP.
import torch import clip model, preprocess = clip.load('ViT-B/32') for chunk in chunks: # For each frame in the chunk, preprocess and convert to tensor images = [torch.unsqueeze(preprocess(frame), 0) for frame in chunk] # Stack all tensors together images_input = torch.cat(images, 0) # Generate the embedding with torch.no_grad(): image_features = model.encode_image(images_input)
Выполнение поиска
Вы можете использовать косинусное сходство:
# Calculate cosine similarity between the corpus of vectors and the query vector
scores = util.cos_sim(query_vector, corpus_vector)[0].cpu().tolist()
# Combine docs & scores
doc_score_pairs = list(zip(docs, scores))
# Sort by decreasing score
doc_score_pairs = sorted(doc_score_pairs, key=lambda x: x[1], reverse=True)
# Output passages & scores
for doc, score in doc_score_pairs:
print(score, doc)
Однако проблема с этим подходом заключается в том, что интервалы в 1 секунду рассматриваются как серия кадров, которые не отражают контекст видео. К ним следует относиться как к движущимся изображениям.
Mixpeek предлагает API управляемого поиска, который делает следующее:
GET: https://api.mixpeek.com/v1/search?q=people+experiencing+joy
Ответ:
[
{
"content_id": "6452f04d4c0c0888bdc6b97c",
"metadata": {
"file_ext": "mp4",
"file_id": "ebc289d7-44e1-4672-bf3c-ccfa490b7k2d",
"file_url": "https://mixpeek.s3.amazonaws.com/<user>/<file>.mp4",
"filename": "CR-9146f0.mp4",
},
"score": 0.636489987373352,
"timestamps": [
2.5035398230088495,
1.2517699115044247,
3.755309734513274
]
}
]
Дальнейшее чтение и демонстрация: https://learn.mixpeek.com/what-is-semantic-video-search/