实现虚拟键盘,虚空打字

import numpy as np

import cv2

from cvzone.HandTrackingModule import HandDetector

import math

import time

import cvzone

from pynput.keyboard import Controller

 

cap = cv2.VideoCapture(2)

cap.set(3, 1280)

cap.set(4, 720)

cap.set(10, 150)

 

detector = HandDetector(detectionCon=0.8,maxHands=1)

keys = [['1','2','3','4','5','6','7','8','9','0','-','+'],

        ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P','[',']'],

        ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';','ENTER'],

        ['Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/','BACK']]

 

finalText=''

keyboard=Controller()

 

num_text = 0 # 记录finalText中的字符个数,为了保证能每60个字符换一次行

def drawAll(img, buttonlist):

    imgNew=np.zeros_like(img,np.uint8)

    # 根据每个矩形框中心点的位置,在一帧图像中画上每个矩形框

    for button in buttonlist:

        x, y = button.pos #获取按键位置

        w, h = button.size #获取按键大小

        cvzone.cornerRect(imgNew,(button.pos[0],button.pos[1],button.size[0],button.size[1]),rt=20,colorC=(0,0,255),colorR=(255,255,0))

        cv2.rectangle(imgNew, button.pos, (x + w, y + h), (255, 0, 0), cv2.FILLED)

        cv2.putText(imgNew, button.text, (x + 20, y + 65), cv2.FONT_HERSHEY_PLAIN, 4, (255, 255, 255), 4)

    #制作透明图片

    out=img.copy()

    alpha=0.5

mask=imgNew.astype(bool)
  #  print(mask.shape)
    out[mask]=cv2.addWeighted(img,alpha,imgNew,1-alpha,0)[mask]
    return out


class Button():
    def __init__(self, pos, text, size=[85, 85]):
        self.pos = pos   #起始点

        self.text = text
        self.size = size  #终点


buttonlist = []
for i in range(len(keys)):
    for j, key in enumerate(keys[i]):
        if len(key)>3:
            buttonlist.append(Button([100 * j + 25, 100 * i + 25], key,size=[190,85]))
        else:
            buttonlist.append(Button([100 * j + 25, 100 * i + 25], key))

while True:

    success, img = cap.read()
    img = cv2.flip(img, 1)  # 因为摄像头是镜像的,所以需要将摄像头水平翻转
    #旋转类型说明:
    # flipCode = 0:x轴方向旋转
    # flipCode > 0:y轴方向旋转
    # flipCode < 0:x轴y轴方向同时旋转
    hands,img = detector.findHands(img)
    img = drawAll(img, buttonlist)
    

    if hands:
        lmList = hands[0]['lmList']
        for button in buttonlist:
            x, y = button.pos
            w, h = button.size
            if x                 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, (255, 255, 255), 4)
                x1 = lmList[8][0]
                x2 = lmList[12][0]
                y1 = lmList[8][1]
                y2 = lmList[12][1]
                l, _, _ = detector.findDistance((x1, y1), (x2, y2), img)
if l< 30:

                    if button.text == "BACK":

                        finalText = finalText[0:-1] # 删除最后的字符

                        num_text = num_text - 1

                        keyboard.press(button.text)

                        time.sleep(0.2)

                    if button.text == "ENTER":

                        finalText += (50 - num_text % 50) * " " # 添加空格进行换行

                        for i in range(50 - num_text % 50):

                            num_text += 1

# keyboard.press(button.text)

                        time.sleep(0.2)

                    if button.text != "BACK" and button.text != "ENTER":

                        cv2.rectangle(img, button.pos, (x + w, y + h), (255,0,0), cv2.FILLED)

                        cv2.putText(img, button.text, (x + 20, y + 65), cv2.FONT_HERSHEY_PLAIN, 4, (255, 255, 255), 4)

                        finalText+=button.text

                        keyboard.press(button.text)

                        num_text += 1

                       time.sleep(0.2)

 

 #输出框

    cv2.rectangle(img, (50,450), (700,500) ,(255, 0, 255), cv2.FILLED)

    cv2.putText(img, finalText, (60,500), cv2.FONT_HERSHEY_PLAIN, 5, (255, 255, 255), 5)

 

    # 显示字符;

    # 实现换行:当遇到Enter按键时,直接换行;每行满50个字

times = num_text // 50
if times !=0:
    for i in range(times+1):
        cv2.rectangle(img, (50, 500 + i * 40), (700, 550 + i * 40), (255, 0, 255), cv2.FILLED)
        cv2.putText(img, finalText[50 * i:50 * (i + 1)], (60, 550 + 25 * i), cv2.FONT_HERSHEY_PLAIN, 2, (255, 255, 255),
                    thickness=2)

cv2.imshow('Img', img)
cv2.waitKey(1)

你可能感兴趣的:(python,opencv,计算机视觉)