Color Bubble Game With Opencv
က်ြန္ေတာ္ဒီtutorial ေလးကုိေရးျဖစ္သြားတာက game ကစားေနရင္းနဲ့ ငါ့blog reader ေတြလဲ ဒါမ်ိဳးေလးသိခ်င္မယ္ထင္လုိ့ပါ။အဲ့ေတာ့ ဒီေန့မွာ color bubble လုိ့နာမည္ေပးထားတဲ့ game ေလးကုိ computer vision beginners ေတြအတြက္ အသုံး၀င္မယ္ထင္ပါတယ္။
ဒီ tutorial မွာ သုံးသြားတာေတြကေတာ့
- Opencv-for image processing
- Dlib-facial landmark detection
က်ြန္ေတာ္တုိ့ video ကုိ ၾကည့္မယ္ဆုိ နွာေခါင္းေပါ္မွာ စက္၀ုိင္းဆြဲထားတာေတြ့ရမွာပါ။အဲ့လုိ နွာေခါင္းဘယ္နားမွာရွိလဲဆုိတာသိဖုိ့ dlib ကုိသုံးရပါတယ္။dlib သည္ ဒီထက္အသုံး၀င္တာအမ်ားၾကီးပါ။facial landmark detection တစ္ခုထဲမဟုတ္ပါဘူး။ထားပါ ဒီပုိ့စ္မွာ ဘယ္လုိမွအကုန္ေျပာဖုိ့အဆင္မေျပဘူး။ဒီမွာ opencv ကုိသုံးသြားတယ္ image processing အတြက္။ျပီးေတာ့ စေလ့လာတဲ့သူေတြကုိ မွာခ်င္တာက အရမ္းေတြ deep learning တု့ိကုိ အားမသန္ပါနဲ့ဦး traditional computer vision ကုိေလ့လာပါဦး။က်ြန္ေတ္ာေတြ့ေတြ့ေနရလုိ့ပါ။တူနဲ့ျပီးမယ့္ ကိစေတြမွာ ေသနတ္ေတြဘာေတြမသုံးပါနဲ့။
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
from imutils import face_utils import random import imutils import cv2 import dlib def is_collide(drawX,drawY,X,Y): print(drawX,drawY,X,Y) if abs(drawX-X) <= 10 and abs(drawY-Y) <= 10: return True return False def draw(frame,x,y,color_index): color = colors[color_index] y = y cv2.circle(frame,(x,y),20,color,-1) |
အဲ့ေတာ့ က်ြန္ေတ္ာတုိ့ ပထမဆုံး လိုအပ္တာေတြ import လုပ္ရမယ္။imutils သည္ image resize နဲ့ တျခား utility ေတြေတာ္ေတ္ာပါ၀င္ေတာ့ အရမ္းအသုံး၀င္ပါတယ္။ျပီးရင္ေတာ့ random ကေတာ့ bubble ေတြ က်ခ်င္တဲ့ ေနရာက က်လာေအာင္ random လုပ္ဖုိ့ပါ။
ျပီးေတာ့ function နွစ္ခုရွိတယ္ တစ္ခုကေတာ့ က်လာတဲ့ bubble နဲ့ က်ြန္ေတ္ာတုိ့ နွာေခါင္းက ဟာေလးနဲ့ တုိက္မိလားၾကည့္ဖုိ့ပါ။ေနာက္တစ္ခုကေတာ့ bubble ေတြကုိ ဆြဲဖုိ့ပါ။အရမ္းစိတ္မပူပါနဲ့ ေအာက္က code နဲ့တြဲၾကည့္ရင္ နားလည္သြားပါမယ္။
1 2 3 4 5 6 7 8 9 10 11 12 13 |
print("[INFO] Loading dlib...") detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") total_mark = 0 colors = [(0,0,255),(0,255,0),(255,0,0)] x,y = 0,0 color_index = random.randint(0,2) color_for_mark = random.randint(0,2) draw_x = random.randint(200,400) draw_y = 0 |
က်ြန္ေတာ္တုိ့ dlib ကုိသုံးမွာမုိ့လုိ့ dlib detector ကုိယူလုိက္ပါတယ္။ျပီးေတာ့ facial landmark ေတြသိရေအာင္လုိ့ predictor ကုိ ေခါ္ရပါတယ္။ဒီမွာ က်ြန္ေတာ္သည္ 68 landmarks ကုိသုံးထားပါတယ္။မလုိေတာ့မလုိပါဘူး။ဒီထက္ေသးတဲ့ landmark file ရွိပါတယ္။ပုိျမန္တာေပါ့ ေသးတာသုံးမယ္ဆုိ။
ျပီးေတာ့ က်ြန္ေတာ္တုိ့ colors ေတြကေတာ့ ဒီမွာ သုံးခုပဲေပါ့ blue green red နဲ့ တြက္ရပါမယ္။opencv သည္ color format ကုိ bgr နဲ့သြားပါတယ္။အဲ့ေတာ့ က်ြန္ေတာ္တုိ့ color list ထဲမွာ [red,green,blue]ရွိေနမွာပါ။နာက္တစ္ခုကေတာ့ color index နဲ့ color for mark ပါ။ color index ကေတာ့ က်လာတဲ့ ေဘာလုံးေတြအတြက္ random color ကုိ colors list ထဲကေနယူမွာပါ။color for mark ကေတာ့ နွာေခါင္းက mark ေလးက က်လာတဲ့ bubble နဲ့ထိသြားရင္ ျပန္ျပီး အေရာင္ခ်ိန္းသြားေအာင္ random လုပ္ယူဖုိ့ပါ။
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
cam = cv2.VideoCapture(0) while True: ret,frame = cam.read() frame = imutils.resize(frame,width=500) gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) rects = detector(gray, 0) # loop over the face detections for (i, rect) in enumerate(rects): shape = predictor(gray, rect) shape = face_utils.shape_to_np(shape) (x,y) = shape[30] cv2.circle(frame,(x,y),20,colors[color_for_mark],-1) |
က်ြန္ေတာ္တုိ့ ျပီးေတာ ့webcam camera ကုိယူတယ္။program runေနတဲ့အထိ webcam က data ယူရမွာမုိ့ while True: နဲ့ပတ္လုိက္ျပီး frame ကုိရယူလုိက္ပါတယ္။အဲ့ frame ကုိ gray color ေျပာင္းရတာက detect လုပ္ရမွာကပုိလြယ္သြားပါတယ္။ျပီးေတာ့ detector နဲ့ detect လုပ္ျပီး ရလာတဲ့ face ေပါ္မွာမွ predictor နဲ့ predict လုပ္လုိက္ေတာ့ facial landmark ေတြရလာပါတယ္။အဲ့ကမွ shape[30] ဆုိတာက 68 landmarks လုိ့က်ြန္ေတာ္ေျပာခဲ့ပါတယ္။ဒီမွာ 30 ေနရာသည္ နွာေခါင္းအေပါ္ကုိ ေျပာတာပါ။အဲ့တာေၾကာင့္ ၃၀ နဲ့ နွာေခါင္းအေပါ္ေနရာကုိ ယူျပီး circle ဆြဲလုိက္ပါတယ္။ဒါဆုိ နွာေခါင္းေပါ္ေတာ့ circle ဆြဲျပီးျပီမုိ့ အေပါ္ကေန က်လာေအာင္ ဆြဲဖုိ့ပဲက်န္ပါတယ္။
1 2 3 4 5 6 7 8 9 10 11 12 |
draw_y = draw_y + 10 if is_collide(draw_x,draw_y,x,y): if color_index == color_for_mark: total_mark += 10 else: total_mark -= 10 draw_y = 0 draw_x = random.randint(200,400) color_index = random.randint(0,2) color_for_mark = random.randint(0,2) continue |
က်ြန္ေတာ္တုိ့ ဒီမွာ သိထားရမွာက က်ြန္ေတာ္တုိ့ color bubble သည္ အေပါ္ကေန က်လာမွာမုိ့လုိ့ တေျဖးေျဖး ၁၀ တုိးျပီး ဆင္းခုိင္းတာပါ။ျပီးေတာ ့is_collide function ကုိၾကည့္မယ္ဆုိ က်ြန္ေတာ္တုိ့ လက္ရွိဆြဲလုိက္တဲ့ color bubble ရဲ့ x,y coordinateနဲ့ နွာေခါင္းက circle ရဲ့ x,y coordinate တုိ့ တုိက္မိတယ္ဆုိ က်ြန္ေတာ္တုိ့က အမွတ္ကုိတုိးေပးလုိက္ျပီး ဆြဲတဲ့ ေနရာေတြကုိ နဂုိတုိင္းျပန္ထားတာပါ။drawx ကုိ random လုပ္လုိက္ောတ့ ေနာက္တစ္ေနရာကေန ထပ္က်လာမွာပါ။color ေတြလဲခ်ိန္းမွာမုိ့ အားလုံးကုိ random ျပန္ေခါက္ျပီး ေအာက္က ဆြဲေနတယ့္အလုပ္ေတြမလုပ္ေအာင္လုိ့ continue နဲ့အေပါ္ျပန္တက္ပါတယ္။ဘာေၾကာင့္ ေအာက္က ဆြဲတယ့္အလုပ္မလုပ္ေစခ်င္တာလဲဆုိ ထိသြားမွေတာ့ ထိသြားတယ့္ bubble ကေပ်ာက္သြားေအာင္ပါ။
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
if not draw_y >= frame.shape[0] - 100: draw(frame,draw_x,draw_y,color_index) else: draw_y = 0 draw_x = random.randint(200,400) color_index = random.randint(0,2) frame = cv2.flip(frame,1) cv2.putText(frame, "Total Mark #{}".format(total_mark), (frame.shape[1]-300,20), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 0), 2) cv2.imshow("Image",frame) key = cv2.waitKey(1) & 0xFF if key == ord('q'): break cv2.destroyAllWindows() cam.release() |
အကယ္လုိ့ မတုိက္မိပဲ ဆြဲေနတဲ့ color bubble က ေအာက္ေရာက္သြားတယ္ဆုိ က်ြန္ေတာ္တုိ့ draw မလုပ္ေတာ့ပဲ ေနာက္အသစ္တစ္ခုအေပါ္ကေန က်လာေအာင္ ေရးထားပါတယ္။ျပီးေတာ့ က်ြန္ေတာ္တုိ့ ရလာတယ့္ frame သည္ webcam ကဆုိ ေျပာင္းျပန္ျဖစ္ေနပါတယ္။အဲ့တာေၾကာင့္မုိ့ flip လုပ္လုိက္ေတာ့ က်ြန္ေတာ္တုိ့မွန္ၾကည့္သလုိျမင္ရျပီး အဲ့ေပါ္မွာ အမွတ္ဘယ္ေလာက္ရလဲကုိေရးလုိက္ပါတယ္။ျပီးေတာ့ key ကုိေစာင့္ၾကည့္ပါတယ္။နွိပ္လုိ္ကတဲ့ key က သာ q ျဖစ္မယ္ဆုိ က်ြန္ေတ္ာတုိ့ program ကုိရပ္လုိက္တာပါ။ဒါေလးပါပဲ။အားလုံးနားလည္မယ္လုိ့ယံုၾကည္ပါတယ္။
ဒီprogram run မယ္ဆုိ dlib နဲ့ opencv installလုပ္ထားရပါမယ္။dlib facial landmark model ရွိရပါမယ္။code နဲ့ model ကုိေအာက္ကလင့္ကေန download လုပ္နုိင္ပါတယ္။installကေတာ့ လုိအပ္ရင္ လာေျပာနုိင္ပါတယ္။
Python Basic ကုိ Practical Way နဲ့ ျမန္ျမန္ဆန္ဆန္ ေလ့လာခ်င္တဲ့ သူမ်ားကေတာ့ က်ြန္ေတာ့္ online course ကုိ ဒီ link ကေန ၾကည့္နုိင္ပါတယ္။
Practical Python For Beginners