خب توی این پست اول با یکی از ابزارهایی که opencv در اختیارمون میزاره تا توی فرایند تنظیم پارامترها کارمون راحت بشه آشنا میشیم و جلوتر سعی می کنم با یه مثال٬ کاربرد فیلتر هایی که توی پست قبلی گفتم٬ واضح تر بشه .
یکی از ابزارهایی که opencv داره و خیلی هم به کار میاد ساختن پنجره و بار هست . این ابزار به ما کمک می کنه که فیلتر هایی که داریم رو در لحظه مقدار دهی کنیم . مثلا فرض کنید ما تعداد لبه هایی که به کمک تابع canny تشخیص میدیدم رو بیشتر یا کمتر کنیم به کمک یک بار ساده میشه در لحظه مقدار پارامتر رو جوری تنظیم کرد که به اون حدی که مد نظر هست برسه و دیگه نیازی به این نیست دستی پارامتر ها رو تغییر بدیم .
def empty(a): pass cv2.namedWindow("Parameters") cv2.createTrackbar("Threshold1", "Parameters", 0, 255, empty) cv2.createTrackbar("Threshold2", "Parameters", 0, 255, empty)
خط سوم یه پنجره میسازه که اسمشو گذاشتیم parameters که قراره بار هایی که تو دو خط بعدی میسازیم توی این پنجره قرار بگیره دو خط بعدی هم بار ها رو میسازه که پارامتر اول اسم ٬ پارامتر دوم پنجره ای که توش قرار میگیرند پارامتر های سه و چهارم مین و ماکس بار هستش و پارامتر آخر تابعی هست که در صورت تغییر دادن بار اون تابع فراخونی میشه که تو این مثال تابعی فراخونی نمیشه (یعنی میشه اما رد میشه ).
نتیجه نهایی همچین چیزی میشه :
خب حالا کاری که ما می خوایم بکنیم اینه که از این بار ها برای تغییر لحظه ای فیلتر canny استفاده کنیم .
cap = cv2.VideoCapture(2) while True : success, img = cap.read() cv2.imshow("frame", img) cv2.imwrite("1.jpg",img)
مثل قبل ورودی رو تعیین می کنیم فقط به جای یه تصویر من دارم از وبکم میخونم که کار راحت تر باشه بقیه کارا هم مثل قبل که خروجی همچین چیزی میده :
من اینجا از یه سیب با بک گراند مشکی استفاده کردم که حداکثر کنتراستو داشته باشه .
imgBlur = cv2.GaussianBlur(img, (7,7), 1) cv2.imwrite("2.jpg",imgBlur)
imgGray = cv2.cvtColor(imgBlur, cv2.COLOR_BGR2GRAY) cv2.imwrite("3.jpg",imgGray)
کارای تکراری قبلی ٬ مات کردن برا کاهش نویز خاکستری کردن تصویر .
threshold1 = cv2.getTrackbarPos("Threshold1", "Parameters") threshold2 = cv2.getTrackbarPos("Threshold2", "Parameters") imgCanny = cv2.Canny(imgGray, threshold1, threshold2) cv2.imwrite("4.jpg", imgCanny)
خب اینجا ما میایم مقداری که بار هامون دارند رو توی دوتا متغییر میریزیم و این دوتا متغییر رو به عنوان پارامتر به تابع canny میدیم .
حالا اگه این پارامتر هارو تغییر بدیم میتونیم مقدار نویز رو کم و زیاد کنیم تا به یه مقدار دلخواه برسیم .
و به این شکل ما خیلی راحت ما یه برنامه shape_detection ساده ساختیم .
تشخیص شکل میتونه تو خیلی از مباحث مربوط به پردازش تصویر مثل تشخیص اشیا یا صورت به کار بیاد .
من یه تابع هم نوشتم که میتونه توی چسبوندن تصاویر و نشون دادن سیر تکامل یه فرایند پردازش تصویر کمک بکنه .
اینم کدش اما دیگه حوصله توضیحشو ندارم واقعا !
def stackImages(scale,imgArray): rows = len(imgArray) cols = len(imgArray[0]) rowsAvailable = isinstance(imgArray[0], list) width = imgArray[0][0].shape[1] height = imgArray[0][0].shape[0] if rowsAvailable: for x in range ( 0, rows): for y in range(0, cols): if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]: imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale) else: imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale) if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR) imageBlank = np.zeros((height, width, 3), np.uint8) hor = [imageBlank]*rows hor_con = [imageBlank]*rows for x in range(0, rows): hor[x] = np.hstack(imgArray[x]) ver = np.vstack(hor) else: for x in range(0, rows): if imgArray[x].shape[:2] == imgArray[0].shape[:2]: imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale) else: imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale) if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR) hor= np.hstack(imgArray) ver = hor return ver
یه موضوع دیگه ای هم که الان یادم اومد در مورد تابع های erode و dilate هستش . این دوتا تابع با هم دیگه خیلی استفاده میشن و دلیلشم اینه که همونطور که گفتم erode برای کاهش جزعیات و dilate برای افزایش هستش و مثلا یه استفاده ای که میشه اینه که ما تصویرمون یه سری نویز داره مثلا نقطه های سفید سفید توی صفحه هستش یه کاری که می کنند اینه که اول از تابع erode برای حذف این نویز ها استفاده می کنند اما اون جسمی که می خوایم تشخیص بده رو کوچک می کنه برای همین بعدش از تابع dilate استفاده میشه تا دوباره جسم مدنظر واضح تر بشه که تو تشخیص کمک بکنه این روش برای تشخیص اجسام دور خیلی کاربرد داره
الان توی تصویر بالا شکل راست بالا نویز داره ما میایم نویزو حذف می کنیم اما تصویرم کوچیک تر میشه کاری که می کنیم اینه که تصویرو تقویتش می کنم که قدرت تشخیص دوباره زیاد بشه حالا توی پست های بعدی بیشتر در موردش صحبت می کنم .
اینم کد کامل چیزی که پیاده سازی کردم امیدوارم که خوشتون اومده باشه و به کار بیاد .
import cv2 import numpy as np def stackImages(scale,imgArray): rows = len(imgArray) cols = len(imgArray[0]) rowsAvailable = isinstance(imgArray[0], list) width = imgArray[0][0].shape[1] height = imgArray[0][0].shape[0] if rowsAvailable: for x in range ( 0, rows): for y in range(0, cols): if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]: imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale) else: imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale) if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR) imageBlank = np.zeros((height, width, 3), np.uint8) hor = [imageBlank]*rows hor_con = [imageBlank]*rows for x in range(0, rows): hor[x] = np.hstack(imgArray[x]) ver = np.vstack(hor) else: for x in range(0, rows): if imgArray[x].shape[:2] == imgArray[0].shape[:2]: imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale) else: imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale) if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR) hor= np.hstack(imgArray) ver = hor return ver def empty(a): pass # Hesam Mohebi cv2.namedWindow("Parameters") cv2.createTrackbar("Threshold1", "Parameters", 0, 255, empty) cv2.createTrackbar("Threshold2", "Parameters", 0, 255, empty) cap = cv2.VideoCapture(2) while True :# Hesam Mohebi success, img = cap.read() print(img.shape) cv2.imshow("frame", img) cv2.imwrite("1.jpg",img) imgBlur = cv2.GaussianBlur(img, (7,7), 1) cv2.imwrite("2.jpg",imgBlur) imgGray = cv2.cvtColor(imgBlur, cv2.COLOR_BGR2GRAY) cv2.imwrite("3.jpg",imgGray) threshold1 = cv2.getTrackbarPos("Threshold1", "Parameters") threshold2 = cv2.getTrackbarPos("Threshold2", "Parameters") imgCanny = cv2.Canny(imgGray, threshold1, threshold2) cv2.imwrite("4.jpg", imgCanny) imgStack = stackImages(0.8, ([img,imgBlur], [imgGray,imgCanny])) cv2.imwrite("5.jpg", imgStack) cv2.imshow("res", imgStack)# Hesam Mohebi if cv2.waitKey(1) & 0xff == ord('q'): break