شناسایی اجسام با استفاده از هیستوگرام آنها
به نام خداو با سلام ، در این برنامه با استفاده از تابع cv2.calcBackProject می خواهیم قسمتی از شی مورد نظر که درون تصویر وجود دارد را به این تابع بدهیم و تمام آن شی را برای ما استخراج کند. دقیقا مانند تابع cv2.inRange عمل می کند ولی با این تفاوت که برحسب هیستوگرام عمل می کند و نه محدوده رنگی. خب شروع کنیم.
1 2 3 4 5 6 7 8 9 |
#Import necessary pachages import cv2 import numpy as np #Read target iamge, resize that , change it's color space from BGR to HSV target=cv2.imread("strawberry.jpg") target=cv2.resize(target,None,fx=0.3,fy=0.3,interpolation=cv2.INTER_AREA) hsv_t=cv2.cvtColor(target,cv2.COLOR_BGR2HSV) cv2.imshow("HSV color space",hsv_t) |
1 2 3 4 5 6 |
#Import sample of object and change it's color space roi=cv2.imread("red_roi.jpg") hsv_r=cv2.cvtColor(roi,cv2.COLOR_BGR2HSV) #Compute sample's 1D histogram and normalize it to keep it in range roi_hist=cv2.calcHist([hsv_r],[0,1],None,[180,256],[0,180,0,256]) cv2.normalize(roi_hist,roi_hist,0,255,cv2.NORM_MINMAX) |
اکنون نمونه ای از توت فرنگی را درون متغیر roi ذخیره می کنیم و فضای رنگی آن را از BGR به HSV تغییر می دهیم. پس از آن هیستوگرام دوبعدی ان را توسط تابع cv2.calcHist محاسبه می کنیم. اولین ورودی این تابع، تصویر نمونه در غالب HSV، دومین روردی تعداد کانال ها که در اینجا دو کانال انتخاب شده است. سومین ورودی ماسک است که مقدار آن را None می دهیم. ورودی چهارم تعداد BINS های هیستوگرام و آخرین ورودی محدوده کانال هاست. پس از محاسبه هیستوگرام لازم است ان را نرمالیزه کنیم تا هیستوگرام در محدود درست قرار بگیرد. شکل زیر نمونه ای از توت فرنگی است.
1 2 3 |
#Calculate back priject of sample in main image. It's give us a mask base on object dst=cv2.calcBackProject([hsv_t],[0,1],roi_hist,[0,180,0,256],1) cv2.imshow("Mask",dst) |
در این مرحله با استفاده از تابع cv2.calcBackProject و با استفاده از تصویر اصلی و هیستوگرام نمونه توت فرنگی، ماسکی می سازیم که فقط توت فرنگی در آن وجود دارد. ورودی اول این تابع تصویر اصلی، ورودی دوم هیستوگرام نمونه، سومین ورودی محدوده کانال های هیستوگرام و آخرین پارامتر ورودی، مقیاس تصویر خروجی نسبت به تصویر ورودی است که در اینجا تصویر خروجی را هم اندازه تصویر ورودی در نظر گرفته ایم. شکل زیر ماسک ساخته شده توس تابع Cv2.calcBackProject را نمایش می دهد.
1 2 3 4 5 6 7 8 9 10 11 12 |
#Define and use a filter to remove noises kernel=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)) cv2.filter2D(dst,-1,kernel,dst) # Extract object from main image using created mask by cv2.calcBackProject() res=cv2.bitwise_and(target,target,mask=dst) # Show results res=np.hstack([target,res]) cv2.imshow("Extracted object",res) cv2.waitKey(0) cv2.destroyAllWindows() |