溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么在Python3.5 中利用OpenCV實(shí)現(xiàn)一個(gè)手勢(shì)識(shí)別功能

發(fā)布時(shí)間:2020-12-22 11:56:32 來(lái)源:億速云 閱讀:216 作者:Leah 欄目:開(kāi)發(fā)技術(shù)

怎么在Python3.5 中利用OpenCV實(shí)現(xiàn)一個(gè)手勢(shì)識(shí)別功能?相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。

OpenCV用攝像頭捕獲視頻

采用方法:調(diào)用OpenCV——cv2.VideoCapture()

def video_capture():
 cap = cv2.VideoCapture(0)
 while True:
 # capture frame-by-frame
 ret, frame = cap.read()

 # our operation on the frame come here
 # gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 可選擇灰度化

 # display the resulting frame
 cv2.imshow('frame', frame)
 if cv2.waitKey(1) & 0xFF == ord('q'): # 按q鍵退出
 break
 # when everything done , release the capture
 cap.release()
 cv2.destroyAllWindows()

效果如下

怎么在Python3.5 中利用OpenCV實(shí)現(xiàn)一個(gè)手勢(shì)識(shí)別功能

膚色識(shí)別——橢圓膚色檢測(cè)模型

參考下述博文

https://www.jb51.net/article/202594.htm

代碼如下

def ellipse_detect(img):
 # 橢圓膚色檢測(cè)模型
 skinCrCbHist = np.zeros((256, 256), dtype=np.uint8)
 cv2.ellipse(skinCrCbHist, (113, 155), (23, 15), 43, 0, 360, (255, 255, 255), -1)

 YCRCB = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)
 (y, cr, cb) = cv2.split(YCRCB)
 skin = np.zeros(cr.shape, dtype=np.uint8)
 (x, y) = cr.shape
 for i in range(0, x):
 for j in range(0, y):
 CR = YCRCB[i, j, 1]
 CB = YCRCB[i, j, 2]
 if skinCrCbHist[CR, CB] > 0:
 skin[i, j] = 255
 dst = cv2.bitwise_and(img, img, mask=skin)
 return dst

效果如下,可見(jiàn)與膚色相近的物體全被提取出來(lái),包括桌子。。。
識(shí)別時(shí)需尋找一無(wú)干擾環(huán)境

怎么在Python3.5 中利用OpenCV實(shí)現(xiàn)一個(gè)手勢(shì)識(shí)別功能

去噪——濾波、腐蝕和膨脹

參考下述博文

https://www.jb51.net/article/202599.htm

采用方法:高斯濾波 cv2.GaussianBlur() + 膨脹 cv2.dilate(),代碼如下

# 膨脹
def dilate_demo(image):
 # 灰度化
 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
 # 二值化
 ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
 # 定義結(jié)構(gòu)元素的形狀和大小
 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
 # 膨脹操作
 dst = cv2.dilate(binary, kernel)
 return dst


# 腐蝕
def erode_demo(image):
 # 灰度化
 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
 # 二值化
 ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
 # 定義結(jié)構(gòu)元素的形狀和大小
 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15, 15))
 # 腐蝕操作
 dst = cv2.erode(binary, kernel)
 return dst


# 濾波
def img_blur(image):
 # 腐蝕操作
 # img_erode = erode_demo(image)
 # 膨脹操作
 img_dilate = dilate_demo(image)

 # 均值濾波
 # blur = cv2.blur(image, (5, 5))
 # 高斯濾波
 blur = cv2.GaussianBlur(img_dilate, (3, 3), 0)
 return blur

Canny邊緣檢測(cè)

參考OpenCV中文教程

https://www.kancloud.cn/aollo/aolloopencv/271603

代碼如下

# Canny邊緣檢測(cè)v
def canny_detect(image):
 edges = cv2.Canny(image, 50, 200)
 return edges

識(shí)別——輪廓匹配

Tensorflow框架實(shí)在太難搭,搭了半天沒(méi)搭出來(lái),還一堆錯(cuò)誤。。。所以采用輪廓匹配 cv2.matchShapes() ,方案如下:

  • 劃分出了一個(gè)手勢(shì)識(shí)別區(qū)域,可避免周圍環(huán)境的干擾,也可簡(jiǎn)化圖像處理過(guò)程

  • 尋找輪廓時(shí)采用尋找矩形框架 cv2.boundingRect()的方法找到最大輪廓,即手勢(shì)的輪廓

  • 將找到的輪廓直接與標(biāo)準(zhǔn)圖片進(jìn)行匹配,簡(jiǎn)化識(shí)別過(guò)程

但在匹配時(shí)發(fā)現(xiàn)“剪刀”的手勢(shì)常與“石頭”、“布”的手勢(shì)匹配到一起。。。所以另辟蹊徑,在匹配時(shí)加上了對(duì)于矩形框架面積的判斷,一般來(lái)說(shuō)有如下規(guī)律,石頭<剪刀<布,代碼如下

 # 輪廓匹配
 value = [0, 0, 0]
 value[0] = cv2.matchShapes(img_contour, img1, 1, 0.0)
 value[1] = cv2.matchShapes(img_contour, img2, 1, 0.0)
 value[2] = cv2.matchShapes(img_contour, img3, 1, 0.0)
 min_index = np.argmin(value)
 if min_index == 0: # 剪刀
  print(text[int(min_index)], value)
 elif min_index == 1 and w*h < 25000: # 石頭
  print(text[int(min_index)], value)
 elif min_index == 1 and w*h >= 25000: # 剪刀
  print(text[0], value)
 elif min_index == 2 and w * h > 30000: # 布
  print(text[int(min_index)], value)
 elif min_index == 2 and w * h <= 30000: # 剪刀
  print(text[0], value)

程序會(huì)根據(jù)匹配值和面積大小來(lái)決定識(shí)別結(jié)果,例如,下述結(jié)果,1.179515828609219, 0.9604643714904955, 0.9896353720020925分別對(duì)應(yīng)剪刀、石頭、布的匹配值,越小說(shuō)明越吻合;結(jié)合最終識(shí)別情況來(lái)看,在三種手勢(shì)中,石頭的識(shí)別成功率最高,約98%;布其次,約88%;剪刀最低,約80%,而且結(jié)果易受環(huán)境亮度影響,環(huán)境過(guò)暗或過(guò)亮,有時(shí)候手勢(shì)輪廓都出不來(lái)。。??磥?lái)仍有待改進(jìn),還是得用機(jī)器學(xué)習(xí)的方法

石頭 [1.179515828609219, 0.9604643714904955, 0.9896353720020925]

看完上述內(nèi)容,你們掌握怎么在Python3.5 中利用OpenCV實(shí)現(xiàn)一個(gè)手勢(shì)識(shí)別功能的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI