מדריך לזיהוי שינויים בצילום

קהל

המדריך הזה נועד לעזור לכם להתחיל במהירות לחקור ולפתח אפליקציות באמצעות Video Intelligence API. הוא מיועד לאנשים שמכירים תכנות בסיסי, אבל גם אם אין לכם ידע רב בתכנות, תוכלו להבין את ההסברים. אחרי שתעברו על המדריך הזה, תוכלו להשתמש במסמכי העיון כדי ליצור אפליקציות בסיסיות משלכם.

במדריך הזה נסביר איך ליצור אפליקציה ל-Video Intelligence API באמצעות קוד Python. המטרה כאן היא לא להסביר על ספריות הלקוח של Python, אלא להסביר איך לבצע קריאות ל-Video Intelligence API. אפליקציות ב-Java וב-Node.js דומות במהותן.

אם אתם מחפשים דוגמה של קוד בלבד או דוגמה בשפה אחרת, כדאי לעיין במדריך הנלווה.

דרישות מוקדמות

יש כמה דרישות מוקדמות למדריך הזה:

הוספת הערות לסרטון באמצעות זיהוי שינוי בסצנה

במדריך הזה נסביר איך ליצור אפליקציה בסיסית ל-Video API באמצעות בקשת SHOT_CHANGE_DETECTION. בקשת SHOT_CHANGE_DETECTION מספקת את תוצאות ההערות:

  • רשימה של כל הצילומים שמופיעים בסרטון
  • לכל צילום, מציינים את שעת ההתחלה ושעת הסיום של הצילום

קודם נציג את הקוד המלא. (שימו לב שהסרנו את רוב ההערות מהקוד הזה כדי להראות לכם כמה הוא קצר. נספק הערות נוספות ככל שנתקדם בקוד).

import argparse

from google.cloud import videointelligence



def analyze_shots(path):
    """Detects camera shot changes."""
    video_client = videointelligence.VideoIntelligenceServiceClient()
    features = [videointelligence.Feature.SHOT_CHANGE_DETECTION]
    operation = video_client.annotate_video(
        request={"features": features, "input_uri": path}
    )
    print("\nProcessing video for shot change annotations:")

    result = operation.result(timeout=120)
    print("\nFinished processing.")


    for i, shot in enumerate(result.annotation_results[0].shot_annotations):
        start_time = (
            shot.start_time_offset.seconds + shot.start_time_offset.microseconds / 1e6
        )
        end_time = (
            shot.end_time_offset.seconds + shot.end_time_offset.microseconds / 1e6
        )
        print("\tShot {}: {} to {}".format(i, start_time, end_time))


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
    )
    parser.add_argument("path", help="GCS path for shot change detection.")
    args = parser.parse_args()

    analyze_shots(args.path)

האפליקציה הפשוטה הזו מבצעת את המשימות הבאות:

  • מייבא את הספריות שנדרשות להפעלת האפליקציה.
  • מקבלת קובץ וידאו שמאוחסן ב-URI של Cloud Storage כארגומנט ומעבירה אותו לפונקציה main().
  • מקבל פרטי כניסה להפעלת השירות Video Intelligence API.
  • יוצר בקשה להערה בסרטון כדי לשלוח אותה לשירות הווידאו.
  • הבקשה נשלחת ומוחזרת פעולה ממושכת.
  • הפונקציה מבצעת לולאה על הפעולה ארוכת הטווח עד שהסרטון מעובד ומחזירה את הערכים הזמינים.
  • מנתח את התגובה של השירות ומציג את התגובה למשתמש.

בהמשך נפרט על השלבים האלה.

ייבוא ספריות

import argparse

from google.cloud import videointelligence

אנחנו מייבאים את argparse כדי לאפשר לאפליקציה לקבל שמות של קובצי קלט כארגומנטים.

כדי להשתמש ב-Video Intelligence API, אנחנו מייבאים גם את ספריית google.cloud.videointelligence, שמכילה את הספרייה של קריאות ה-API שלנו ואת קבועי הספירה.

הפעלת האפליקציה

parser = argparse.ArgumentParser(
    description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument("path", help="GCS path for shot change detection.")
args = parser.parse_args()

analyze_shots(args.path)

כאן אנחנו מנתחים את הארגומנט שהועבר ל-URI של Google Cloud Storage של שם קובץ הסרטון ומעבירים אותו לפונקציה main().

אימות ל-API

לפני שמתקשרים עם שירות Video Intelligence API, צריך לאמת את השירות באמצעות פרטי כניסה שהושגו בעבר. בתוך אפליקציה, הדרך הכי פשוטה לקבל פרטי כניסה היא באמצעות Application Default Credentials‏ (ADC). כברירת מחדל, ADC ינסה לקבל פרטי כניסה מקובץ הסביבה GOOGLE_APPLICATION_CREDENTIALS, שצריך להיות מוגדר כך שיצביע על קובץ ה-JSON של מפתח חשבון השירות. (הגדרתם את חשבון השירות והסביבה שלכם לשימוש ב-ADC במדריך לתחילת העבודה. מידע נוסף זמין במאמר הגדרת חשבון שירות).

הרכבת הבקשה

video_client = videointelligence.VideoIntelligenceServiceClient()
features = [videointelligence.Feature.SHOT_CHANGE_DETECTION]
operation = video_client.annotate_video(
    request={"features": features, "input_uri": path}
)

עכשיו ששירות Video Intelligence API מוכן, אפשר ליצור בקשה לשירות הזה. הבקשות ל-Video Intelligence API מסופקות כאובייקטים של JSON. מידע מלא על המבנה הספציפי של בקשה כזו מופיע בהפניית Video Intelligence API.

קטע הקוד הזה מבצע את המשימות הבאות:

  1. יוצר את ה-JSON לבקשת POST ל-method‏ annotate_video().
  2. הפונקציה מחדירה את המיקום של Google Cloud Storage של שם קובץ הווידאו שהועבר לבקשה.
  3. מציין ששיטת annotate צריכה לבצע SHOT_CHANGE_DETECTION.

יצירת הפעולה הממושכת

כשמריצים בקשה ל-Video Intelligence API בפעם הראשונה, לא מקבלים תוצאה מיידית. במקום זאת, מקבלים שם פעולה שמאוחסן בשדה name בתגובה, ואפשר להשתמש בו כדי לבדוק אם יש תוצאות בשלב מאוחר יותר.

העברת השם של הפעולה הזו (שהוא מחרוזת מספרית) אל method‏ operations של Operations Service ב-Video Intelligence API מחזירה את המצב הנוכחי של הפעולה. דוגמה לתגובה:

{
   "response":{
      "@type":"type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoResponse"
   },
   "name":"us-west1.17159971042783089144",
   "metadata":{
      "annotationProgress":[
         {
            "inputUri":"/video/gbikes_dinosaur.mp4",
            "updateTime":"2017-01-27T19:45:54.297807Z",
            "startTime":"2017-01-27T19:45:54.275023Z"
         }
      ],
      "@type":"type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoProgress"
   }
}

שימו לב שהשדה response מכיל כרגע רק את השדה @type, שמציין את סוג התגובה. אחרי שהתוצאות יהיו זמינות, שדה התגובה יכיל תוצאות מהסוג הזה.

בדיקת הפעולה

result = operation.result(timeout=120)
print("\nFinished processing.")

אנחנו משתמשים בבקשת הפעולה הקיימת עבור הפעולה הקיימת שלנו, ויוצרים לולאת while כדי לבדוק מעת לעת את מצב הפעולה. אחרי שהפעולה שלנו מציינת שהפעולה היא done, אנחנו יוצאים מהלולאה ויכולים לנתח את התגובה.

ניתוח התשובה

for i, shot in enumerate(result.annotation_results[0].shot_annotations):
    start_time = (
        shot.start_time_offset.seconds + shot.start_time_offset.microseconds / 1e6
    )
    end_time = (
        shot.end_time_offset.seconds + shot.end_time_offset.microseconds / 1e6
    )
    print("\tShot {}: {} to {}".format(i, start_time, end_time))

אחרי שהפעולה תושלם, התגובה תכיל AnnotateVideoResponse, שמורכבת מרשימה של annotationResults, אחד לכל סרטון שנשלח בבקשה. מכיוון ששלחנו רק סרטון אחד בבקשה, אנחנו לוקחים את shotAnnotations הראשון של התוצאה. אנחנו עוברים על כל ה 'קטעים' בסרטון.

הפעלת האפליקציה שלנו

כדי להפעיל את האפליקציה, פשוט מעבירים לה את ה-URI של Cloud Storage של סרטון:

$ python shotchange.py gs://cloud-samples-data/video/gbikes_dinosaur.mp4
operationId=us-west1.12468772851081463748
Operation us-west1.12468772851081463748 started: 2017-01-30T01:53:45.981043Z
Processing video for shot change annotations:
Finished processing.
  Shot 0: 0.0 to 5.166666
  Shot 1: 5.233333 to 10.066666
  Shot 2: 10.1 to 28.133333
  Shot 3: 28.166666 to 42.766666

כל הכבוד! ביצעתם משימת הערות באמצעות Video Intelligence API.