一. 介绍
OpenCV是最流行的计算机视觉任务库,它是用于机器学习、图像处理等的跨平台开源库,用于开发实时计算机视觉应用程序。
CVzone 是一个计算机视觉包,它使用 OpenCV 和 Media Pipe 库作为其核心,使我们易于运行,如手部跟踪、人脸检测、面部标志检测、姿势估计等,以及图像处理和其他计算机视觉。
二. 效果
三. 重点
多的我也就我讲了,网络上的其他博主写的也是非常好了,我这里就主要介绍那个避免一次输入多个相同的字母,以及如何一次输入相同的字母.
代码如下:
import cv2
import cvzone
from cvzone. HandTrackingModule import HandDetector
from time import sleep
import numpy as np
from pynput. keyboard import Controller
cap = cv2. VideoCapture( 0 , cv2. CAP_DSHOW)
cap. set ( 3 , 1280 )
cap. set ( 4 , 720 )
detector = HandDetector( detectionCon= 0.8 )
keyboard_keys = [ [ "Q" , "W" , "E" , "R" , "T" , "Y" , "U" , "I" , "O" , "P" ] ,
[ "A" , "S" , "D" , "F" , "G" , "H" , "J" , "K" , "L" , ";" ] ,
[ "Z" , "X" , "C" , "V" , "B" , "N" , "M" , "," , "." , "/" ] ]
final_text = ""
a = [ 1 ]
keyboard = Controller( )
def draw ( img, buttonList) :
for button in buttonList:
x, y = button. pos
w, h = button. size
cvzone. cornerRect( img, ( button. pos[ 0 ] , button. pos[ 1 ] ,
button. size[ 0 ] , button. size[ 0 ] ) , 20 , rt= 0 )
cv2. rectangle( img, button. pos, ( int ( x + w) , int ( y + h) ) , ( 255 , 144 , 30 ) , cv2. FILLED)
cv2. putText( img, button. text, ( x + 20 , y + 65 ) ,
cv2. FONT_HERSHEY_PLAIN, 4 , ( 0 , 0 , 0 ) , 4 )
return img
def transparent_layout ( img, buttonList) :
imgNew = np. zeros_like( img, np. uint8)
for button in buttonList:
x, y = button. pos
cvzone. cornerRect( imgNew, ( button. pos[ 0 ] , button. pos[ 1 ] ,
button. size[ 0 ] , button. size[ 0 ] ) , 20 , rt= 0 )
cv2. rectangle( imgNew, button. pos, ( x + button. size[ 0 ] , y + button. size[ 1 ] ) ,
( 255 , 144 , 30 ) , cv2. FILLED)
cv2. putText( imgNew, button. text, ( x + 20 , y + 65 ) ,
cv2. FONT_HERSHEY_PLAIN, 4 , ( 0 , 0 , 0 ) , 4 )
out = img. copy( )
alpaha = 0.5
mask = imgNew. astype( bool )
print ( mask. shape)
out[ mask] = cv2. addWeighted( img, alpaha, imgNew, 1 - alpaha, 0 ) [ mask]
return out
class Button ( ) :
def __init__ ( self, pos, text, size= [ 85 , 85 ] ) :
self. pos = pos
self. size = size
self. text = text
buttonList = [ ]
for k in range ( len ( keyboard_keys) ) :
for x, key in enumerate ( keyboard_keys[ k] ) :
buttonList. append( Button( [ 100 * x + 25 , 100 * k + 50 ] , key) )
while True :
success, img = cap. read( )
img = detector. findHands( img)
lmList, bboxInfo = detector. findPosition( img)
img = draw( img, buttonList)
if lmList:
for button in buttonList:
x, y = button. pos
w, h = button. size
if x < lmList[ 8 ] [ 0 ] < x + w and y < lmList[ 8 ] [ 1 ] < y + h:
cv2. rectangle( img, button. pos, ( x + w, y + h) ,
( 0 , 255 , 255 ) , cv2. FILLED)
cv2. putText( img, button. text, ( x + 20 , y + 65 ) ,
cv2. FONT_HERSHEY_PLAIN, 4 , ( 0 , 0 , 0 ) , 4 )
l, _, _ = detector. findDistance( 8 , 12 , img, draw= False )
if l < 15 :
print ( l, button. text)
a. append( button. text)
print ( a)
if button. text == a[ - 2 ] or button. text == '/' :
break
else :
keyboard. press( button. text)
cv2. rectangle( img, button. pos, ( x + w, y + h) ,
( 0 , 255 , 0 ) , cv2. FILLED)
cv2. putText( img, button. text, ( x + 20 , y + 65 ) ,
cv2. FONT_HERSHEY_PLAIN, 4 , ( 0 , 0 , 0 ) , 4 )
final_text += button. text
sleep( 0.20 )
cv2. rectangle( img, ( 25 , 350 ) , ( 700 , 450 ) ,
( 255 , 255 , 255 ) , cv2. FILLED)
cv2. putText( img, final_text, ( 60 , 425 ) ,
cv2. FONT_HERSHEY_PLAIN, 4 , ( 0 , 0 , 0 ) , 4 )
cv2. imshow( "output" , img)
cv2. waitKey( 1 )
四. 解释代码
主要就是增加了两个判断,如下,当两个手指的距离小于15才打印距离,减小了输出区的冗余,增加了一个列表 来存储小于15距离的字母,当列表里面的最后一个字母与当前的字母相同的时候就不输出,直接跳出,只打印一个字母,这就是去重的思想.
第二个就是增加一个无意义的字母,当输入这个字母的时候,什么都不用做,用来可以输入重复的字母.这里我选择了==/==作为无意义的字母,当然你也可以选择其他的符号.
if l < 15 :
print ( l, button. text)
a. append( button. text)
print ( a)
if button. text == a[ - 2 ] or button. text == '/' :
break
else :
keyboard. press( button. text)
cv2. rectangle( img, button. pos, ( x + w, y + h) ,
( 0 , 255 , 0 ) , cv2. FILLED)
cv2. putText( img, button. text, ( x + 20 , y + 65 ) ,
cv2. FONT_HERSHEY_PLAIN, 4 , ( 0 , 0 , 0 ) , 4 )
final_text += button. text
sleep( 0.20 )
五. 其他的说明
手指关节的对应的数字
知识体系
六. 这个就是我自己改进后的代码,希望大家共同学习提高.