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

1. نظرة عامة

cfaa6ffa7bc5ca70.png

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

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

ما ستتعلمه

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

المتطلبات

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

استطلاع الرأي

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

قراءة المحتوى فقط قراءة المحتوى وإكمال التمارين

كيف تقيّم تجربتك مع 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 ~

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

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 Generic License.