Filter by دسته‌ها
chatGTP
ابزارهای هوش مصنوعی
اخبار
گزارش
تیتر یک
چندرسانه ای
آموزش علوم داده
اینفوگرافیک
پادکست
ویدیو
دانش روز
آموزش‌های پایه‌ای هوش مصنوعی
اصول هوش مصنوعی
یادگیری بدون نظارت
یادگیری تقویتی
یادگیری عمیق
یادگیری نیمه نظارتی
آموزش‌های پیشرفته هوش مصنوعی
بینایی ماشین
پردازش زبان طبیعی
پردازش گفتار
چالش‌های عملیاتی
داده کاوی و بیگ دیتا
رایانش ابری و HPC
سیستم‌‌های امبدد
علوم شناختی
دیتاست
رویدادها
جیتکس
کاربردهای هوش مصنوعی
کتابخانه
اشخاص
شرکت‌های هوش مصنوعی
محصولات و مدل‌های هوش مصنوعی
مفاهیم
کسب‌و‌کار
تحلیل بازارهای هوش مصنوعی
کارآفرینی
هوش مصنوعی در ایران
هوش مصنوعی در جهان
مقاله
 پروژه تشخیص اشیاء و ایجاد یک مکانیزم لاگین کردن با استفاده از TDD

پروژه تشخیص اشیاء و ایجاد یک مکانیزم لاگین کردن با استفاده از TDD

زمان مطالعه: 8 دقیقه
اخیراً مشغول کار در پروژه‌ای مربوطه به نرم‌افزار پردازش آنی بوده‌ایم. این نرم‌افزار ویدئوها را از سیستم‌های نظارتی دریافت کرده و کادرهای محصورکننده Bounding boxes را در موارد شناسایی‌شده به نمایش در می‌آورد. سپس اطلاعات مربوط به آن موارد در فایل‌های json به صورت رکورد log ذخیره می‌شود. به نظر می‌آید این پروژه تشخیص اشیاء ساده برای شروع کار، خوب باشد.
در همین راستا، از رویکرد Test-Driven-Development برای نوشتن کد نرم‌افزار استفاده می‌کنیم. امیدواریم افراد تازه‌کاری که مایل‌اند با ابزارهای unittest در پایتون آشنا شوند، نهایت استفاده را از این پست ببرند. شما می‌توانید برای دریافت کد منبع به این لینک مراجعه کنید. در این لینک، یک مورد پیاده‌سازی همین کد بر روی سرویس تشخیص اشیاء  Object detection service نیز اضافه شده است. منبع کد پروژه تشخیص اشیاء متعلق به آدریان رزبراک است که در این پست فوق‌العاده به اشتراک گذاشته شده است.

توصیف سیستم

برای اینکه دقیقاً متوجه هدف این پست شوید، یک نگاه به نمونه عکس زیر بیندازید:

پروژه تشخیص اشیاء

در این عکس، فریمی با دو کادر محصورکننده نشان داده شده و هر کادر حاوی برچسبی با سطح اطمینان مشخص است. پس فهرستی از فریم‌ها در اختیار داریم و هر فریم می‌تواند دربردارنده‌ی چندین کادر می‌باشد. معمولاً در اکثر پروژه‌های تشخیص اشیاء در خروجی شبکه‌های پروژه تشخیص اشیاء، برای هر کادر محصور کننده چندین برچسب‌ با درجه اطمینان وجود دارد که شی شناسایی شده با اولویت درجه اطمینان انتخاب می‌شود. پس در این پروژه شرایطی فراهم می‌آوریم که کادرها فهرستی از برچسب‌ها با درصد اطمینان خروجی شبکه مصنوعی داشته باشند. این کار با انتخاب پارامتری تحت عنوان top_k_label به انجام می‌رسد. انتظار داریم همه کادرها تعداد برچسب یکسانی داشته باشند. حال، به مثالی از فایل json که به شکل 1 مربوط است، توجه نمائید:

{
“video_details”: {
“frame_width”: 1080,
“frame_height”: 720,
“frame_fps”: 20,
“video_name”: “test.avi”
},
“frames”: [
{
“frame_id”: 1,
“bboxes”: [
{
“bbox_id”: “0”,
“labels”: [
{
“category”: “car”,
“confidence”: 99.25
},
{
“category”: “truck”,
“confidence”: 57.14
}
],
“left”: 5,
“top”: 400,
“width”: 250,
“height”: 145https://hooshio.com/%d9%be%d8%b1%d9%88%da%98%d9%87-%d8%aa%d8%b4%d8%ae%db%8c%d8%b5-%d8%a7%d8%b4%db%8c%d8%a7%d8%a1-%d9%88-%d8%a7%db%8c%d8%ac%d8%a7%d8%af-%d9%85%da%a9%d8%a7%d9%86%db%8c%d8%b2%d9%85-%d9%84%d8%a7%da%af%db%8c/
},
{
“bbox_id”: “1”,

“labels”: [
{
“category”: “car”,
“confidence”: 99.78
},
{
“category”: “bus”,
“confidence”: 65.23
}],
“left”: 650,
“top”: 450,
“width”: 300,
“height”: 150
}]
}]

 

جزئیات ویدئو نیز در این نمونه مد نظر قرار گرفته است؛ از جمله این جزئیات می‌توان به عرض، ارتفاع، سرعت خواندن ویدئو (فریم بر ثانیه fps) و نام فایل ویدئویی اشاره کرد. هدف از این کار، اطمینان حاصل کردن از ساخت مجدد کادرها در هنگام استفاده از فایل ویدئویی است.

[irp posts=”4503″]

شروع کار

من کد اولیه را با سه class شروع کردم. این class حاوی اطلاعاتی درباره فریم‌ها، کادرها و برچسب‌ها است.

class Label:
"""
For each bounding box there are various categories with confidences. Label class keeps track of that information.
"""

def __init__(self, category: str, confidence: float):
self.category = category
self.confidence = confidence

class Bbox:
"""
This classhttps://hooshio.com/%d9%be%d8%b1%d9%88%da%98%d9%87-%d8%aa%d8%b4%d8%ae%db%8c%d8%b5-%d8%a7%d8%b4%db%8c%d8%a7%d8%a1-%d9%88-%d8%a7%db%8c%d8%ac%d8%a7%d8%af-%d9%85%da%a9%d8%a7%d9%86%db%8c%d8%b2%d9%85-%d9%84%d8%a7%da%af%db%8c/ keeps the information of each bounding box in the frame.
"""

def __init__(self, bbox_id, top, left, width, height):
self.labels = []
self.bbox_id = bbox_id
self.top = top
self.left = left
self.width = width
self.height = height

class Frame:
def __init__(self, frame_id: int):
self.frame_id = frame_id
self.bboxes = []

دسته‌های پایه

class دیگری برای مدیریت خروجی ایجاد و آن را JsonParser نامگذاری کردم:

class JsonParser:
def __init__(self, top_k_labels: int = 1):
self.frames = {}
self.video_details = dict(frame_width=None,
frame_height=None,
frame_rate=None,
video_name=None)
self.top_k_labels = top_k_labels

این class مخصوصِ مدیریت logger است.

[irp posts=”13463″]

مرحله 1: افزودن فریم

حال که class های اولیه را در اختیار داریم، بیایید از رویکرد TDD software development استفاده کنیم. من فایل دیگری به نام test_json_parser ایجاد کردم و آن را در پوشه tests قرار دادم. حالا به کدی نیاز داریم که افزودنِ فریم به JsonParser.frames را تحت آزمایش unittest قرار دهد. اکنون زمان اجرای TestCase با کد زیر فرا رسیده است:

import unittest
import sys
from unittest.case import TestCase

sys.path.append('../..')
from json_parser.json_parser import *

class TestFrame(TestCase):

def setUp(self) -> None:
self.json_parser = JsonParser()
self.video_details = {'frame_width': 500,
'frame_height': 200,
'frame_rate': 20,
'video_name': 'something.mp4'}

مقداردهی اولیه برای jsonparser tests

من از ابزارهای نرم افزار pycharm برای آزمایش کد استفاده کردم. دلیل افزودنِ sys.path.append(../..) این بود که اگر قادر به استفاده از pycharm نبودید، بتوانید از فرمان‌های terminal برای انجام unittest ها استفاده کنیم. کد زیر، فرایند افزودن فریم را تحت unittest قرار می‌دهد.

def test_add_frame(self):
frames_ids = [1, 2, 3, 4, 5]
self.json_parser.set_top_k(0)
for frame_id in frames_ids:
self.json_parser.add_frame(frame_id)
output = self.json_parser.output()
output_ids = [frame['frame_id'] for frame in output['frames']]
for frame_id in frames_ids:
self.assertIn(frame_id, output_ids)

# if repeated frame id was inserted, raise ValueError
with self.assertRaisesRegex(ValueError, "Frame id: (.*?) already exists"):
self.json_parser.add_frame(frames_ids[1])

در این آزمایش:
1. اطمینان حاصل می‌کنیم که تعداد فریمی که در json قرار دارد همان مقداری است که در ورودی تخصیص یافته است.
2. اگر بر اساس شماره فریم، فریمی تکراری جایگذاری شود، انتظار می‌رود روند کار با خطا همراه باشد.
توجه داشته باشید که تابع assertRaisesRegex از عبارات معمولی برای بررسی پیام خطا استفاده می‌کند. عبارت (.*?) یک عبارت معمولی است، اما در این مورد، برای چشم‌پوشی از جملات میان (Frame id:) و already exists استفاده شد. حال بیایید کد را برای پشت سر گذاشتن این آزمایش به کار ببندیم. باید کار را با ماژول JsonParser آغاز کنیم. در همین راستا، سه تابع زیر به کد اضافه می شود:

def set_top_k(self, value):
self.top_k_labels = value

def frame_exists(self, frame_id: int):
return frame_id in self.frames.keys()

def add_frame(self, frame_id: int):
# Use this function to add frames with index.
if not self.frame_exists(frame_id):
self.frames[frame_id] = Frame(frame_id)
else:
raise ValueError("Frame id: {} already exists".format(frame_id))

توابع لازم برای پشت سر گذاشتن آزمایش «اضافه کردنِ فریم»

من معمولاً از دستورالعمل __dict__() برای دسترسی به خصوصیات کلاس‌ها در پایتون استفاده می‌کنم. اما به منظور دسترسی به خصوصیاتی که شامل یک لیست از اشیاء می‌شوند، مثل labels در دسته Bbox یا bboxes در دسته Frame، باید از یک ترفند برای به دست آوردن این پارامترها استفاده کنیم. به لطف این لینک ، یک کلاس والد Parent class ایجاد کردم که خصوصیت دیگری به کلاس‌های Frame، Bbox و Label اضافه می‌کند. نام این کلاس BaseJsonParser است. به فرایند زیر توجه نمائید.

class BaseJsonParser(object):
"""
This is the base class that returns __dict__ of its own
it also returns the dicts of objects in the attributes that are list instances
"""

def dic(self):
# returns dicts of objects
out = {}
for k, v in self.__dict__.items():
if hasattr(v, 'dic'):
out[k] = v.dic()
elif isinstance(v, list):
out[k] = self.list(v)
else:
out[k] = v
return out

@staticmethod
def list(values):
# applies the dic method on items in the list
return [v.dic() if hasattr(v, 'dic') else v for v in values]

class Label(BaseJsonParser):
"""
For each bounding box there are various categories with confidences. Label class keeps track of that information.
"""

def __init__(self, category: str, confidence: float):
self.category = category
self.confidence = confidence

class Bbox(BaseJsonParser):
"""
This class keeps the information of each bounding box in the frame.
"""

def __init__(self, bbox_id, top, left, width, height):
self.labels = []
self.bbox_id = bbox_id
self.top = top
self.left = left
self.width = width
self.height = height

class Frame(BaseJsonParser):
def __init__(self, frame_id: int):
self.frame_id = frame_id
self.bboxes = []

تعریف BaseJsonParser

با انتخاب BaseJsonParser به عنوان کلاس والد، خصیصه ای به نام dic برای کلاس ها تخصیص داده می‌شود. این خصوصیت  Attribute به ما اجازه خواهد داد تا خصوصیات را در کلاس های جایگذاری شده بازگردانیم. اکنون زمان افزودنِ دستورالعمل output به `JsonParser` و اجرای آزمایش فرا رسیده است:

def output(self):
output = {'video_details': self.video_details}
result = list(self.frames.values())
output['frames'] = [item.dic() for item in result]
return output

این تابع را به کلاس `JsonParser` اضافه کنید.

حالا به اجرای test_add_frame.pyمی پردازیم.

پروژه تشخیص اشیاء

آزمایش اول با موفقیت به پایان رسید!

مرحله 2: اضافه کردن کادر محصورکننده به هر فریم

بسیار عالی! اکنون می‌خواهیم آزمایش دوم را بنویسیم که مخصوصِ اضافه کردنِ کادر به فریم‌ها است:

def test_add_bbox_to_frame(self):
# test if bbox is added to its own frame
frame_one_id = 0
bbox_id = 1
bbox_xywh = (10, 20, 30, 40)
top_k = 0
self.json_parser.set_top_k(top_k)

self.json_parser.add_frame(frame_one_id)
self.json_parser.add_bbox_to_frame(frame_one_id, bbox_id, *bbox_xywh)
out = self.json_parser.output()
# retrieve the bbox in the frame
inserted_bbox = out['frames'][0]['bboxes'][0]
# check the values inserted in bbox
self.assertEqual((inserted_bbox['bbox_id']), bbox_id)
self.assertEqual(inserted_bbox['top'], bbox_xywh[0])
self.assertEqual(inserted_bbox['left'], bbox_xywh[1])
self.assertEqual(inserted_bbox['width'], bbox_xywh[2])
self.assertEqual(inserted_bbox['height'], bbox_xywh[3])

# check if error raises with repeated insertion
with self.assertRaisesRegex(ValueError,
'frame with frame_id: (.*?) already contains the bbox with id: (.*?) '):
self.json_parser.add_bbox_to_frame(frame_one_id, bbox_id, *bbox_xywh)

# check if error raises when frame_id is not recognized
with self.assertRaisesRegex(ValueError,
'frame with frame_id: (.*?) does not exist'):
self.json_parser.add_bbox_to_frame(2, bbox_id, *bbox_xywh)

این کار برای اضافه کردن کادر ضروری است.

باید موارد زیر را برای پاس کردن تست‌ها پیاده‌سازی کنیم:
1. ایجاد تابع برای JsonParser تا بررسی کند آیا bbox وجود دارد یا خیر.
2. ایجا تابع برای اضافه کردنِ bbox به فریم

def bbox_exists(self, frame_id, bbox_id):
bboxes = []
if self.frame_exists(frame_id=frame_id):
bboxes = [bbox.bbox_id for bbox in self.frames[frame_id].bboxes]
return bbox_id in bboxes

def add_bbox_to_frame(self, frame_id: int, bbox_id: int, top: int, left: int, width: int, height: int):
if self.frame_exists(frame_id):
frame = self.frames[frame_id]
if not self.bbox_exists(frame_id, bbox_id):
frame.add_bbox(bbox_id, top, left, width, height)
else:
raise ValueError(
"frame with frame_id: {} already contains the bbox with id: {} ".format(frame_id, bbox_id))
else:
raise ValueError("frame with frame_id: {} does not exist".format(frame_id))

این موارد را به `JsonParser` اضافه کنید.

def add_bbox(self, bbox_id: int, top: int, left: int, width: int, height: int):
bboxes_ids = [bbox.bbox_id for bbox in self.bboxes]
if bbox_id not in bboxes_ids:
self.bboxes.append(Bbox(bbox_id, top, left, width, height))
else:
raise ValueError("Frame with id: {} already has a Bbox with id: {}".format(self.frame_id, bbox_id)

این مورد را به دستۀ Frame اضافه کنید.

حالا نوبت انجام مجدد هر دو آزمایش فرا رسیده است:

پروژه تشخیص اشیاء

مرحله 3: اضافه کردنِ برچسب به کادرها

در گام بعدی، باید برچسب‌ها را به bboxes افزوده و فرایند کار را آزمایش کنیم. باید موارد زیر آزمایش شوند:
1. با بکارگیری top_k_labels و افزودن برچسب‌های یکسان به bboxes، انتظار داریم کار بدون هیچ مشکلی پیش برود.
2. با اضافه شدن برچسب‌های بیشتر از top_k_labels به خطای ValueError خواهیم خورد.
3. در حین خروجی گرفتن از json، انتظار داریم برنامه از این موضوع را اطمینان حاصل کند که تعداد برچسبهای هر کادر یکسان باشد.
اکنون به روند آزمایش دقت کنید:

def test_add_label_to_bbox(self):
# test if label exists in bbox
frame_one_id = 0
bbox_id = 1
bbox_xywh = (10, 20, 30, 40)
self.json_parser.add_frame(frame_one_id)
self.json_parser.add_bbox_to_frame(frame_one_id, bbox_id, *bbox_xywh)

categories = ['car', 'truck', 'bus']
confidences = [0.47, 0.85, 1]
top_k = 3

self.json_parser.set_top_k(value=top_k)
for cat, conf in zip(categories, confidences):
self.json_parser.add_label_to_bbox(frame_one_id, bbox_id, cat, conf)
out = self.json_parser.output()
inserted_labels = out['frames'][0]['bboxes'][0]['labels']

# Does output contain all labels that were inserted.
for label in inserted_labels:
self.assertTrue(label['category'] in categories)
self.assertTrue(label['confidence'] in confidences)

# Check if appending extra label (more than top_k) raises ValueError
with self.assertRaisesRegex(ValueError, 'labels in frame_id: (.*?), bbox_id: (.*?) is fulled'):
self.json_parser.add_label_to_bbox(frame_one_id, bbox_id, 'new_category', 0.12)

# Check if error raises when the number of inserted labels are less than top_k
self.json_parser.set_top_k(4)
with self.assertRaisesRegex(ValueError,
'labels in frame_id: (.*?), bbox_id: (.*?) is not fulled before outputting.'):
out = self.json_parser.output()

آزمایشِ روند افزودن برچسب به bbox

حال با پیاده سازی موارد زیر این تست را پشت سر می گذاریم:
1. تابعی نیاز داریم تا bbox را در لیست bboxes با در اختیار داشتن frame_id و bbox_id از لیست frames پیدا کند.
2. ایجاد تابعی که برچسبی به bbox پیدا شده اضافه کند.
3. باید تعداد برچسب‌های اضافه شده به bbox برابر با تعداد top_k_labels باشد. در غیر این صورت، انتظار داریم خطا رخ بدهد. هنگام خروجی گرفتن از فریم‌ها نیز باید این مسئله بررسی شود.

حال، تابع find_bbox را در JsonParser اضافه می‌کنیم:

def find_bbox(self, frame_id: int, bbox_id: int):
if not self.bbox_exists(frame_id, bbox_id):
raise ValueError("frame with id: {} does not contain bbox with id: {}".format(frame_id, bbox_id))
bboxes = {bbox.bbox_id: bbox for bbox in self.frames[frame_id].bboxes}
return bboxes.get(bbox_id)

اینجا باید add_label_to_bbox را به JsonParser اضافه کنیم:

def add_label_to_bbox(self, frame_id: int, bbox_id: int, category: str, confidence: float):
bbox = self.find_bbox(frame_id, bbox_id)
if not bbox.labels_full(self.top_k_labels):
bbox.add_label(category, confidence)
else:
raise ValueError("labels in frame_id: {}, bbox_id: {} is fulled".format(frame_id, bbox_id))

همان طور که ملاحظه می‌کنید، باید add_label در bbox وجود داشته باشد. البته من علاوه بر آن تابع دیگری تحت عنوان labels_full نیز اضافه کردم:

class Bbox(BaseJsonParser):
"""
This class keeps the information of each bounding box in the frame.
"""

def __init__(self, bbox_id, top, left, width, height):
self.labels = []
self.bbox_id = bbox_id
self.top = top
self.left = left
self.width = width
self.height = height

def add_label(self, category, confidence):
# adds category and confidence only if top_k is not exceeded.
self.labels.append(Label(category, confidence))

def labels_full(self, value):
return len(self.labels) == value

با افزودن `add_label` و `labels_full`، به‌روزرِرسانیِ کلاس `Bbox` در دستور کار قرار گرفت.
مقداری که در ورودی برای labels_full تخصیص داده شد، top_k خواهد بود. این مورد در JsonParser مد نظر قرار گرفته بود. اکنون مجبوریم کد مربوط به تابع خروجی را در JsonParser اصلاح کنیم:

def output(self):
output = {'video_details': self.video_details}
result = list(self.frames.values())

# Every bbox in each frame has to have `top_k_labels` number of labels otherwise error raises.
for frame in result:
for bbox in frame.bboxes:
if not bbox.labels_full(self.top_k_labels):
raise ValueError(
"labels in frame_id: {}, bbox_id: {} is not fulled before outputting.".format(frame.frame_id,
bbox.bbox_id))

اصلاح خروجی در JsonParser

بیایید یکبار دیگر همه تست‌ها را یکجا اجرا کنیم:

پروژه تشخیص اشیاء

اجرای همه تست‌ها

مرحله 1: خودکارسازی خروجی‌های Json

بسیار خب. JsonParser را در اختیار داریم. زمینه برای ساخت تابعی که بتواند کل فرایندِ ذخیرۀ فایل‌های json را خودکار کند، فراهم شده است. سازوکارِ من برای پیاده‌سازی این طرح به صورت زیر است:
1. یک پارامتر interval در اختیار داریم که می‌تواند بین 1 ثانیه تا 5 ساعت باشد. این پارامتر نشان می‌دهد که فایل‌های json چند وقت به چند وقت ذخیره می‌شوند.

[irp posts=”7503″]

2. پیش از اینکه فرایند فریم اول آغاز شود، باید زمان آغاز را تعیین کنیم.
3. تابع زمان‌بندی در حلقه به کار گرفته می‌شود و این فرایند در هر فریم به اجرا درمی‌آید. در وهله بعد، می‌توان تفاوت میان زمان آغازین و زمان فعلی را اندازه گرفت. هر وقت این تفاوت بیشتر از پارامتر time_to_save باشد، می‌توانیم فایل json را ذخیره کنیم.
اکنون زمان ایجاد تست در فایلی دیگر به نام test_scheduled_output.py و انجام فرایند تست به صورت زیر فرا رسیده است:

import unittest
import sys
from datetime import datetime
from os import listdir
from time import sleep
from tempfile import mkdtemp
from unittest.case import TestCase

# from json_parser import JsonParser

sys.path.append('../..')
from json_parser.json_parser import *

class TestFrame(TestCase):

def setUp(self) -> None:
self.json_parser = JsonParser()
self.video_details = {'frame_width': 500,
'frame_height': 200,
'num_of_frames': 100,
'frame_rate': 20}
self.out_path = mkdtemp()
self.list_of_files_to_remove = []

def test_automated_output_jsons(self):
self.json_parser.set_top_k(0)
self.json_parser.set_start()

frames = [0, 1, 2]
bbox_ids = [0, 1]
bbox_xywh = [(10, 20, 30, 40), (50, 60, 70, 80)]
time_to_output = 2
start = datetime.now()

for frame in frames:
self.json_parser.add_frame(frame)
sleep(1)
for i in range(len(bbox_ids)):
self.json_parser.add_bbox_to_frame(frame, bbox_ids[i], *bbox_xywh[i])
self.json_parser.schedule_output(output_path=self.out_path, hours=0, minutes=0, seconds=time_to_output)
end = datetime.now()
saved_files = listdir(self.out_path)
self.assertEqual(int((end - start).seconds / time_to_output), len(saved_files))

if __name__ == '__main__':
unittest.main()

انجام آزمایش خروجی
چرا mkdtemp؟
تابع mkdtemp از کتابخانه tempfile از یک منبع موقتی در سیستم استفاده کرده و یک پوشه موقت هم ایجاد می‌کند. این پوشه برای ذخیره کردنِ json به منظور آزمایش موقت در آنجا ذخیره می‌شود.

[irp posts=”10418″]

باید این فرایند بیش از یک ثانیه طول بکشد تا ببینیم json به صورت خودکار ذخیره می‌شود یا خیر. برای اینکه تاخیر زیادی در فرایند اتفاق نیفتد، از ویدئو در آزمایش استفاده نمی‌شود.
اکنون باید کد زیر را به اجرا درآوریم:

import json
from os import makedirs
from os.path import exists, join
from bunch import bunchify
from datetime import datetime

class JsonMeta(object):
HOURS = 4
MINUTES = 59
SECONDS = 59
PATH_TO_SAVE = 'jsons'

class JsonParser:

# ....
# I did not include the rest of code to let you
# just find the update to code

def json_output(self, output_name):
if not output_name.endswith('.json'):
output_name += '.json'
with open(output_name, 'w') as file:
json.dump(self.output(), file)

def set_start(self):
self.start_time = datetime.now()

def schedule_output(self, output_path=JsonMeta.PATH_TO_SAVE, hours: int = 0, minutes: int = 0, seconds: int = 60):
end = datetime.now()
interval = 0
interval += min([hours, JsonMeta.HOURS]) * 3600
interval += min([minutes, JsonMeta.MINUTES]) * 60
interval += min([seconds, JsonMeta.SECONDS])
diff = (end - self.start_time).seconds

if diff > interval:
output_name = self.start_time.strftime('%Y-%m-%d %H-%M-%S') + '.json'
output = join(output_path, output_name)
if not exists(output_path):
makedirs(output_path)
self.json_output(output_name=output)
self.frames.clear()
self.start_time = datetime.now()

اضافه کردن json_output و schedule_output

JsonMeta به چه دردی می‌خورد؟ دلیل استفاده از JsonMeta این است که می‌خواهیم بعضی از مقادیر مانند ثانیه، دقیقه و ساعت را به صورت پیش فرض قرار دهیم تا مقادیر مورد استفاده در در تابع schedule_output را کنترل کنیم. به کلاس JsonMeta توجه کنید:

پروژه تشخیص اشیاء

کلاس JsonMeta
بگذارید ببینیم آیا آزمایش با موفقیت انجام شده است یا خیر:

پروژه تشخیص اشیاء

بسیار عالی! همه آزمایش‌ها پاس شده است.
در نهایت از تابع زیر می‌توان برای افزودن جزئیات ویدئو به json استفاده کرد:

پروژه تشخیص اشیاء

پیشنهاد برای کارهای آتی

اکنون ابزاری در اختیار داریم که برای ذخیره json در سیستم نظارت لحظه‌ای مفید است. توصیه می‌کنم ویژگی‌های زیر را برای تمرین هم که شده، اضافه کنید:
1. دسته دیگری ایجاد کنید که قادر به تجزیه و تحلیل داده‌های json باشد.
2. تابعی ایجاد کنید بتواند با بازسازی bboxها در فریم ویدئو، موارد شناسایی را ذکر کرده و نتایج را نشان دهد.
3. سعی کنید کد را در کد پروژه تشخیص اشیاء مورد استفاده قرار دهید.
کل کد پروژه تشخیص اشیاء در این لینک بارگذاری شده است.

میانگین امتیاز / 5. تعداد ارا :

مطالب پیشنهادی مرتبط

اشتراک در
اطلاع از
0 نظرات
بازخورد (Feedback) های اینلاین
مشاهده همه دیدگاه ها
[wpforms id="48325"]