2016年12月18日 星期日

OPENCV(12)--追蹤顏色物件並利用它來做打磚塊遊戲


        這篇文章利用之前所介紹的OPENCV基礎方法來做一個可以追蹤顏色物件的範例。
首先我用3D印表機列印一個綠色的小物件,然後用筆電的內建webcam 抓取即時影像透過OPENCV的處裡來追蹤這個綠色物件的位置。然後可以畫出他移動的軌跡。接著利用這個特點把它應用在經典遊戲打磚塊擋板的控制,當該綠色物件往右移時打磚塊裡的擋板也會跟著往右移,往左移也跟著往左移,提供一種不需透過鍵盤或滑鼠就可以隔空操作擋板的方式,增加遊戲的樂趣。實際操作請觀看底下影片連結。

  主要處理步驟如下

1.開啟Web camera 擷取影像
       _, frame = cap.read()
2. 高斯模糊
     frame = cv2.GaussianBlur(frame,(77,77),0)
3.從BGR轉成HSV 色域
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
4.設定擷取綠色物件範圍
lower_green = np.array([60,50,50])
upper_green = np.array([80,255,255])
mask = cv2.inRange(hsv, lower_green, upper_green)
5.利用找出的mask 跟原圖做 Bitwise-AND
res = cv2.bitwise_and(frame,frame, mask= mask)
6.找出輪廓
        cv2.findContours(mask,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
7.找出輪廓之後便可以找出其質心或是面積周長
       M = cv2.moments(cnt)


<圖一>追蹤物件並劃出軌跡



<圖二>應用在打磚塊遊戲,擋板位置會跟著綠色物件X軸位置而移動




<Demo 影片>







<追蹤物件範例程式>

import cv2
import numpy as np
global cxx,cyy,cxx_last,cyy_last
cxx=0
cyy=0
cap = cv2.VideoCapture(0)
point=100
cxx_m=np.zeros(point)
cyy_m=np.zeros(point)
count=0

Green = np.uint8([[[0,255,0 ]]])
hsv_Green = cv2.cvtColor(Green,cv2.COLOR_BGR2HSV)
print (hsv_Green)

ret = cap.set(3,640)             ##Default is 640X480
ret = cap.set(4,480)             ##change to 320X240
while(1):
 # Take each frame
 _, frame = cap.read()
 frame = cv2.flip(frame,1)  #0:inves up/down 1:mirror (right/left)  -1:inves up/down ,right/left
 # Convert BGR to HSV
 frame2=frame.copy()
 frame = cv2.GaussianBlur(frame,(77,77),0)
 hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
 # define range of blue color in HSV
 lower_green = np.array([60,50,50])
 upper_green = np.array([80,255,255])
 # Threshold the HSV image to get only blue colors
 mask = cv2.inRange(hsv, lower_green, upper_green)
 mask_org=mask.copy()
 # Bitwise-AND mask and original image
 res = cv2.bitwise_and(frame,frame, mask= mask)

 ##=================================
 img2, contours, hierarchy = cv2.findContours(mask,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
 cx=np.zeros(len(contours))
 cy=np.zeros(len(contours))
 global cxx,cyy,cxx_last,cyy_last,count,cxx_m,cyy_m
 if len(contours)>0:
  cxx_last=cxx
  cyy_last=cyy
  if count1:
    cxx_m[count]=cxx
    cyy_m[count]=cyy
    count=count+1
  else:
   count=0
   cxx_m=np.zeros(point)
   cyy_m=np.zeros(point)
  
  cxx=0
  cyy=0
 
  print (len(contours))
  cnt = contours[0]
  M = cv2.moments(cnt)
  #print (M)
  if M['m00']>1:

   for i in range(len(contours)): 
    #global cxx,cyy
    cx[i] = int(M['m10']/M['m00'])
    cy[i] = int(M['m01']/M['m00'])
    cxx=cxx+cx[i]
    cyy=cyy+cy[i]
    
  #global cxx,cyy  
  cxx=cxx/(len(contours))
  cyy=cyy/(len(contours))

  if cxx>1:
   print ("Center=",cxx,cyy)
   #area = cv2.contourArea(cnt)
   #print("Area",area)
   #perimeter = cv2.arcLength(cnt,True)
   #print("perimeter=",perimeter)
   if cxx_last>1:
    cv2.circle(res,(int(cxx_last),int(cyy_last)), 5, (0,0,255), -1)
    cv2.circle(frame,(int(cxx_last),int(cyy_last)), 5, (0,0,255), -1)
   if count <(point-1):
    for j in range(0,(point-1),1):
     if  int(cxx_m[j+1])>0:
      cv2.line(res,(int(cxx_m[j]),int(cyy_m[j])),(int(cxx_m[j+1]),int(cyy_m[j+1])),(255,0,255),3)
      cv2.circle(res,(int(cxx_m[j]),int(cyy_m[j])), 10, (0,255,0), 0)
      cv2.line(frame,(int(cxx_m[j]),int(cyy_m[j])),(int(cxx_m[j+1]),int(cyy_m[j+1])),(255,0,255),3)
      cv2.circle(frame,(int(cxx_m[j]),int(cyy_m[j])), 10, (0,255,0), 0)
      #print(j,cxx_m[j],cyy_m[j])
 ##=================================

 cv2.drawContours(res, contours, -1, (255,0,0), 2)
 cv2.imshow('Frame',frame)
 #cv2.imshow('mask',mask_org)
 cv2.imshow('contours:',res)
 #cv2.imshow('res',res)
 k = cv2.waitKey(5) & 0xFF
 if k == 27:
  break
cv2.destroyAllWindows()



<打磚塊範例程式>
https://github.com/Ashing00/opencv_brick_game/tree/master



加入阿布拉機的3D列印與機器人的FB專頁
https://www.facebook.com/arbu00/


<其他有關OPENCV 文章>

機器學習(2)--使用OPENCV SVM實作手寫辨識
機器學習(1)--使用OPENCV KNN實作手寫辨識
OPENCV(11)--contours and convex hull(輪廓與凸包)
OPENCV(10)--Canny Edge Detection(Canny邊緣檢測)
OPENCV(9)--Image Gradients(圖像梯度)
OPENCV(8)--Histogram & Histograms Equalization(長條圖與長條圖均衡化)
OPENCV(7)--2D Convolution ,Image Filtering and Blurring (旋積,濾波與模糊)
OPENCV(6)--Trackbar(軌道桿)
OPENCV(5)--Drawing
OPENCV(4)--Grayscale,Binarization,Threshole(灰階化,二值化,閥值)
OPENCV(3)--Matplotlib pyplot bassic function
OPENCV(2)--Capture Video from Camera
OPENCV(1 )--How to install OPENCV in Python

<其他文章>
人工神經網路(2)--使用Python實作後向傳遞神經網路演算法(Backprogation artificial neature network)
人工神經網路(1)--使用Python實作perceptron(感知器)

<參考資料:>OPENCV官網
http://docs.opencv.org/3.1.0/index.html