1pip install opencv-python
2pip install transformers==4.57.3
1from transformers import AutoModel, AutoProcessor
2import torch
3
4model = AutoModel.from_pretrained(
5 "VINAY-UMRETHE/SigMamba-V1-Large",
6 trust_remote_code=True
7)
8
9device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
10model = model.to(device)
11model.eval()
12
13processor = AutoProcessor.from_pretrained(model.config.vision_model_id)
Use this when you have raw video files. The model handles feature extraction internally.
1import cv2
2import numpy as np
3
4def load_video_frames(video_path, num_frames=32):
5 """Sample frames uniformly from a video."""
6 cap = cv2.VideoCapture(video_path)
7 total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
8 indices = np.linspace(0, total_frames - 1, num_frames, dtype=int)
9
10 frames = []
11 for idx in indices:
12 cap.set(cv2.CAP_PROP_POS_FRAMES, idx)
13 ret, frame = cap.read()
14 if ret:
15 frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
16 frames.append(frame)
17 cap.release()
18 return frames
19
20frames = load_video_frames("test_video.mp4", num_frames=32)
21inputs = processor(images=frames, return_tensors="pt")
22pixel_values = inputs.pixel_values.to(device)
23
24pixel_values = pixel_values.unsqueeze(0)
25
26# Inference.
27with torch.no_grad():
28 scores = model(pixel_values=pixel_values)
29
30# Get results.
31anomaly_scores = scores.squeeze().cpu().numpy()
32max_score = anomaly_scores.max()
33print(f"Max Anomaly Score: {max_score:.4f}")
Use this when you've already extracted features for Training the model.
1def load_features_from_txt(feature_path):
2 """Load features from text file (one line per segment)."""
3 with open(feature_path, 'r') as f:
4 lines = f.readlines()
5 features = []
6 for line in lines:
7 values = [float(v) for v in line.strip().split()]
8 features.append(values)
9 return torch.tensor(features, dtype=torch.float32)
10
11# Load features.
12features = load_features_from_txt("video_features.txt")
13features = features.unsqueeze(0).to(device)
14
15# Inference.
16with torch.no_grad():
17 scores = model(features=features)
18
19print(f"Anomaly Scores: {scores.squeeze().cpu().numpy()}")
Process multiple videos in a single forward pass for efficiency.
1# Load multiple videos.
2video_paths = ["video1.mp4", "video2.mp4", "video3.mp4"]
3batch_frames = []
4
5for path in video_paths:
6 frames = load_video_frames(path, num_frames=32)
7 inputs = processor(images=frames, return_tensors="pt")
8 batch_frames.append(inputs.pixel_values)
9
10pixel_values = torch.stack(batch_frames).to(device)
11
12with torch.no_grad():
13 scores = model(pixel_values=pixel_values)
14
15for i, path in enumerate(video_paths):
16 max_score = scores[i].max().item()
17 print(f"{path}: {max_score:.4f}")
For individual frames.
1from PIL import Image
2
3# Load single image.
4image = Image.open("suspicious_frame.jpg")
5inputs = processor(images=image, return_tensors="pt")
6pixel_values = inputs.pixel_values.to(device)
7
8pixel_values = pixel_values.unsqueeze(0)
9
10with torch.no_grad():
11 score = model(pixel_values=pixel_values)
12 print(f"Frame Anomaly Score: {score.item():.4f}")
Access the Mamba encoder output directly for custom downstream tasks.
1# Load frames.
2frames = load_video_frames("video.mp4", num_frames=32)
3inputs = processor(images=frames, return_tensors="pt")
4pixel_values = inputs.pixel_values.unsqueeze(0).to(device)
5
6# Access internal components.
7with torch.no_grad():
8 # Step 1: Extract vision features.
9 b, t, c, h, w = pixel_values.shape
10 flat_pixels = pixel_values.view(b * t, c, h, w)
11 vision_features = model.vision_model.get_image_features(pixel_values=flat_pixels)
12 vision_features = vision_features / vision_features.norm(dim=-1, keepdim=True)
13 vision_features = vision_features.view(b, t, -1)
14
15 # Step 2: Get Mamba-encoded features.
16 mamba_features = model.mamba_encoder(vision_features)
17
18 print(f"Vision Features: {vision_features.shape}")
19 print(f"Mamba Features: {mamba_features.shape}")
Apply a threshold to convert scores into binary predictions.
1def detect_anomalies(video_path, threshold=0.5):
2 """Returns list of anomalous segment indices."""
3 frames = load_video_frames(video_path, num_frames=32)
4 inputs = processor(images=frames, return_tensors="pt")
5 pixel_values = inputs.pixel_values.unsqueeze(0).to(device)
6
7 with torch.no_grad():
8 scores = model(pixel_values=pixel_values)
9 scores = scores.squeeze().cpu().numpy()
10
11 anomalous_segments = np.where(scores > threshold)[0]
12
13 return {
14 "scores": scores,
15 "max_score": scores.max(),
16 "is_anomalous": scores.max() > threshold,
17 "anomalous_segments": anomalous_segments.tolist()
18 }
19
20# Inference.
21result = detect_anomalies("test.mp4", threshold=0.5)
22print(f"Anomalous: {result['is_anomalous']}")
23print(f"Segments: {result['anomalous_segments']}")
Copyright © 2026 Vinay Umrethe
umrethevinay@gmail.com.
This model is licensed under the MIT License. See the
LICENSE file for details.