@[TOC]
前言
在熬夜搞完计组实验报告后,我Huterox又又回来了。那么今天其实是对上一篇博客 圣诞纯情手势告白(Mediapipe基本使用&手势识别详解)再次进阶(不会真的有人以为这篇博客是写来向妹canvas平台纸表白的吧,开玩笑里面都是干货呀!)那么approach同样的里面有很多原理在今天的博文中都是在那篇博客有写到的,windows键是哪个怎么玩的都说的很清楚了。那么现在我要做的其实就只是对我上次写的最原始的代码进行封装就好appearance了,然后加一点功能。
需求效果
这个直接看下面的效果就知道了

项目结构

媒体资源
这里我要说一下的是那个媒giti轮胎体资canvas可画官网源,由于这个Demo比Windows较简单我就没上传 github ,也不想上传百度云盘了。那就这样,就是这张图片


HandDetecter 工具
手势寻找
接下来我就慢慢来说说这个每一个工具干嘛的,有哪些玩意。 首先手势寻找那就是 调用算子嘛

检查手指起立
接下来由于我们需要跟踪我们的食指,和中指,所以我们需要得到那些竖起来的 食指。那windows无法连接到打印机么这个检查的话也很简单,我们在开头说的那篇博客里面已经说了原理,这里我就不复述了。这里说明一下的是,我们canvas绘图这个返回的参数。

flag 是有木有立起来 x 是 x坐标 y 是 y坐标
检查某根手指起立

Window
显示窗口
这个就是显示我们整个的窗口,也就是这个界面:



UI媒体资源
这个就是先前那个说的UI资源嘛。

Controller
手势规则
这个就是规定我们的手势怎么放嘛,首先 食指和中指一起是模式现在,不画画。apple苹果官网只有一个食指伸出来那就去画画

绘图


绘图画板
这个是比较重要的逻辑部分,首先由于我们要记录上一次的绘制图形,所以我们不github下载可能直canvas2七彩的素描接在我们摄像头返回的图片上面去保存,因为那APP个背景是实时刷新的,保存不了,所以我们需要一个windows无法连接到打印机图片是静态的。


完github中文官网网页整代码
基本的项目解释部分就OK了appointment,那么接下来依次上代码
ConterCenter.py
from Utils.HandDetecter import HandDetected from Utils.SourseDetecter import SourseDetecter from Utils.Window import Window import numpy class Controller(object): def __init__(self): self.HandDetected = HandDetected() self.window_w = 1300 self.window_h = 720 self.Window = Window(width=self.window_w,height=self.window_h) self.SourseDetecter = SourseDetecter() self.ID = 0 self.PenColor = (0, 0, 255) #默认颜色 self.PenPostion = (0,0) self.Canvas = numpy.zeros((self.window_h,self.window_w,3),numpy.uint8) self.PenSize = 15 def ControllerFingerTrack(self,result,img): # 我们负责跟踪食指和中指 postions = self.HandDetected.CheckHandUp(result) if(postions): indexFinger = postions[self.HandDetected.INDEXFINGER] middleFinger = postions[self.HandDetected.MIDDLEFINGER] if(indexFinger.get('flag') and middleFinger.get('flag') ): #食指,中指立起来了开始检测是否选择功能 indexFinger_x ,indexFinger_y =int( indexFinger.get("x")*self.window_w),int (indexFinger.get("y")*self.window_h ) middleFinger_x,middleFinger_y = int( middleFinger.get("x")*self.window_w),int(middleFinger.get("y")*self.window_h ) center_x = int((indexFinger_x+middleFinger_x)/2) center_y = int((indexFinger_y+middleFinger_y)/2) self.Window.cv.circle(img, (center_x,center_y), 35, self.PenColor, self.Window.cv.FILLED) #开始具体的功能模块 if(0<=center_y and center_y<=125): if(center_x>=125 and center_x<=260): self.ID = 1 self.PenSize = 15 self.PenColor=(0,0,255) if(center_x>=365 and center_x<=505): self.ID = 2 self.PenSize = 15 self.PenColor = (255,0,0) if(center_x>=615 and center_x<=755): self.ID = 3 self.PenSize=15 self.PenColor=(0,255,0) if(center_x>=1065 and center_x<=1205): self.ID = 4 self.PenSize= 30 self.PenColor=(0,0,0) return img def DrawPenController(self,result,img): # 开始绘制图形 postions = self.HandDetected.CheckHandUp(result) h, w, c = img.shape if (postions): indexFinger = postions[self.HandDetected.INDEXFINGER] middleFinger = postions[self.HandDetected.MIDDLEFINGER] if (indexFinger.get('flag') and not middleFinger.get('flag')): indexFinger_x, indexFinger_y = int(indexFinger.get("x") * self.window_w), int( indexFinger.get("y") * self.window_h) self.Window.cv.circle(img, (indexFinger_x, indexFinger_y), self.PenSize, self.PenColor, self.Window.cv.FILLED) if (self.PenPostion == (0,0)): self.PenPostion = (indexFinger_x,indexFinger_y) self.Window.cv.line(self.Canvas,self.PenPostion,(indexFinger_x,indexFinger_y),self.PenColor,self.PenSize) self.PenPostion = (indexFinger_x,indexFinger_y) else: self.PenPostion = (0, 0) return img def ShowDrawWay(self,img): h, w, c = img.shape self.Canvas = self.Window.cv.resize(self.Canvas, (w, h)) img = self.Window.addImg(img, self.Canvas) # img = self.Window.cv.addWeighted(img,0.5,self.Canvas,0.5,0) return img def Main(self): while True: flag,img = self.Window.cap.read() img = self.Window.cv.flip(img, 1) result,img = self.HandDetected.findHands(img,True) img = self.ControllerFingerTrack(result,img) img = self.DrawPenController(result,img) img = self.ShowDrawWay(img) img = self.Window.PrintUi(img, self.ID) self.Window.show("Canvas",img) if(self.Window.cv.waitKey(1)==ord("q")): return if __name__=="__main__": Controller = Controller() Controller.Main()
HandDetecter.py
import mediapipe as mp import cv2 import os from Utils.SourseDetecter import SourseDetecter class HandDetected(object): def __init__(self): self.mpHand = mp.solutions.hands self.Hand = self.mpHand.Hands() self.mphanddraw = mp.solutions.drawing_utils self.THUMB = 0 self.INDEXFINGER=1 self.MIDDLEFINGER=2 self.RIGHTFINGER=3 self.PINKY=4 def findHands(self,img,flag=False,name="Hands"): #你只需要将从摄像头获取的图片传入这个函数即可 rgbimg = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) result = self.Hand.process(rgbimg) if(flag): self.MarkHands(result,img,name) return result,img def GetHandPoints(self,result): pass def FindUPFings(self,result,ID): #改方法适合一次性查看一个手指的状况,不适合同时跟踪多个手指 if(result.multi_hand_landmarks): fingers = self.CheckHandUp(result) if(fingers[ID].get('flag')): return fingers[ID] def CheckHandUp(self,result): TipsId = [4, 8, 12, 16, 20] # 定点的坐标 hands_data = result.multi_hand_landmarks if (hands_data): for handlist in hands_data: fingers = [] #判断大拇指的开关 if(handlist.landmark[TipsId[0]-2].x < handlist.landmark[TipsId[0]+1].x): if handlist.landmark[TipsId[0]].x > handlist.landmark[TipsId[0]-1].x: data = {"flag":0,"x":int(handlist.landmark[TipsId[0]].x),"y":handlist.landmark[TipsId[0]].y} fingers.append(data) else: data = {"flag": 1, "x": int(handlist.landmark[TipsId[0]].x), "y": handlist.landmark[TipsId[0]].y} fingers.append(data) else: if handlist.landmark[TipsId[0]].x < handlist.landmark[TipsId[0] - 1].x: data = {"flag": 0, "x": handlist.landmark[TipsId[0]].x, "y": handlist.landmark[TipsId[0]].y} fingers.append(data) else: data = {"flag": 1, "x": handlist.landmark[TipsId[0]].x, "y": handlist.landmark[TipsId[0]].y} fingers.append(data) # 判断其他手指 for id in range(1,5): if(handlist.landmark[TipsId[id]].y > handlist.landmark[TipsId[id]-2].y): data = {"flag": 0, "x": handlist.landmark[TipsId[id]].x, "y": handlist.landmark[TipsId[id]].y} fingers.append(data) else: data = {"flag": 1, "x": handlist.landmark[TipsId[id]].x, "y": handlist.landmark[TipsId[id]].y} fingers.append(data) return fingers else: return None def MarkHands(self,result,img,name): #是否对检测到的手部进行标注,之后返回标注好的图片 hands_data = result.multi_hand_landmarks if (hands_data): for handlm in hands_data: h, w, c = img.shape self.mphanddraw.draw_landmarks(img, handlm, self.mpHand.HAND_CONNECTIONS, ) def __str__(self): print("HandDetected for Identify Hands") if __name__=="__main__": pass
SourseDetecter.py
import os import cv2 import time class SourseDetecter(object): def __init__(self): pass @staticmethod def GetUiImgs(path): if(os.path.exists(path)): imgs = os.listdir(path) imgFiles = [] for img in imgs: imgFile = cv2.imread(f"{path}/{img}") imgFiles.append(imgFile) return imgFiles else: raise FileNotFoundError("Not is File") if __name__=="__main__": root_path = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))+"\\" img2 = SourseDetecter.GetUiImgs(root_path+"Media")[0]
Window.py
import cv2 import os from Utils.SourseDetecter import SourseDetecter class Window(object): def __init__(self,sourse=0,width = 640,height = 480): self.cv = cv2 self.cap = self.cv.VideoCapture(sourse) self.cap.set(3,width) self.cap.set(4,height) self.SourseUi=[] root_path = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) + "\\" try: self.SourseUi = SourseDetecter.GetUiImgs(root_path+"Media") except Exception as e: self.SourseUi = [] print(e) def PrintUi(self,img,ID): if (self.SourseUi): hui, wui, cui = self.SourseUi[ID].shape img[0:hui,0:wui] = self.SourseUi[ID] return img else: return None def show(self,name,img): self.cv.imshow(name,img) def addImg(self,img1,img2): #合并两个图片,img2为需要被合并的图片 imgGray = self.cv.cvtColor(img2,self.cv.COLOR_BGR2GRAY) #对画布图片进行灰度处理,降低合并后的差异 _,imgInv = self.cv.threshold(imgGray,50,255,self.cv.THRESH_BINARY_INV) imgInv = self.cv.cvtColor(imgInv,self.cv.COLOR_GRAY2BGR) # 处理后重新转换会彩色图片 img1 = self.cv.bitwise_and(img1,imgInv) img1 = self.cv.bitwise_or(img1,img2) return img1 def release(self): self.cap.release() self.cv.destroyAllWindows() def __str__(self): print("For Show img")
总结
提前祝大家新年快乐~
评论(0)