استخدام Video Intelligence API مع Python

1. نظرة عامة

cfaa6ffa7bc5ca70.png

تمكّنك Video Intelligence API من استخدام تكنولوجيا تحليل الفيديو من Google كجزء من تطبيقاتك.

سوف تركز في هذا التمرين المعملي على استخدام Video Intelligence API مع Python.

المعلومات التي ستطّلع عليها

  • كيفية إعداد البيئة
  • كيفية إعداد Python
  • كيفية رصد التغييرات في اللقطات
  • كيفية اكتشاف التصنيفات
  • كيفية رصد المحتوى الفاضح
  • كيفية تحويل الصوت إلى نص
  • كيفية رصد النص وتتبُّعه
  • كيفية رصد العناصر وتتبُّعها
  • كيفية رصد الشعارات وتتبُّعها

المتطلبات

  • مشروع على Google Cloud
  • متصفح، مثل Chrome أو Firefox
  • الإلمام باستخدام بايثون

استطلاع

كيف ستستخدم هذا البرنامج التعليمي؟

القراءة فقط اقرأها وأكمِل التمارين

كيف تقيّم تجربتك مع Python؟

حديث متوسط بارع

كيف تقيّم تجربتك مع خدمات Google Cloud؟

حديث متوسط بارع

2. الإعداد والمتطلبات

إعداد بيئة ذاتية

  1. سجِّل الدخول إلى Google Cloud Console وأنشئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة أحرف لا تستخدمها Google APIs. ويمكنك تعديلها في أي وقت.
  • يكون رقم تعريف المشروع فريدًا في جميع مشاريع Google Cloud وغير قابل للتغيير (لا يمكن تغييره بعد تحديده). تنشئ Cloud Console سلسلة فريدة تلقائيًا. فعادةً لا تهتم بما هو. في معظم الدروس التطبيقية حول الترميز، يجب الإشارة إلى رقم تعريف المشروع (الذي يتم تحديده عادةً على أنّه PROJECT_ID). وإذا لم يعجبك رقم التعريف الذي تم إنشاؤه، يمكنك إنشاء رقم تعريف عشوائي آخر. ويمكنك بدلاً من ذلك تجربة طلبك الخاص ومعرفة ما إذا كان متاحًا. ولا يمكن تغييره بعد هذه الخطوة ويبقى طوال مدة المشروع.
  • لمعلوماتك، هناك قيمة ثالثة، وهي رقم المشروع، الذي تستخدمه بعض واجهات برمجة التطبيقات. اطّلِع على مزيد من المعلومات حول هذه القيم الثلاث في المستندات.
  1. بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام الموارد/واجهات برمجة التطبيقات في Cloud. لن يؤدي إكمال هذا الدرس التطبيقي حول الترميز إلى فرض أي تكاليف، إن وُجدت. لإيقاف تشغيل الموارد لتجنب تحمُّل الفواتير إلى ما هو أبعد من هذا البرنامج التعليمي، يمكنك حذف الموارد التي أنشأتها أو حذف المشروع. يكون مستخدمو Google Cloud الجدد مؤهَّلون للانضمام إلى برنامج فترة تجريبية مجانية بقيمة 300 دولار أمريكي.

بدء Cloud Shell

يمكنك إدارة Google Cloud عن بُعد من الكمبيوتر المحمول، إلا أنّك ستستخدم في هذا الدرس التطبيقي Cloud Shell، وهي بيئة سطر أوامر يتم تشغيلها في السحابة الإلكترونية.

تفعيل Cloud Shell

  1. من Cloud Console، انقر على تفعيل Cloud Shell 853e55310c205094.png.

55efc1aaa7a4d3ad.png

إذا كانت هذه هي المرة الأولى التي تبدأ فيها Cloud Shell، ستظهر لك شاشة وسيطة تصف ماهيتها. إذا ظهرت لك شاشة وسيطة، انقر على متابعة.

9c92662c6a846a5c.png

من المفترَض أن تستغرق عملية إدارة الحسابات والاتصال بخدمة Cloud Shell بضع دقائق فقط.

9f0e51b578fecce5.png

يتم تحميل هذا الجهاز الافتراضي مع جميع أدوات التطوير اللازمة. وتوفّر هذه الشبكة دليلاً رئيسيًا دائمًا بسعة 5 غيغابايت ويتم تشغيله في Google Cloud، ما يحسّن بشكل كبير من أداء الشبكة والمصادقة. يمكنك تنفيذ معظم عملك، إن لم يكن كلّه، في هذا الدرس التطبيقي حول الترميز باستخدام متصفّح.

بعد الربط بخدمة Cloud Shell، من المفترض أن تتأكّد من أنّه تمّت مصادقتك وأنّ المشروع مضبوط على رقم تعريف مشروعك.

  1. شغِّل الأمر التالي في Cloud Shell لتأكيد مصادقتك:
gcloud auth list

مخرجات الأمر

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. شغّل الأمر التالي في Cloud Shell للتأكد من معرفة الأمر gcloud بمشروعك:
gcloud config list project

مخرجات الأمر

[core]
project = <PROJECT_ID>

إذا لم يكن كذلك، يمكنك تعيينه من خلال هذا الأمر:

gcloud config set project <PROJECT_ID>

مخرجات الأمر

Updated property [core/project].

3- إعداد البيئة

قبل أن تبدأ في استخدام واجهة برمجة التطبيقات Video Intelligence API، يمكنك تشغيل الأمر التالي في Cloud Shell لتفعيل واجهة برمجة التطبيقات:

gcloud services enable videointelligence.googleapis.com

ينبغي أن تظهر لك على النحو التالي:

Operation "operations/..." finished successfully.

يمكنك الآن استخدام Video Intelligence API

انتقِل إلى الدليل الرئيسي:

cd ~

أنشئ بيئة بايثون افتراضية لعزل التبعيات:

virtualenv venv-videointel

تفعيل البيئة الافتراضية:

source venv-videointel/bin/activate

تثبيت IPython ومكتبة برامج واجهة برمجة التطبيقات Video Intelligence API:

pip install ipython google-cloud-videointelligence

ينبغي أن تظهر لك على النحو التالي:

...
Installing collected packages: ..., ipython, google-cloud-videointelligence
Successfully installed ... google-cloud-videointelligence-2.11.0 ...

أصبحت الآن جاهزًا لاستخدام مكتبة برامج واجهة برمجة التطبيقات Video Intelligence API.

في الخطوات التالية، ستستخدم مترجمًا تفاعليًا بلغة Python يُسمى IPython، وقد تم تثبيته في الخطوة السابقة. يمكنك بدء جلسة من خلال تشغيل ipython في Cloud Shell:

ipython

ينبغي أن تظهر لك على النحو التالي:

Python 3.9.2 (default, Feb 28 2021, 17:03:44)
Type 'copyright', 'credits' or 'license' for more information
IPython 8.12.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]:

4. فيديو نموذجي

يمكنك استخدام Video Intelligence API لإضافة تعليقات توضيحية إلى الفيديوهات المخزَّنة في Cloud Storage أو المقدَّمة على هيئة وحدات بايت للبيانات.

ستستخدم في الخطوات التالية نموذجًا لفيديو مخزَّن في Cloud Storage. يمكنك مشاهدة الفيديو في المتصفّح.

afe058b29c480d42.png

جاهز، بثبات، اذهب!

5- رصد التغييرات في اللقطات

يمكنك استخدام Video Intelligence API لرصد التغييرات التي طرأت على اللقطات في فيديو معيّن. اللقطة هي جزء من الفيديو وهي عبارة عن سلسلة من اللقطات التي لا تتوقّف عن رؤية المحتوى.

انسخ الرمز التالي إلى جلسة IPython:

from typing import cast

from google.cloud import videointelligence_v1 as vi


def detect_shot_changes(video_uri: str) -> vi.VideoAnnotationResults:
    video_client = vi.VideoIntelligenceServiceClient()
    features = [vi.Feature.SHOT_CHANGE_DETECTION]
    request = vi.AnnotateVideoRequest(input_uri=video_uri, features=features)

    print(f'Processing video: "{video_uri}"...')
    operation = video_client.annotate_video(request)

    # Wait for operation to complete
    response = cast(vi.AnnotateVideoResponse, operation.result())
    # A single video is processed
    results = response.annotation_results[0]

    return results
    

خصِّص بعض الوقت لدراسة الرمز البرمجي ومعرفة كيفية استخدامه لطريقة مكتبة برامج annotate_video مع المَعلمة SHOT_CHANGE_DETECTION لتحليل فيديو ورصد التغييرات في اللقطات.

استدعِ الدالة لتحليل الفيديو:

video_uri = "gs://cloud-samples-data/video/JaneGoodall.mp4"

results = detect_shot_changes(video_uri)

الانتظار حتى تتم معالجة الفيديو:

Processing video: "gs://cloud-samples-data/video/JaneGoodall.mp4"...

أضف هذه الدالة لطباعة لقطات الفيديو:

def print_video_shots(results: vi.VideoAnnotationResults):
    shots = results.shot_annotations
    print(f" Video shots: {len(shots)} ".center(40, "-"))
    for i, shot in enumerate(shots):
        t1 = shot.start_time_offset.total_seconds()
        t2 = shot.end_time_offset.total_seconds()
        print(f"{i+1:>3} | {t1:7.3f} | {t2:7.3f}")
        

استدعِ الدالة:

print_video_shots(results)

ينبغي أن تظهر لك على النحو التالي:

----------- Video shots: 34 ------------
  1 |   0.000 |  12.880
  2 |  12.920 |  21.680
  3 |  21.720 |  27.880
...
 32 | 135.160 | 138.320
 33 | 138.360 | 146.200
 34 | 146.240 | 162.520

إذا قمت باستخراج الإطار الأوسط لكل لقطة وترتيبها في حائط من الإطارات، يمكنك إنشاء ملخص مرئي للفيديو:

25bbffa59f7ed71d.png

ملخّص

في هذه الخطوة، أصبح بإمكانك رصد تغيير اللقطات في فيديو باستخدام Video Intelligence API. يمكنك قراءة المزيد عن رصد التغييرات في اللقطات.

6- رصد التصنيفات

يمكنك استخدام Video Intelligence API لرصد التصنيفات في فيديو. تصف التصنيفات الفيديو استنادًا إلى محتواه المرئي.

انسخ الرمز التالي إلى جلسة IPython:

from datetime import timedelta
from typing import Optional, Sequence, cast

from google.cloud import videointelligence_v1 as vi


def detect_labels(
    video_uri: str,
    mode: vi.LabelDetectionMode,
    segments: Optional[Sequence[vi.VideoSegment]] = None,
) -> vi.VideoAnnotationResults:
    video_client = vi.VideoIntelligenceServiceClient()
    features = [vi.Feature.LABEL_DETECTION]
    config = vi.LabelDetectionConfig(label_detection_mode=mode)
    context = vi.VideoContext(segments=segments, label_detection_config=config)
    request = vi.AnnotateVideoRequest(
        input_uri=video_uri,
        features=features,
        video_context=context,
    )

    print(f'Processing video "{video_uri}"...')
    operation = video_client.annotate_video(request)

    # Wait for operation to complete
    response = cast(vi.AnnotateVideoResponse, operation.result())
    # A single video is processed
    results = response.annotation_results[0]

    return results
    

خصِّص بعض الوقت لدراسة الرمز البرمجي ومعرفة كيفية استخدامه لطريقة مكتبة برامج annotate_video مع المَعلمة LABEL_DETECTION لتحليل فيديو واكتشاف التصنيفات.

استدعِ الدالة لتحليل أول 37 ثانية من الفيديو:

video_uri = "gs://cloud-samples-data/video/JaneGoodall.mp4"
mode = vi.LabelDetectionMode.SHOT_MODE
segment = vi.VideoSegment(
    start_time_offset=timedelta(seconds=0),
    end_time_offset=timedelta(seconds=37),
)

results = detect_labels(video_uri, mode, [segment])

الانتظار حتى تتم معالجة الفيديو:

Processing video: "gs://cloud-samples-data/video/JaneGoodall.mp4"...

أضِف هذه الدالة لطباعة التصنيفات على مستوى الفيديو:

def print_video_labels(results: vi.VideoAnnotationResults):
    labels = sorted_by_first_segment_confidence(results.segment_label_annotations)

    print(f" Video labels: {len(labels)} ".center(80, "-"))
    for label in labels:
        categories = category_entities_to_str(label.category_entities)
        for segment in label.segments:
            confidence = segment.confidence
            t1 = segment.segment.start_time_offset.total_seconds()
            t2 = segment.segment.end_time_offset.total_seconds()
            print(
                f"{confidence:4.0%}",
                f"{t1:7.3f}",
                f"{t2:7.3f}",
                f"{label.entity.description}{categories}",
                sep=" | ",
            )


def sorted_by_first_segment_confidence(
    labels: Sequence[vi.LabelAnnotation],
) -> Sequence[vi.LabelAnnotation]:
    def first_segment_confidence(label: vi.LabelAnnotation) -> float:
        return label.segments[0].confidence

    return sorted(labels, key=first_segment_confidence, reverse=True)


def category_entities_to_str(category_entities: Sequence[vi.Entity]) -> str:
    if not category_entities:
        return ""
    entities = ", ".join([e.description for e in category_entities])
    return f" ({entities})"
    

استدعِ الدالة:

print_video_labels(results)

ينبغي أن تظهر لك على النحو التالي:

------------------------------- Video labels: 10 -------------------------------
 96% |   0.000 |  36.960 | nature
 74% |   0.000 |  36.960 | vegetation
 59% |   0.000 |  36.960 | tree (plant)
 56% |   0.000 |  36.960 | forest (geographical feature)
 49% |   0.000 |  36.960 | leaf (plant)
 43% |   0.000 |  36.960 | flora (plant)
 38% |   0.000 |  36.960 | nature reserve (geographical feature)
 38% |   0.000 |  36.960 | woodland (forest)
 35% |   0.000 |  36.960 | water resources (water)
 32% |   0.000 |  36.960 | sunlight (light)

بفضل هذه التصنيفات على مستوى الفيديو، يمكنكم فهم أنّ بداية الفيديو تدور حول الطبيعة والنباتات.

أضف هذه الدالة لطباعة التسميات على مستوى اللقطة:

def print_shot_labels(results: vi.VideoAnnotationResults):
    labels = sorted_by_first_segment_start_and_confidence(
        results.shot_label_annotations
    )

    print(f" Shot labels: {len(labels)} ".center(80, "-"))
    for label in labels:
        categories = category_entities_to_str(label.category_entities)
        print(f"{label.entity.description}{categories}")
        for segment in label.segments:
            confidence = segment.confidence
            t1 = segment.segment.start_time_offset.total_seconds()
            t2 = segment.segment.end_time_offset.total_seconds()
            print(f"{confidence:4.0%} | {t1:7.3f} | {t2:7.3f}")


def sorted_by_first_segment_start_and_confidence(
    labels: Sequence[vi.LabelAnnotation],
) -> Sequence[vi.LabelAnnotation]:
    def first_segment_start_and_confidence(label: vi.LabelAnnotation):
        first_segment = label.segments[0]
        ms = first_segment.segment.start_time_offset.total_seconds()
        return (ms, -first_segment.confidence)

    return sorted(labels, key=first_segment_start_and_confidence)
    

استدعِ الدالة:

print_shot_labels(results)

ينبغي أن تظهر لك على النحو التالي:

------------------------------- Shot labels: 29 --------------------------------
planet (astronomical object)
 83% |   0.000 |  12.880
earth (planet)
 53% |   0.000 |  12.880
water resources (water)
 43% |   0.000 |  12.880
aerial photography (photography)
 43% |   0.000 |  12.880
vegetation
 32% |   0.000 |  12.880
 92% |  12.920 |  21.680
 83% |  21.720 |  27.880
 77% |  27.920 |  31.800
 76% |  31.840 |  34.720
...
butterfly (insect, animal)
 84% |  34.760 |  36.960
...

بفضل هذه التصنيفات على مستوى اللقطات، يمكنك فهم أنّ الفيديو يبدأ بلقطة لكوكب (من المرجّح أن الأرض)، وأنّ هناك فراشة في اللقطة 34.760-36.960s،...

ملخّص

في هذه الخطوة، كان بإمكانك رصد التصنيف في فيديو باستخدام Video Intelligence API. يمكنك الاطّلاع على مزيد من المعلومات حول اكتشاف التصنيفات.

7. رصد المحتوى الفاضح

يمكنك استخدام Video Intelligence API لرصد المحتوى الفاضح في فيديو معيّن. المحتوى الفاضح هو محتوى للبالغين غير ملائم بشكل عام للأشخاص الذين تقل أعمارهم عن 18 عامًا، ويشمل على سبيل المثال لا الحصر، العُري والأنشطة الجنسية والمواد الإباحية. يتم إجراء الاكتشاف استنادًا إلى الإشارات المرئية لكل إطار فقط (لا يتم استخدام الصوت). تتضمّن الاستجابة قيم احتمالية تتراوح بين VERY_UNLIKELY وVERY_LIKELY.

انسخ الرمز التالي إلى جلسة IPython:

from datetime import timedelta
from typing import Optional, Sequence, cast

from google.cloud import videointelligence_v1 as vi


def detect_explicit_content(
    video_uri: str,
    segments: Optional[Sequence[vi.VideoSegment]] = None,
) -> vi.VideoAnnotationResults:
    video_client = vi.VideoIntelligenceServiceClient()
    features = [vi.Feature.EXPLICIT_CONTENT_DETECTION]
    context = vi.VideoContext(segments=segments)
    request = vi.AnnotateVideoRequest(
        input_uri=video_uri,
        features=features,
        video_context=context,
    )

    print(f'Processing video "{video_uri}"...')
    operation = video_client.annotate_video(request)

    # Wait for operation to complete
    response = cast(vi.AnnotateVideoResponse, operation.result())
    # A single video is processed
    results = response.annotation_results[0]

    return results
    

خصِّص بعض الوقت لدراسة الرمز البرمجي ومعرفة طريقة استخدامه لطريقة مكتبة برامج annotate_video مع المَعلمة EXPLICIT_CONTENT_DETECTION لتحليل فيديو ورصد محتوى فاضح.

استدعِ الدالة لتحليل أول 10 ثوانٍ من الفيديو:

video_uri = "gs://cloud-samples-data/video/JaneGoodall.mp4"
segment = vi.VideoSegment(
    start_time_offset=timedelta(seconds=0),
    end_time_offset=timedelta(seconds=10),
)

results = detect_explicit_content(video_uri, [segment])

الانتظار حتى تتم معالجة الفيديو:

Processing video: "gs://cloud-samples-data/video/JaneGoodall.mp4"...

أضِف هذه الدالة لطباعة أعداد الاحتمال المختلفة:

def print_explicit_content(results: vi.VideoAnnotationResults):
    from collections import Counter

    frames = results.explicit_annotation.frames
    likelihood_counts = Counter([f.pornography_likelihood for f in frames])

    print(f" Explicit content frames: {len(frames)} ".center(40, "-"))
    for likelihood in vi.Likelihood:
        print(f"{likelihood.name:<22}: {likelihood_counts[likelihood]:>3}")
        

استدعِ الدالة:

print_explicit_content(results)

ينبغي أن تظهر لك على النحو التالي:

----- Explicit content frames: 10 ------
LIKELIHOOD_UNSPECIFIED:   0
VERY_UNLIKELY         :  10
UNLIKELY              :   0
POSSIBLE              :   0
LIKELY                :   0
VERY_LIKELY           :   0

أضِف هذه الدالة لطباعة تفاصيل الإطار:

def print_frames(results: vi.VideoAnnotationResults, likelihood: vi.Likelihood):
    frames = results.explicit_annotation.frames
    frames = [f for f in frames if f.pornography_likelihood == likelihood]

    print(f" {likelihood.name} frames: {len(frames)} ".center(40, "-"))
    for frame in frames:
        print(frame.time_offset)
        

استدعِ الدالة:

print_frames(results, vi.Likelihood.VERY_UNLIKELY)

ينبغي أن تظهر لك على النحو التالي:

------- VERY_UNLIKELY frames: 10 -------
0:00:00.365992
0:00:01.279206
0:00:02.268336
0:00:03.289253
0:00:04.400163
0:00:05.291547
0:00:06.449558
0:00:07.452751
0:00:08.577405
0:00:09.554514

ملخّص

في هذه الخطوة، أصبح بإمكانك رصد المحتوى الفاضح في فيديو باستخدام Video Intelligence API. يمكنك قراءة المزيد حول اكتشاف المحتوى الجنسي الفاضح.

8. تحويل الكلام إلى نص

يمكنك استخدام Video Intelligence API لتحويل كلام الفيديو إلى نص.

انسخ الرمز التالي إلى جلسة IPython:

from datetime import timedelta
from typing import Optional, Sequence, cast

from google.cloud import videointelligence_v1 as vi


def transcribe_speech(
    video_uri: str,
    language_code: str,
    segments: Optional[Sequence[vi.VideoSegment]] = None,
) -> vi.VideoAnnotationResults:
    video_client = vi.VideoIntelligenceServiceClient()
    features = [vi.Feature.SPEECH_TRANSCRIPTION]
    config = vi.SpeechTranscriptionConfig(
        language_code=language_code,
        enable_automatic_punctuation=True,
    )
    context = vi.VideoContext(
        segments=segments,
        speech_transcription_config=config,
    )
    request = vi.AnnotateVideoRequest(
        input_uri=video_uri,
        features=features,
        video_context=context,
    )

    print(f'Processing video "{video_uri}"...')
    operation = video_client.annotate_video(request)

    # Wait for operation to complete
    response = cast(vi.AnnotateVideoResponse, operation.result())
    # A single video is processed
    results = response.annotation_results[0]

    return results
    

خصِّص بعض الوقت لدراسة الرمز البرمجي ومعرفة كيفية استخدامه لطريقة مكتبة برامج annotate_video مع المَعلمة SPEECH_TRANSCRIPTION لتحليل فيديو وتحويل الكلام إلى نص.

استدعِ الدالة لتحليل الفيديو من 55 إلى 80 ثانية:

video_uri = "gs://cloud-samples-data/video/JaneGoodall.mp4"
language_code = "en-GB"
segment = vi.VideoSegment(
    start_time_offset=timedelta(seconds=55),
    end_time_offset=timedelta(seconds=80),
)

results = transcribe_speech(video_uri, language_code, [segment])

الانتظار حتى تتم معالجة الفيديو:

Processing video: "gs://cloud-samples-data/video/JaneGoodall.mp4"...

أضِف هذه الدالة لطباعة الكلام المحوّل إلى نص:

def print_video_speech(results: vi.VideoAnnotationResults, min_confidence: float = 0.8):
    def keep_transcription(transcription: vi.SpeechTranscription) -> bool:
        return min_confidence <= transcription.alternatives[0].confidence

    transcriptions = results.speech_transcriptions
    transcriptions = [t for t in transcriptions if keep_transcription(t)]

    print(f" Speech transcriptions: {len(transcriptions)} ".center(80, "-"))
    for transcription in transcriptions:
        first_alternative = transcription.alternatives[0]
        confidence = first_alternative.confidence
        transcript = first_alternative.transcript
        print(f" {confidence:4.0%} | {transcript.strip()}")
        

استدعِ الدالة:

print_video_speech(results)

ينبغي أن تظهر لك على النحو التالي:

--------------------------- Speech transcriptions: 2 ---------------------------
  91% | I was keenly aware of secret movements in the trees.
  92% | I looked into his large and lustrous eyes. They seem somehow to express his entire personality.

أضِف هذه الدالة لطباعة قائمة الكلمات التي تم رصدها والطوابع الزمنية لها:

def print_word_timestamps(
    results: vi.VideoAnnotationResults,
    min_confidence: float = 0.8,
):
    def keep_transcription(transcription: vi.SpeechTranscription) -> bool:
        return min_confidence <= transcription.alternatives[0].confidence

    transcriptions = results.speech_transcriptions
    transcriptions = [t for t in transcriptions if keep_transcription(t)]

    print(" Word timestamps ".center(80, "-"))
    for transcription in transcriptions:
        first_alternative = transcription.alternatives[0]
        confidence = first_alternative.confidence
        for word in first_alternative.words:
            t1 = word.start_time.total_seconds()
            t2 = word.end_time.total_seconds()
            word = word.word
            print(f"{confidence:4.0%} | {t1:7.3f} | {t2:7.3f} | {word}")
            

استدعِ الدالة:

print_word_timestamps(results)

ينبغي أن تظهر لك على النحو التالي:

------------------------------- Word timestamps --------------------------------
 93% |  55.000 |  55.700 | I
 93% |  55.700 |  55.900 | was
 93% |  55.900 |  56.300 | keenly
 93% |  56.300 |  56.700 | aware
 93% |  56.700 |  56.900 | of
...
 94% |  76.900 |  77.400 | express
 94% |  77.400 |  77.600 | his
 94% |  77.600 |  78.200 | entire
 94% |  78.200 |  78.500 | personality.

ملخّص

في هذه الخطوة، كان بإمكانك تحويل الكلام إلى نص في فيديو باستخدام Video Intelligence API. يمكنك قراءة المزيد حول تحويل الصوت إلى نص.

9. رصد النص وتتبُّعه

يمكنك استخدام Video Intelligence API لرصد النص في فيديو وتتبُّعه.

انسخ الرمز التالي إلى جلسة IPython:

from datetime import timedelta
from typing import Optional, Sequence, cast

from google.cloud import videointelligence_v1 as vi


def detect_text(
    video_uri: str,
    language_hints: Optional[Sequence[str]] = None,
    segments: Optional[Sequence[vi.VideoSegment]] = None,
) -> vi.VideoAnnotationResults:
    video_client = vi.VideoIntelligenceServiceClient()
    features = [vi.Feature.TEXT_DETECTION]
    config = vi.TextDetectionConfig(
        language_hints=language_hints,
    )
    context = vi.VideoContext(
        segments=segments,
        text_detection_config=config,
    )
    request = vi.AnnotateVideoRequest(
        input_uri=video_uri,
        features=features,
        video_context=context,
    )

    print(f'Processing video "{video_uri}"...')
    operation = video_client.annotate_video(request)

    # Wait for operation to complete
    response = cast(vi.AnnotateVideoResponse, operation.result())
    # A single video is processed
    results = response.annotation_results[0]

    return results
    

خصِّص بعض الوقت لدراسة الرمز البرمجي ومعرفة كيفية استخدامه لطريقة مكتبة برامج annotate_video مع المَعلمة TEXT_DETECTION لتحليل فيديو ورصد نص.

استدعِ الدالة لتحليل الفيديو من 13 إلى 27:

video_uri = "gs://cloud-samples-data/video/JaneGoodall.mp4"
segment = vi.VideoSegment(
    start_time_offset=timedelta(seconds=13),
    end_time_offset=timedelta(seconds=27),
)

results = detect_text(video_uri, segments=[segment])

الانتظار حتى تتم معالجة الفيديو:

Processing video: "gs://cloud-samples-data/video/JaneGoodall.mp4"...

أضِف هذه الدالة لطباعة النص الذي تم رصده:

def print_video_text(results: vi.VideoAnnotationResults, min_frames: int = 15):
    annotations = sorted_by_first_segment_end(results.text_annotations)

    print(" Detected text ".center(80, "-"))
    for annotation in annotations:
        for text_segment in annotation.segments:
            frames = len(text_segment.frames)
            if frames < min_frames:
                continue
            text = annotation.text
            confidence = text_segment.confidence
            start = text_segment.segment.start_time_offset
            seconds = segment_seconds(text_segment.segment)
            print(text)
            print(f"  {confidence:4.0%} | {start} + {seconds:.1f}s | {frames} fr.")


def sorted_by_first_segment_end(
    annotations: Sequence[vi.TextAnnotation],
) -> Sequence[vi.TextAnnotation]:
    def first_segment_end(annotation: vi.TextAnnotation) -> int:
        return annotation.segments[0].segment.end_time_offset.total_seconds()

    return sorted(annotations, key=first_segment_end)


def segment_seconds(segment: vi.VideoSegment) -> float:
    t1 = segment.start_time_offset.total_seconds()
    t2 = segment.end_time_offset.total_seconds()
    return t2 - t1
    

استدعِ الدالة:

print_video_text(results)

ينبغي أن تظهر لك على النحو التالي:

-------------------------------- Detected text ---------------------------------
GOMBE NATIONAL PARK
   99% | 0:00:15.760000 + 1.7s | 15 fr.
TANZANIA
  100% | 0:00:15.760000 + 4.8s | 39 fr.
With words and narration by
  100% | 0:00:23.200000 + 3.6s | 31 fr.
Jane Goodall
   99% | 0:00:23.080000 + 3.8s | 33 fr.

أضف هذه الدالة لطباعة قائمة إطارات النص ومربعات الإحاطة التي تم اكتشافها:

def print_text_frames(results: vi.VideoAnnotationResults, contained_text: str):
    # Vertex order: top-left, top-right, bottom-right, bottom-left
    def box_top_left(box: vi.NormalizedBoundingPoly) -> str:
        tl = box.vertices[0]
        return f"({tl.x:.5f}, {tl.y:.5f})"

    def box_bottom_right(box: vi.NormalizedBoundingPoly) -> str:
        br = box.vertices[2]
        return f"({br.x:.5f}, {br.y:.5f})"

    annotations = results.text_annotations
    annotations = [a for a in annotations if contained_text in a.text]
    for annotation in annotations:
        print(f" {annotation.text} ".center(80, "-"))
        for text_segment in annotation.segments:
            for frame in text_segment.frames:
                frame_ms = frame.time_offset.total_seconds()
                box = frame.rotated_bounding_box
                print(
                    f"{frame_ms:>7.3f}",
                    box_top_left(box),
                    box_bottom_right(box),
                    sep=" | ",
                )
                

استدعِ الدالة لمعرفة الإطارات التي تعرض اسم الراوي:

contained_text = "Goodall"
print_text_frames(results, contained_text)

ينبغي أن تظهر لك على النحو التالي:

--------------------------------- Jane Goodall ---------------------------------
 23.080 | (0.39922, 0.49861) | (0.62752, 0.55888)
 23.200 | (0.38750, 0.49028) | (0.62692, 0.56306)
...
 26.800 | (0.36016, 0.49583) | (0.61094, 0.56048)
 26.920 | (0.45859, 0.49583) | (0.60365, 0.56174)

إذا رسمت المربعات الإحاطة أعلى الإطارات المقابلة، فستحصل على هذا:

7e530d3d25f2f40e.gif

ملخّص

في هذه الخطوة، أصبح بإمكانك رصد النصوص وتتبُّعها في فيديو باستخدام Video Intelligence API. يمكنك الاطّلاع على مزيد من المعلومات عن رصد النص وتتبُّعه.

10. رصد العناصر وتتبُّعها

يمكنك استخدام Video Intelligence API لرصد العناصر في فيديو وتتبُّعها.

انسخ الرمز التالي إلى جلسة IPython:

from datetime import timedelta
from typing import Optional, Sequence, cast

from google.cloud import videointelligence_v1 as vi


def track_objects(
    video_uri: str, segments: Optional[Sequence[vi.VideoSegment]] = None
) -> vi.VideoAnnotationResults:
    video_client = vi.VideoIntelligenceServiceClient()
    features = [vi.Feature.OBJECT_TRACKING]
    context = vi.VideoContext(segments=segments)
    request = vi.AnnotateVideoRequest(
        input_uri=video_uri,
        features=features,
        video_context=context,
    )

    print(f'Processing video "{video_uri}"...')
    operation = video_client.annotate_video(request)

    # Wait for operation to complete
    response = cast(vi.AnnotateVideoResponse, operation.result())
    # A single video is processed
    results = response.annotation_results[0]

    return results
    

خصِّص بعض الوقت لدراسة الرمز البرمجي ومعرفة كيفية استخدامه لطريقة مكتبة برامج annotate_video مع المَعلمة OBJECT_TRACKING لتحليل فيديو ورصد عناصر.

استدعِ الدالة لتحليل الفيديو من 98 إلى 112 ثانية:

video_uri = "gs://cloud-samples-data/video/JaneGoodall.mp4"
segment = vi.VideoSegment(
    start_time_offset=timedelta(seconds=98),
    end_time_offset=timedelta(seconds=112),
)

results = track_objects(video_uri, [segment])

الانتظار حتى تتم معالجة الفيديو:

Processing video: "gs://cloud-samples-data/video/JaneGoodall.mp4"...

أضِف هذه الدالة لطباعة قائمة العناصر التي تم رصدها:

def print_detected_objects(
    results: vi.VideoAnnotationResults,
    min_confidence: float = 0.7,
):
    annotations = results.object_annotations
    annotations = [a for a in annotations if min_confidence <= a.confidence]

    print(
        f" Detected objects: {len(annotations)}"
        f" ({min_confidence:.0%} <= confidence) ".center(80, "-")
    )
    for annotation in annotations:
        entity = annotation.entity
        description = entity.description
        entity_id = entity.entity_id
        confidence = annotation.confidence
        t1 = annotation.segment.start_time_offset.total_seconds()
        t2 = annotation.segment.end_time_offset.total_seconds()
        frames = len(annotation.frames)
        print(
            f"{description:<22}",
            f"{entity_id:<10}",
            f"{confidence:4.0%}",
            f"{t1:>7.3f}",
            f"{t2:>7.3f}",
            f"{frames:>2} fr.",
            sep=" | ",
        )
        

استدعِ الدالة:

print_detected_objects(results)

ينبغي أن تظهر لك على النحو التالي:

------------------- Detected objects: 3 (70% <= confidence) --------------------
insect                 | /m/03vt0   |  87% |  98.840 | 101.720 | 25 fr.
insect                 | /m/03vt0   |  71% | 108.440 | 111.080 | 23 fr.
butterfly              | /m/0cyf8   |  91% | 111.200 | 111.920 |  7 fr.

أضِف هذه الدالة لطباعة قائمة إطارات الكائنات ومربّعات الإحاطة التي تم رصدها:

def print_object_frames(
    results: vi.VideoAnnotationResults,
    entity_id: str,
    min_confidence: float = 0.7,
):
    def keep_annotation(annotation: vi.ObjectTrackingAnnotation) -> bool:
        return (
            annotation.entity.entity_id == entity_id
            and min_confidence <= annotation.confidence
        )

    annotations = results.object_annotations
    annotations = [a for a in annotations if keep_annotation(a)]
    for annotation in annotations:
        description = annotation.entity.description
        confidence = annotation.confidence
        print(
            f" {description},"
            f" confidence: {confidence:.0%},"
            f" frames: {len(annotation.frames)} ".center(80, "-")
        )
        for frame in annotation.frames:
            t = frame.time_offset.total_seconds()
            box = frame.normalized_bounding_box
            print(
                f"{t:>7.3f}",
                f"({box.left:.5f}, {box.top:.5f})",
                f"({box.right:.5f}, {box.bottom:.5f})",
                sep=" | ",
            )
            

استدعِ الدالة برقم تعريف الكيان للحشرات:

insect_entity_id = "/m/03vt0"
print_object_frames(results, insect_entity_id)

ينبغي أن تظهر لك على النحو التالي:

--------------------- insect, confidence: 87%, frames: 25 ----------------------
 98.840 | (0.49327, 0.19617) | (0.69905, 0.69633)
 98.960 | (0.49559, 0.19308) | (0.70631, 0.69671)
...
101.600 | (0.46668, 0.19776) | (0.76619, 0.69371)
101.720 | (0.46805, 0.20053) | (0.76447, 0.68703)
--------------------- insect, confidence: 71%, frames: 23 ----------------------
108.440 | (0.47343, 0.10694) | (0.63821, 0.98332)
108.560 | (0.46960, 0.10206) | (0.63033, 0.98285)
...
110.960 | (0.49466, 0.05102) | (0.65941, 0.99357)
111.080 | (0.49572, 0.04728) | (0.65762, 0.99868)

إذا رسمت المربعات الإحاطة أعلى الإطارات المقابلة، فستحصل على هذا:

8f5796f6e73d1a46.gif

c195a2dca4573f95.gif

ملخّص

في هذه الخطوة، أصبح بإمكانك رصد العناصر وتتبُّعها في فيديو باستخدام Video Intelligence API. يمكنك الاطّلاع على مزيد من المعلومات حول رصد العناصر وتتبُّعها.

11. رصد الشعارات وتتبُّعها

يمكنك استخدام Video Intelligence API لرصد الشعارات في فيديو معيّن وتتبُّعها. يمكن رصد أكثر من 100,000 علامة تجارية وشعار.

انسخ الرمز التالي إلى جلسة IPython:

from datetime import timedelta
from typing import Optional, Sequence, cast

from google.cloud import videointelligence_v1 as vi


def detect_logos(
    video_uri: str, segments: Optional[Sequence[vi.VideoSegment]] = None
) -> vi.VideoAnnotationResults:
    video_client = vi.VideoIntelligenceServiceClient()
    features = [vi.Feature.LOGO_RECOGNITION]
    context = vi.VideoContext(segments=segments)
    request = vi.AnnotateVideoRequest(
        input_uri=video_uri,
        features=features,
        video_context=context,
    )

    print(f'Processing video "{video_uri}"...')
    operation = video_client.annotate_video(request)

    # Wait for operation to complete
    response = cast(vi.AnnotateVideoResponse, operation.result())
    # A single video is processed
    results = response.annotation_results[0]

    return results
    

خصِّص بعض الوقت لدراسة الرمز البرمجي ومعرفة كيفية استخدامه لطريقة مكتبة برامج annotate_video مع المَعلمة LOGO_RECOGNITION لتحليل فيديو واكتشاف الشعارات.

استدعِ الدالة لتحليل التسلسل نصف النهائي للفيديو:

video_uri = "gs://cloud-samples-data/video/JaneGoodall.mp4"
segment = vi.VideoSegment(
    start_time_offset=timedelta(seconds=146),
    end_time_offset=timedelta(seconds=156),
)

results = detect_logos(video_uri, [segment])

الانتظار حتى تتم معالجة الفيديو:

Processing video: "gs://cloud-samples-data/video/JaneGoodall.mp4"...

أضِف هذه الدالة لطباعة قائمة الشعارات التي تمّ رصدها:

def print_detected_logos(results: vi.VideoAnnotationResults):
    annotations = results.logo_recognition_annotations

    print(f" Detected logos: {len(annotations)} ".center(80, "-"))
    for annotation in annotations:
        entity = annotation.entity
        entity_id = entity.entity_id
        description = entity.description
        for track in annotation.tracks:
            confidence = track.confidence
            t1 = track.segment.start_time_offset.total_seconds()
            t2 = track.segment.end_time_offset.total_seconds()
            logo_frames = len(track.timestamped_objects)
            print(
                f"{confidence:4.0%}",
                f"{t1:>7.3f}",
                f"{t2:>7.3f}",
                f"{logo_frames:>3} fr.",
                f"{entity_id:<15}",
                f"{description}",
                sep=" | ",
            )
            

استدعِ الدالة:

print_detected_logos(results)

ينبغي أن تظهر لك على النحو التالي:

------------------------------ Detected logos: 1 -------------------------------
 92% | 150.680 | 155.720 |  43 fr. | /m/055t58       | Google Maps

أضِف هذه الدالة لطباعة قائمة بإطارات الشعارات والمربّعات المحيطة التي تم رصدها:

def print_logo_frames(results: vi.VideoAnnotationResults, entity_id: str):
    def keep_annotation(annotation: vi.LogoRecognitionAnnotation) -> bool:
        return annotation.entity.entity_id == entity_id

    annotations = results.logo_recognition_annotations
    annotations = [a for a in annotations if keep_annotation(a)]
    for annotation in annotations:
        description = annotation.entity.description
        for track in annotation.tracks:
            confidence = track.confidence
            print(
                f" {description},"
                f" confidence: {confidence:.0%},"
                f" frames: {len(track.timestamped_objects)} ".center(80, "-")
            )
            for timestamped_object in track.timestamped_objects:
                t = timestamped_object.time_offset.total_seconds()
                box = timestamped_object.normalized_bounding_box
                print(
                    f"{t:>7.3f}",
                    f"({box.left:.5f}, {box.top:.5f})",
                    f"({box.right:.5f}, {box.bottom:.5f})",
                    sep=" | ",
                )
                

استدعِ الدالة باستخدام رقم تعريف كيان شعار "خرائط Google":

maps_entity_id = "/m/055t58"
print_logo_frames(results, maps_entity_id)

ينبغي أن تظهر لك على النحو التالي:

------------------- Google Maps, confidence: 92%, frames: 43 -------------------
150.680 | (0.42024, 0.28633) | (0.58192, 0.64220)
150.800 | (0.41713, 0.27822) | (0.58318, 0.63556)
...
155.600 | (0.41775, 0.27701) | (0.58372, 0.63986)
155.720 | (0.41688, 0.28005) | (0.58335, 0.63954)

إذا رسمت المربعات الإحاطة أعلى الإطارات المقابلة، فستحصل على هذا:

554743aff6d8824c.gif

ملخّص

في هذه الخطوة، أصبح بإمكانك رصد الشعار وتتبُّعه في فيديو باستخدام Video Intelligence API. يمكنك الاطّلاع على مزيد من المعلومات حول التعرّف على الشعارات وتتبُّعها.

12. رصد عدّة ميزات

هنا نوع الطلب الذي يمكنك تقديمه للحصول على جميع الإحصاءات في آنٍ واحد:

from google.cloud import videointelligence_v1 as vi

video_client = vi.VideoIntelligenceServiceClient()
video_uri = "gs://..."
features = [
    vi.Feature.SHOT_CHANGE_DETECTION,
    vi.Feature.LABEL_DETECTION,
    vi.Feature.EXPLICIT_CONTENT_DETECTION,
    vi.Feature.SPEECH_TRANSCRIPTION,
    vi.Feature.TEXT_DETECTION,
    vi.Feature.OBJECT_TRACKING,
    vi.Feature.LOGO_RECOGNITION,
    vi.Feature.FACE_DETECTION,  # NEW
    vi.Feature.PERSON_DETECTION,  # NEW
]
context = vi.VideoContext(
    segments=...,
    shot_change_detection_config=...,
    label_detection_config=...,
    explicit_content_detection_config=...,
    speech_transcription_config=...,
    text_detection_config=...,
    object_tracking_config=...,
    face_detection_config=...,  # NEW
    person_detection_config=...,  # NEW
)
request = vi.AnnotateVideoRequest(
    input_uri=video_uri,
    features=features,
    video_context=context,
)

# video_client.annotate_video(request)

13. تهانينا!

cfaa6ffa7bc5ca70.png

لقد تعلمت كيفية استخدام Video Intelligence API باستخدام Python!

تَنظيم

لتنظيف بيئة التطوير، من Cloud Shell:

  • إذا كنت لا تزال في جلسة IPython، يُرجى الرجوع إلى واجهة الأوامر: exit
  • التوقف عن استخدام بيئة Python الافتراضية: deactivate
  • حذف مجلد البيئة الافتراضية: cd ~ ; rm -rf ./venv-videointel

لحذف مشروعك على Google Cloud، اتّبِع الخطوات التالية من Cloud Shell:

  • استرداد رقم تعريف مشروعك الحالي: PROJECT_ID=$(gcloud config get-value core/project)
  • تأكَّد من أنّ هذا هو المشروع الذي تريد حذفه: echo $PROJECT_ID.
  • حذف المشروع: gcloud projects delete $PROJECT_ID

مزيد من المعلومات

الترخيص

هذا العمل مرخّص بموجب رخصة المشاع الإبداعي 2.0 مع نسب العمل إلى مؤلف عام.