تشخیص پوست بدن با OpenCV
در پست قبلی (تشخیص رنگ با استفاده از OpenCV و Python)، نحوه تشخیص رنگ های مختلف درون یک تصویر را با استفاده از دستور inRange آموزش دادم. اکنون با استفاده از این آموزش و کمی فیلترهای مختلف، قصد دارم برنامه ای برای تشخیص پوست بدن بنویسم. برای امتحان درستی کد از دوربین Raspberry pi استفاده می کنم. کدها توسط OpenCV 3.0.0 و Python 2.7 نوشته شده اند.
1 2 3 4 5 6 7 8 |
# import the necessary packages import numpy as np import cv2 # define the upper and lower boundaries of the HSV pixel # intensities to be considered 'skin' lower = np.array([0,48,80], dtype = "uint8") upper = np.array([189,224,255], dtype = "uint8") |
ابتدا پکیج های لازم را فراخوانی می کنیم. پکیج Numpy برای Numerical Processing و پکیج cv2 برای OpenCV است.
برای تشخیص رنگ، ساده ترین روش استفاده از حالت HSV نسبت به BGR است. چون می خواهیم از دستور inRange برای ساخت ماسک استفاده کنیم به همبن دلیل باید محدوده ای برای رنگ پوست انتخاب کنیم. با کمی جستجو در اینترنت می توانید رنگ پوست مورد نظر را بدست آورید.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
camera = cv2.VideoCapture(-1) # keep looping over the frames in the video while True: # grab the current frame success, frame = camera.read() #convert it to the HSV color space, # and determine the HSV pixel intensities that fall into # the speicifed upper and lower boundaries frame=cv2.resize(frame,(300,300),cv2.INTER_AREA) converted = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) skinMask = cv2.inRange(converted, lower, upper) |
چون می خواهیم از دوربین استفاده کنیم، پس با استفاده از دستور cv2.VideoCapture، استفاده از دوربین را آماده می کنیم.
برای اینکه عملیات پردازش بر روی هر فریم سریع تر انجام شود، بهتر است ابعاد فریم ها رو کوچکتر کنیم. به همین جهت، ابعاد فریم ها را به ۳۰۰ پیکسل کاهش می دهیم.
در قسمت بعدی هر فریم را از حالت BGR به HSV تبدیل می کنیم و در آخر توسط دستور inRange یک ماسک براساس رنگ پوست می سازیم.
1 2 3 4 5 6 7 8 9 10 |
# apply a series of erosions and dilations to the mask # using an elliptical kernel kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10, 10)) skinMask = cv2.erode(skinMask, kernel, iterations = 2) skinMask = cv2.dilate(skinMask, kernel, iterations = 2) # blur the mask to help remove noise, then apply the # mask to the frame skinMask = cv2.GaussianBlur(skinMask, (3, 3), 0) skin = cv2.bitwise_and(frame, frame, mask = skinMask) |
در برخی مواقع ممکن است قسمت های کوچک و اشتباهی در تصویر مشخص شوند. برای از بین بردن این قسمت ها از فیلترهای erode و dilate استفاده خواهیم کرد. ولی قبل از آن یک ماتریس به شکل ellipse طراحی می کنیم و ابعاد آن را ۱۰*۱۰ انتخاب می کنیم. توجه کنید هرچه ابعاد ماتریس بیشتر باشد عملیات پردازش کندتر ولی نتیجه با کیفیت بالاتری خواهد بوذ.
در مرحله بعدی با استفاده از دستور cv2.bitwise_and، هر فریم را باخودش و برحسب ماسک AND خواهیم کرد.
1 2 3 4 5 6 7 8 9 |
# show the skin in the image along with the mask cv2.imshow("images", np.hstack([frame, skin])) # if the 'q' key is pressed, stop the loop if cv2.waitKey(1) & 0xFF == ord("q"): break # cleanup the camera and close any open windows camera.release() cv2.destroyAllWindows() |
در آخر نوبت به نمایش نتیجه می رسد. برای خروج از برنامه از کلید q استفاده خواهیم کرد.