استفاده از تبدیل Hough Circle برای شناسایی دایره های موجود در تصویر
به نام خدا و باسلام
در این مطلب قصد دارم یک کد به منظور پیدا کردن دایره هایی که درون یک تصویر وجود دارد بنویسم. برای این کار از تبدیل Hough Circle استفاده می کنم. اما این تبدیل چگونه کار می کند؟ مختصات یک دایره به صورت زیر است:
پس برای شناسایی هر دایره به سه پارامتر احتیاج داریم، مختصات مرکز و شعاع دایره. تبدیل Hough Circle نیز از یک محاسبه کننده سه بعدی برای این کار استفاده می کند. در جعبه افزار OpenCV، این تابع وجود دارد و یکی از پارامترهای مهم این تابع، تعیین روشی برای شناسایی دایره است؛ که بهترین روش، Hough Gradient Method است که براساس گرادیان لبه ها دایره ها شناسایی می کند. خب توضیح کافیه اجازه بدهید به کدنویسی بپردازیم.
1 2 3 4 5 6 7 8 |
# Import necessary packages import cv2 import numpy as np # Import image, convert it to gray and filter it img=cv2.imread("google.jpg") img=cv2.medianBlur(img,5) gray_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) |
ابتدا پکیج های مورد نیاز را وارد می کنیم. پکیج cv2 برای جعبه افزار OpenCV و Numpy برای محاسبات عددی هستند. سپس تصویر مورد نظر را بارگذاری می کنیم. در اینجا از لوگوی شرکت گوگل استفاده کردم.
چون تابع cv2.HoughCircles از لبه ها برای شناسایی دایره ها استفاده می کند، تصویر را از یک فیلتر بالاگذر (medinBlur) عبور می دهیم تا لبه ها صاف تر شوند. در آخر حتماً باید تصویر را از حالت رنگی به خاکستری تبدیل کنیم؛ چرا که تابع cv2.HoughCircles تنها بر روی تصاویر خاکستری عمل می کند.
1 2 3 |
# Use hough circle transform to detect all corcles in the image circles=cv2.HoughCircles(gray_img,cv2.HOUGH_GRADIENT,1,20,param1=50,param2=30,minRadius=0,maxRadius=0) circles=np.uint16(np.around(circles)) |
از تابع cv2.HoughCircles برای شناسایی دایره های درون تصویر استفاده می کنیم. خروجی این تابع شامل مختصات مرکز و شعاع دایره شناسایی شده است. یعنی دو المان اول مختصات مرکز و المان سوم شعاع دایره هستند. بد نیست توضیحی در مورد پارامترهای این تابع بدهم.
- پارامتر اول: تصویر خاکستری شده
- پارامتر دوم: روش شناسایی دایره ها است که در اینجا cv2.HOUGH_GRADIENT را انتخاب کرده ایم
- پارامتر سوم: مقسم رزولیشن است که توصیه می کنم همیشه مقدار ۱ را قرار دهید
- پارامتر چهارم: کمترین فاصله بین مرکز دایره های شناسایی شده است
- پارامتر پنجم (param1): حد بالای threshold برای شناسایی لبه ها است
- پارامتر ششم (param2): مقدار threshold محاسبه گر که برای پیدا کردن مرکز دایره ها استفاده می شود. هر چه این مقدار کمتر باشد دایره های بیشتری به اشتباه (دایره های ناخواسته) پیدا می شوند
- پارامترهای هفتم و هشتم: بیشترین و کمترین شعاع دایره
مقدار دهی به این پارامترها کاملاً سلیقه ای است و بیشتر به نیاز کاربر از این تابع بر می گردد. من مقادیر بالا را دادم. با استفاده از دستور np.around مقادیر بدست آمده از تابع را رند می کنیم و سپس آنها را از حالت uint8 به حالت uint16 تبدیل می کنیم.
1 2 3 4 5 6 7 8 9 10 11 12 |
# Draw circles and centers for i in circles[0,:]: # Draw the outer circles cv2.circle(img,(i[0],i[1]),i[2],(0,255,0),2) # Draw the center of the circles cv2.circle(img,(i[0],i[1]),2,(0,0,255),3) # Show the results cv2.imshow("Detected circles",img) cv2.waitKey(0) cv2.destroyAllWindows() |
خب در این مرحله می خواهیم دایره هایی که پیدا کردیم را به همراه مرکزشان بر روی تصویر اصلی مشخص کنیم. برای این کار از دستور cv2.circle استفاده خواهیم کرد. برای دایره ها از سه المان خروجی تابع cv2.HoughCircles استفاده خواهیم کرد و برای نمایش مرکز دایره فقط از دو المان اول تابع که مختصات مرکز هستند استفاده می کنیم. و در پایان نیز تصویر را نشان خواهیم داد. شکل زیر به ازای param1=50 و param2=30 خاصل شده است.
و به ازای param1=30 و param2=50 نتیجه زیر که بهتر است بدست آمد.
در پایان از لینک زیر می توانید کد و تصاویر را دانلود کنید.
به شدت اموزش مفیدی بود تشکراز شما
خواهش میکنم موفق باشید