mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-19 21:52:21 +03:00
114 lines
4.5 KiB
Python
114 lines
4.5 KiB
Python
#!/usr/bin/env python3
|
|
import os
|
|
import glob
|
|
import json
|
|
import time
|
|
import vertexai
|
|
from vertexai.generative_models import GenerativeModel, Part
|
|
|
|
# Config
|
|
PROJECT_ID = "project-f91a723f-af1b-4dd2-ba3"
|
|
REGION = "europe-west3"
|
|
CLIPS_DIR = "/Users/work/Documents/showreel/casino_clips"
|
|
REPORT_PATH = "/Users/work/.gemini/antigravity-cli/brain/d378ad95-fd02-43ed-a491-c96e0078dc8a/film_critic_report.md"
|
|
|
|
os.environ["GOOGLE_CLOUD_PROJECT"] = PROJECT_ID
|
|
os.environ["GOOGLE_CLOUD_REGION"] = REGION
|
|
|
|
def main():
|
|
print("Initializing Vertex AI...")
|
|
vertexai.init(project=PROJECT_ID, location=REGION)
|
|
model = GenerativeModel("gemini-2.5-flash")
|
|
|
|
clips = sorted(glob.glob(os.path.join(CLIPS_DIR, "*.mp4")))
|
|
if not clips:
|
|
print("No clips found.")
|
|
return
|
|
|
|
print(f"Found {len(clips)} clips for evaluation.")
|
|
|
|
prompt = """
|
|
You are an expert Film Critic and Quality Assurance AI.
|
|
Evaluate the provided generated video based on the following criteria. Score each from 1 to 5.
|
|
|
|
1. color_match: Does it look like a cohesive cinematic grade?
|
|
2. composition: Is the framing cinematic and aesthetically pleasing?
|
|
3. motion_quality: Is the motion fluid and free of AI morphing artifacts?
|
|
4. grain_match: Does it have a natural texture without excessive digital noise?
|
|
5. palette_artifact: CRITICAL RULE. Look at the frame carefully. Are there explicit color palette boxes, hex code text, or color swatches painted/generated directly inside the video? If yes, score 1. If no, score 5.
|
|
|
|
Return EXACTLY valid JSON in this format:
|
|
{"scores": {"color_match": 4, "composition": 5, "motion_quality": 4, "grain_match": 5, "palette_artifact": 5}, "reasoning": "Short explanation"}
|
|
"""
|
|
|
|
results = []
|
|
|
|
for clip in clips:
|
|
filename = os.path.basename(clip)
|
|
print(f"\nEvaluating {filename}...")
|
|
|
|
try:
|
|
with open(clip, "rb") as f:
|
|
video_bytes = f.read()
|
|
|
|
video_part = Part.from_data(data=video_bytes, mime_type="video/mp4")
|
|
|
|
response = model.generate_content(
|
|
[video_part, prompt],
|
|
generation_config={
|
|
"temperature": 0.1,
|
|
"response_mime_type": "application/json"
|
|
}
|
|
)
|
|
|
|
resp_text = response.text.strip()
|
|
# Handle potential markdown wrappers
|
|
if resp_text.startswith("```json"):
|
|
resp_text = resp_text[7:-3]
|
|
|
|
data = json.loads(resp_text)
|
|
scores = data.get("scores", {})
|
|
|
|
avg_score = sum(scores.values()) / max(len(scores), 1)
|
|
|
|
# If palette_artifact is < 5, it automatically fails the clip by capping the avg_score artificially low
|
|
if scores.get("palette_artifact", 5) < 5:
|
|
avg_score = 1.0
|
|
data["reasoning"] = "FAILED: Color palette artifact detected in frame! " + data.get("reasoning", "")
|
|
|
|
data["filename"] = filename
|
|
data["average"] = avg_score
|
|
data["passed"] = avg_score >= 4.0
|
|
|
|
results.append(data)
|
|
print(f" -> Score: {avg_score:.2f}/5.0 | Passed: {data['passed']} | {data.get('reasoning')}")
|
|
|
|
except Exception as e:
|
|
print(f" -> Error analyzing {filename}: {e}")
|
|
results.append({
|
|
"filename": filename,
|
|
"scores": {"color_match": 0, "composition": 0, "motion_quality": 0, "grain_match": 0, "palette_artifact": 0},
|
|
"average": 0.0,
|
|
"passed": False,
|
|
"reasoning": f"Error: {e}"
|
|
})
|
|
|
|
# Small delay to avoid API rate limits
|
|
time.sleep(2)
|
|
|
|
# Generate Markdown Report
|
|
with open(REPORT_PATH, "w") as f:
|
|
f.write("# Film Critic Evaluation Report\\n\\n")
|
|
f.write("| Clip | Average Score | Palette Artifact? | Passed? | Reasoning |\\n")
|
|
f.write("|---|---|---|---|---|\\n")
|
|
for res in results:
|
|
pal_score = res.get("scores", {}).get("palette_artifact", 0)
|
|
pal_warn = "🚨 YES" if pal_score < 5 else "✅ NO"
|
|
passed_emoji = "✅ Pass" if res["passed"] else "❌ Fail"
|
|
f.write(f"| {res['filename']} | {res['average']:.2f} | {pal_warn} | {passed_emoji} | {res.get('reasoning')} |\\n")
|
|
|
|
print(f"\\nEvaluation complete! Report saved to {REPORT_PATH}")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|