از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
تقسیمبندی نمونه با YOLOv7 در پایتون
سرفصلهای مطلب
معرفی
تشخیص اشیا میدان بزرگی در بینایی کامپیوتری است و یکی از مهمترین کاربردهای بینایی کامپیوتر در طبیعت است. از آن، بخشبندی نمونه استخراج شد، و وظیفه دارد مدلها نه تنها برچسب و جعبه مرزی یک شی را پیشبینی کنند، بلکه «منطقه» آن را نیز پیشبینی کنند – طبقهبندی هر پیکسلی که به آن شی تعلق دارد.
Semantic Segmentation تمام پیکسل های یک تصویر را به آنها طبقه بندی می کند معنایی برچسب (ماشین، پیاده رو، ساختمان). تقسیم بندی نمونه طبقه بندی می کند تمام پیکسل های هر شی شناسایی شده به صورت جداگانه، و ماشین 1 متمایز است از ماشین 2.
از نظر مفهومی – آنها مشابه هستند، اما تقسیمبندی نمونه، تقسیمبندی معنایی و تشخیص شی را ترکیب میکند. خوشبختانه، تشخیص اشیاء، بخشبندی معنایی و تقسیمبندی نمونه بسط، میتواند با یک بکاند مشترک، با سرهای مختلف شبکه انجام شود، زیرا وظیفه آنها از نظر مفهومی مشابه است، و بنابراین نمایشهای محاسباتی آن دانش را به اشتراک میگذارند.
تشخیص اشیاء، بخشبندی معنایی، تقسیمبندی نمونه و تشخیص نقاط کلیدی به اندازه طبقهبندی تصویر استاندارد نیستند، عمدتاً به این دلیل که بیشتر پیشرفتهای جدید بهجای کتابخانهها و چارچوبهای بزرگ، معمولاً توسط محققان، نگهداریکنندگان و توسعهدهندگان انجام میشود. بستهبندی اسکریپتهای کاربردی ضروری در چارچوبی مانند TensorFlow یا PyTorch و حفظ دستورالعملهای API که تاکنون توسعه را هدایت کردهاند، دشوار است.
خوشبختانه برای توده ها – Ultralytics یک API تشخیص شی ساده، بسیار قدرتمند و زیبا در اطراف YOLOv5 خود ایجاد کرده است که توسط سایر تیم های تحقیق و توسعه به نسخه های جدیدتر مانند YOLOv7 گسترش یافته است.
در این راهنمای کوتاه، ما نمونهسازی را در پایتون با پیشرفتهترین YOLOv7 انجام خواهیم داد.
YOLO و تقسیمبندی نمونه
یولو (شما فقط یک بار نگاه می کنید) یک متدولوژی و همچنین خانواده ای از مدل های ساخته شده برای تشخیص اشیا است. از زمان آغاز به کار در سال 2015، YOLOv1، YOLOv2 (YOLO9000) و YOLOv3 توسط همان نویسنده(ها) پیشنهاد شده اند – و جامعه یادگیری عمیق با پیشرفت های منبع باز در سال های ادامه دار ادامه داد.
Ultralytics’ YOLOv5 یک مخزن عظیم و اولین پیاده سازی در سطح تولید YOLO در PyTorch است که کاربرد عمده ای در صنعت داشته است. پیاده سازی PyTorch آن را بیش از هر زمان دیگری در دسترس قرار داد، که معمولاً در ++C انجام می شد، اما دلیل اصلی محبوبیت آن به دلیل API بسیار ساده و قدرتمندی است که در اطراف آن ساخته شده است، که به هر کسی اجازه می دهد چند خط پایتون را اجرا کند. کدی که قادر به ساخت آشکارسازهای شی است.
YOLOv5 چنان به یک عنصر اصلی تبدیل شده است که اکثر مخازن که هدفشان پیشرفت روش YOLO است از آن به عنوان پایه استفاده می کنند و API مشابهی را ارائه می دهند که از Ultralytics به ارث رسیده است. YOLOR (شما فقط یک نمایش یاد می گیرید) دقیقاً این کار را انجام داد و YOLOv7 ساخته شد روی بالای YOLOR توسط همان نویسندگان.
YOLOv7 اولین مدل YOLO است که با سر مدلهای جدید عرضه میشود و امکان نقاط کلیدی، تقسیمبندی نمونهها و تشخیص اشیاء را فراهم میکند، که افزوده بسیار معقولی بود. امیدواریم در آینده شاهد تعداد فزایندهای از مدلهای مبتنی بر YOLO باشیم که قابلیتهای مشابهی را ارائه میکنند.
این باعث میشود که قطعهبندی نمونه و تشخیص نقاط کلیدی با معماری سادهتر از آشکارسازهای دو مرحلهای سریعتر از همیشه انجام شود.
خود این مدل از طریق تغییرات معماری و همچنین بهینهسازی جنبههای آموزش ایجاد شده است که به آن «bag-of-freebies» میگویند که دقت را بدون افزایش هزینه استنتاج افزایش میدهد.
تقسیمبندی نمونه با YOLOv7
یک کتابخانه استاندارد که برای نمونهبندی، تشخیص اشیا و تخمین نقاط کلیدی در پایتون استفاده میشود Detectron2 است که توسط Meta AI ساخته شده است.
این کتابخانه روشها و کلاسهای راحتی مختلفی را برای کمک به تجسم زیبای نتایج ارائه میکند، اما پیادهسازی اساسی برای تشخیص، Mask R-CNN است. نشان داده شده است که YOLO در کل از مدل های مبتنی بر R-CNN بهتر عمل می کند. مخزن YOLOv7 با Detectron2 سازگار است و با API و ابزارهای تجسم سازگار است، و اجرای تقسیمبندی سریع و دقیق نمونه بدون نیاز به یادگیری API جدید را آسانتر میکند. شما می توانید در واقع، swap ستون فقرات Mask R-CNN را خارج کنید و آن را با YOLOv7 جایگزین کنید.
نصب Dependencies – YOLOv7 و Detectron2
بیایید ابتدا پیش برویم و وابستگی ها را نصب کنیم. ما مخزن GitHub را برای پروژه YOLOv7 کلون می کنیم و آخرین نسخه Detectron2 را از طریق نصب می کنیم. pip
:
! git clone -b mask https://github.com/WongKinYiu/yolov7.git
! pip install pyyaml==5.1
! pip install 'git+https://github.com/facebookresearch/detectron2.git'
Detectron2 نیاز دارد pyyaml
همچنین. برای اطمینان از سازگاری، شما همچنین می خواهید در حال اجرا را مشخص کنید torch
نسخه:
! pip install torch==1.10.1+cu111 torchvision==0.11.2+cu111 torchaudio==0.10.1 -f https://download.pytorch.org/whl/torch_stable.html
شاخه اصلی YOLOv7 از تقسیمبندی نمونه پشتیبانی نمیکند، زیرا وابستگی دارد روی یک پروژه شخص ثالث با این حال mask
شعبه دقیقاً برای این پشتیبانی ساخته شده است، بنابراین ما در حال نصب آن هستیم mask
شعبه پروژه در نهایت، میخواهید وزنهای از پیش آموزشدیدهشده را برای مدل تقسیمبندی نمونه به صورت دستی یا با استفاده از موارد زیر دانلود کنید:
%cd yolov7
! curl -L https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-mask.pt -o yolov7-mask.pt
ما ابتدا به yolov7
دایرکتوری (دایرکتوری دانلود شده حاوی پروژه) و سپس فایل وزن را در آنجا دانلود کنید. با آن – وابستگی های ما تنظیم شده است! اجازه دهید import بسته ها و کلاس هایی که استفاده خواهیم کرد:
import matplotlib.pyplot as plt
import torch
import cv2
import yaml
from torchvision import transforms
import numpy as np
from utils.datasets import letterbox
from utils.general import non_max_suppression_mask_conf
from detectron2.modeling.poolers import ROIPooler
from detectron2.structures import Boxes
from detectron2.utils.memory import retry_if_cuda_oom
from detectron2.layers import paste_masks_in_image
استنتاج تقسیمبندی نمونه با YOLOv7
بیایید ابتدا به تصویری که تقسیم بندی می کنیم نگاهی بیندازیم:
street_img = cv2.imread('../street.png')
street_img = cv2.cvtColor(street_img, cv2.COLOR_BGR2RGB)
fig = plt.figure(figsize=(12, 6))
plt.imshow(street_img)
این یک اسکرین شات از نمای زنده Google Maps است! از آنجایی که مدل از قبل آموزش داده نشده است روی بسیاری از کلاسها، احتمالاً فقط برای کلاسهایی مانند تقسیمبندی معنایی خواهیم دید “فرد”، ‘ماشین’و غیره بدون کلاس های “ریزدانه” مانند ‘چراغ راهنمایی و رانندگی’.
اکنون می توانیم به بارگذاری مدل و آماده سازی آن برای استنتاج بپردازیم. این hyp.scratch.mask.yaml
فایل حاوی تنظیماتی برای هایپرپارامترها است، بنابراین ابتدا آن را بارگذاری می کنیم، دستگاه فعال (GPU یا CPU) را بررسی می کنیم و مدل را از فایل وزنی که به تازگی دانلود کرده ایم بارگیری می کنیم:
with open('data/hyp.scratch.mask.yaml') as f:
hyp = yaml.load(f, Loader=yaml.FullLoader)
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
def load_model():
model = torch.load('yolov7-mask.pt', map_location=device)('model')
model.eval()
if torch.cuda.is_available():
model.half().to(device)
return model
model = load_model()
بعد، بیایید یک روش کمکی برای اجرای استنتاج ایجاد کنیم! ما می خواهیم که یک تصویر را بخواند، آن را تغییر شکل دهد و آن را به اندازه ورودی مورد انتظار اضافه کند، تبدیل ها را اعمال کند، آن را دسته بندی کند و به مدل منتقل کند:
def run_inference(url):
image = cv2.imread(url)
image = letterbox(image, 640, stride=64, auto=True)(0)
image = transforms.ToTensor()(image)
image = image.half().to(device)
image = image.unsqueeze(0)
output = model(image)
return output, image
output, image = run_inference('../street.png')
این تابع خروجی مدل و همچنین خود تصویر (بارگذاری شده، پرشده و پردازش شده) را برمیگرداند. خروجی یک دیکشنری است:
output.keys()
پیشبینیهایی که مدل انجام داده خام هستند – باید از آنها عبور کنیم non_max_supression()
، و از ROIPooler از Detectron2 استفاده کنید.
توجه داشته باشید: “تجمیع ROI” کوتاه است برای “منطقه مورد علاقه ادغام” و برای استخراج نقشه های ویژگی های کوچک برای وظایف تشخیص و تقسیم بندی اشیا، در مناطقی که ممکن است دارای اشیاء باشند، استفاده می شود.
inf_out = output('test')
attn = output('attn')
bases = output('bases')
sem_output = output('sem')
bases = torch.cat((bases, sem_output), dim=1)
nb, _, height, width = image.shape
names = model.names
pooler_scale = model.pooler_scale
pooler = ROIPooler(output_size=hyp('mask_resolution'),
scales=(pooler_scale,),
sampling_ratio=1,
pooler_type='ROIAlignV2',
canonical_level=2)
output, output_mask, _, _, _ = non_max_suppression_mask_conf(inf_out,
attn,
bases,
pooler,
hyp,
conf_thres=0.25,
iou_thres=0.65,
merge=False,
mask_iou=None)
در اینجا – پیشبینیهای مربوط به اشیاء و برچسبهای آنها را به دست آوردهایم output
و ماسک هایی که باید آن اشیاء را در آن بپوشاند output_mask
:
output(0).shape
output_mask(0).shape
این مدل 30 نمونه را در تصویر پیدا کرد که هر کدام دارای یک برچسب مرتبط با آنها بود. بیایید با کمک Detectron2 جعبه هایی برای نمونه های خود ایجاد کنیم Boxes
کلاس و متراکم کردن pred_masks
(که حاوی یک ماسک بولی هستند) به مجموعه ای از پیکسل ها که می توانیم روی تصویر اصلی اعمال کنیم:
pred, pred_masks = output(0), output_mask(0)
base = bases(0)
bboxes = Boxes(pred(:, :4))
original_pred_masks = pred_masks.view(-1,
hyp('mask_resolution'),
hyp('mask_resolution'))
pred_masks = retry_if_cuda_oom(paste_masks_in_image)(original_pred_masks,
bboxes,
(height, width),
threshold=0.5)
pred_masks_np = pred_masks.detach().cpu().numpy()
pred_cls = pred(:, 5).detach().cpu().numpy()
pred_conf = pred(:, 4).detach().cpu().numpy()
nimg = image(0).permute(1, 2, 0) * 255
nimg = nimg.cpu().numpy().astype(np.uint8)
nimg = cv2.cvtColor(nimg, cv2.COLOR_RGB2BGR)
nbboxes = bboxes.tensor.detach().cpu().numpy().astype(np.int)
این original_pred_masks
نشان دهنده ماسک های پیش بینی شده برای تصویر اصلی است:
original_pred_masks.shape
و در نهایت، میتوانیم نتایج را با استفاده از:
def plot_results(original_image, pred_img, pred_masks_np, nbboxes, pred_cls, pred_conf, plot_labels=True):
for one_mask, bbox, cls, conf in zip(pred_masks_np, nbboxes, pred_cls, pred_conf):
if conf < 0.25:
continue
color = (np.random.randint(255), np.random.randint(255), np.random.randint(255))
pred_img = pred_img.copy()
pred_img(one_mask) = pred_img(one_mask) * 0.5 + np.array(color, dtype=np.uint8) * 0.5
pred_img = cv2.rectangle(pred_img, (bbox(0), bbox(1)), (bbox(2), bbox(3)), color, 2)
if plot_labels:
label = '%s %.3f' % (names(int(cls)), conf)
t_size = cv2.getTextSize(label, 0, fontScale=0.1, thickness=1)(0)
c2 = bbox(0) + t_size(0), bbox(1) - t_size(1) - 3
pred_img = cv2.rectangle(pred_img, (bbox(0), bbox(1)), c2, color, -1, cv2.LINE_AA)
pred_img = cv2.putText(pred_img, label, (bbox(0), bbox(1) - 2), 0, 0.5, (255, 255, 255), thickness=1, lineType=cv2.LINE_AA)
fig, ax = plt.subplots(1, 2, figsize=(pred_img.shape(0)/10, pred_img.shape(1)/10), dpi=150)
original_image = np.moveaxis(image.cpu().numpy().squeeze(), 0, 2).astype('float32')
original_image = cv2.cvtColor(original_image, cv2.COLOR_RGB2BGR)
ax(0).imshow(original_image)
ax(0).axis("off")
ax(1).imshow(pred_img)
ax(1).axis("off")
تصویر کپی شده است، بنابراین ما تغییراتی را در محل به تصویر اعمال نمی کنیم، اما روی یک کپی. برای هر پیکسلی که بین تصویر ورودی و ماسک های پیش بینی شده مطابقت دارد، رنگی با کدورت اعمال می کنیم. 0.5
و برای هر شیء یک عدد را رسم می کنیم cv2.Rectangle()
که آن را از جعبه های مرزی در بر می گیرد (bbox
). اگر می خواهید برچسب هایی را ترسیم کنید، که ممکن است همپوشانی قابل توجهی برای آنها وجود داشته باشد، یک وجود دارد plot_labels
پرچم در plot_results()
امضای روش بیایید سعی کنیم تصویری را که قبلاً کار با آن را شروع کرده بودیم با و بدون برچسب ترسیم کنیم:
%matplotlib inline
plot_results(image, nimg, pred_masks_np, nbboxes, pred_cls, pred_conf, plot_labels=False)
%matplotlib inline
plot_results(image, nimg, pred_masks_np, nbboxes, pred_cls, pred_conf, plot_labels=True)
ما هر دو تصویر را ترسیم کردهایم – تصویر اصلی و قطعهبندی شده را در یک طرح. برای وضوح بالاتر، تنظیم کنید dpi
(نقطه در اینچ) آرگومان در subplots()
تماس بگیرید، و فقط تصویر را با نقشه/برچسب های تقسیم بندی پیش بینی شده رسم کنید تا شکل را به طور کامل اشغال کند.
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-03 04:50:03