AI计算机视觉笔记八:基于mediapipe的虚拟绘画

简介: 该项目利用MediaPipe手部关键点识别技术,实现了隔空绘画功能。用户可以通过手势控制绘画工具,选择颜色或橡皮擦。环境配置基于`mediapipe_env`,在PyCharm中运行。项目包括两个文件:`AiVirtualPainter.py`负责绘画逻辑,`HandTrackingModule.py`用于手部关键点检测。此项目展示了AI技术在互动应用中的潜力,适合初学者实践与学习。

一、项目介绍

随着人工智能时代的到来,许多技术得到了空前的发展,让人们更加认识到了线上虚拟技术的强大。

通过mediapipe识别手的关键点,检测中指,实现隔空画画的操作。

通过两个手指的间距,实现点击选择颜色或橡皮檫。
image.png

二、运行

1、环境

环境搭建使用的是上一篇搭建的环境mediapipe_env

打开终端,输入下面命令,激活环境:

conda activate mediapipe
这次使用的是pycharm,软件自行安装,安装社区版本。

建立一个目录,把项目导入到pycharm里,然后设置环境

点击Add New Interpreter
image.png
选择环境的python.exeimage.png

终端选择,一定要powershell.exe
image.png
设置好可以在pycharm里的终端操作
image.png

2、运行

导入代码,右键运行
image.png

3 、结果

image.png

三、代码

这里不介绍原理及过程,想学习的人不会因为这些而去不学习,所以需要自行了解,项目难度不大,代码也相对的不复杂。直接上源码

一共两个文件,AiVirtualPainter.py和HandTrackingModule.py

AiVirtualPainter.py实现的是绘画功能,HandTrackingModule.py实现的是手关键点识别。

AiVirtualPainter.py

import cv2
import HandTrackingModule as htm
import os
import numpy as np


folderPath = "PainterImg/"
mylist = os.listdir(folderPath)
overlayList = []
for imPath in mylist:
    image = cv2.imread(f'{folderPath}/{imPath}')
    overlayList.append(image)
header = overlayList[0]
color = [255, 0, 0]
brushThickness = 15
eraserThickness = 40

cap = cv2.VideoCapture(0)  # 若使用笔记本自带摄像头则编号为0  若使用外接摄像头 则更改为1或其他编号
cap.set(3, 1280)
cap.set(4, 720)
# cap.set(3, 800)
# cap.set(4, 500)
detector = htm.handDetector()
xp, yp = 0, 0
imgCanvas = np.zeros((720, 1280, 3), np.uint8)  # 新建一个画板
# imgCanvas = np.zeros((500, 800, 3), np.uint8)  # 新建一个画板

while True:
    # 1.import image
    success, img = cap.read()
    img = cv2.flip(img, 1)  # 翻转

    # 2.find hand landmarks
    img = detector.findHands(img)
    lmList = detector.findPosition(img, draw=True)

    if len(lmList) != 0:
        x1, y1 = lmList[8][1:]
        x2, y2 = lmList[12][1:]

        # 3. Check which fingers are up
        fingers = detector.fingersUp()

        # 4. If Selection Mode – Two finger are up
        if fingers[1] and fingers[2]:
            if y1 < 153:
                if 0 < x1 < 320:
                    header = overlayList[0]
                    color = [50, 128, 250]
                elif 320 < x1 < 640:
                    header = overlayList[1]
                    color = [0, 0, 255]
                elif 640 < x1 < 960:
                    header = overlayList[2]
                    color = [0, 255, 0]
                elif 960 < x1 < 1280:
                    header = overlayList[3]
                    color = [0, 0, 0]
        img[0:1280][0:153] = header

        # 5. If Drawing Mode – Index finger is up
        if fingers[1] and fingers[2] == False:
            cv2.circle(img, (x1, y1), 15, color, cv2.FILLED)
            print("Drawing Mode")
            if xp == 0 and yp == 0:
                xp, yp = x1, y1

            if color == [0, 0, 0]:
                cv2.line(img, (xp, yp), (x1, y1), color, eraserThickness)  # ??
                cv2.line(imgCanvas, (xp, yp), (x1, y1), color, eraserThickness)
            else:
                cv2.line(img, (xp, yp), (x1, y1), color, brushThickness)   # ??
                cv2.line(imgCanvas, (xp, yp), (x1, y1), color, brushThickness)

        xp, yp = x1, y1
        # Clear Canvas when all fingers are up
        # if all (x >= 1 for x in fingers):
        #     imgCanvas = np.zeros((720, 1280, 3), np.uint8)

    # 实时显示画笔轨迹的实现
    imgGray = cv2.cvtColor(imgCanvas, cv2.COLOR_BGR2GRAY)
    _, imgInv = cv2.threshold(imgGray, 50, 255, cv2.THRESH_BINARY_INV)
    imgInv = cv2.cvtColor(imgInv, cv2.COLOR_GRAY2BGR)
    img = cv2.bitwise_and(img, imgInv)
    img = cv2.bitwise_or(img, imgCanvas)
    img[0:1280][0:153] = header

    cv2.imshow("Image", img)
    # cv2.imshow("Canvas", imgCanvas)
    # cv2.imshow("Inv", imgInv)
    cv2.waitKey(1)

HandTrackingModule.py

import cv2
import mediapipe as mp
import time
import math

class handDetector():
    def __init__(self, mode=False, maxHands=2, detectionCon=0.8, trackCon=0.8):
        self.mode = mode
        self.maxHands = maxHands
        self.detectionCon = detectionCon
        self.trackCon = trackCon

        self.mpHands = mp.solutions.hands
        self.hands = self.mpHands.Hands(self.mode, self.maxHands, self.detectionCon, self.trackCon)
        self.mpDraw = mp.solutions.drawing_utils
        self.tipIds = [4, 8, 12, 16, 20]

    def findHands(self, img, draw=True):
        imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        self.results = self.hands.process(imgRGB)

        print(self.results.multi_handedness)  # 获取检测结果中的左右手标签并打印

        if self.results.multi_hand_landmarks:
            for handLms in self.results.multi_hand_landmarks:
                if draw:
                    self.mpDraw.draw_landmarks(img, handLms, self.mpHands.HAND_CONNECTIONS)
        return img

    def findPosition(self, img, draw=True):
        self.lmList = []
        if self.results.multi_hand_landmarks:
            for handLms in self.results.multi_hand_landmarks:
                for id, lm in enumerate(handLms.landmark):
                    h, w, c = img.shape
                    cx, cy = int(lm.x * w), int(lm.y * h)
                    # print(id, cx, cy)
                    self.lmList.append([id, cx, cy])
                    if draw:
                        cv2.circle(img, (cx, cy), 12, (255, 0, 255), cv2.FILLED)
        return self.lmList

    def fingersUp(self):
        fingers = []
        # 大拇指
        if self.lmList[self.tipIds[0]][1] > self.lmList[self.tipIds[0] - 1][1]:
            fingers.append(1)
        else:
            fingers.append(0)

        # 其余手指
        for id in range(1, 5):
            if self.lmList[self.tipIds[id]][2] < self.lmList[self.tipIds[id] - 2][2]:
                fingers.append(1)
            else:
                fingers.append(0)

        # totalFingers = fingers.count(1)
        return fingers

    def findDistance(self, p1, p2, img, draw=True, r=15, t=3):
        x1, y1 = self.lmList[p1][1:]
        x2, y2 = self.lmList[p2][1:]
        cx, cy = (x1 + x2) // 2, (y1 + y2) // 2

        if draw:
            cv2.line(img, (x1, y1), (x2, y2), (255, 0, 255), t)
            cv2.circle(img, (x1, y1), r, (255, 0, 255), cv2.FILLED)
            cv2.circle(img, (x2, y2), r, (255, 0, 255), cv2.FILLED)
            cv2.circle(img, (cx, cy), r, (0, 0, 255), cv2.FILLED)
            length = math.hypot(x2 - x1, y2 - y1)

        return length, img, [x1, y1, x2, y2, cx, cy]


def main():
    pTime = 0
    cTime = 0
    cap = cv2.VideoCapture(0)
    detector = handDetector()
    while True:
        success, img = cap.read()
        img = detector.findHands(img)        # 检测手势并画上骨架信息

        lmList = detector.findPosition(img)  # 获取得到坐标点的列表
        if len(lmList) != 0:
            print(lmList[4])

        cTime = time.time()
        fps = 1 / (cTime - pTime)
        pTime = cTime

        cv2.putText(img, 'fps:' + str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 255), 3)
        cv2.imshow('Image', img)
        cv2.waitKey(1)


if __name__ == "__main__":
    main()

源码网上有很多,有不懂可以联系博主,一起相互交流。

学习永无止境,AI是未来的发展方向,每天进步一点点,实现终身学习。

相关文章
|
2月前
|
人工智能 测试技术 API
AI计算机视觉笔记二十 九:yolov10竹签模型,自动数竹签
本文介绍了如何在AutoDL平台上搭建YOLOv10环境并进行竹签检测与计数。首先从官网下载YOLOv10源码并创建虚拟环境,安装依赖库。接着通过官方模型测试环境是否正常工作。然后下载自定义数据集并配置`mycoco128.yaml`文件,使用`yolo detect train`命令或Python代码进行训练。最后,通过命令行或API调用测试训练结果,并展示竹签计数功能。如需转载,请注明原文出处。
|
21天前
|
机器学习/深度学习 人工智能 算法
打造你的超级Agent智能体——在虚拟迷宫中智斗未知,解锁AI进化之谜的惊心动魄之旅!
【10月更文挑战第5天】本文介绍了一个基于强化学习的Agent智能体项目实战,通过控制Agent在迷宫环境中找到出口来完成特定任务。文章详细描述了环境定义、Agent行为及Q-learning算法的实现。使用Python和OpenAI Gym框架搭建迷宫环境,并通过训练得到的Q-table测试Agent表现。此项目展示了构建智能体的基本要素,适合初学者理解Agent概念及其实现方法。
60 9
|
2月前
|
机器学习/深度学习 人工智能 PyTorch
AI计算机视觉笔记三十二:LPRNet车牌识别
LPRNet是一种基于Pytorch的高性能、轻量级车牌识别框架,适用于中国及其他国家的车牌识别。该网络无需对字符进行预分割,采用端到端的轻量化设计,结合了squeezenet和inception的思想。其创新点在于去除了RNN,仅使用CNN与CTC Loss,并通过特定的卷积模块提取上下文信息。环境配置包括使用CPU开发板和Autodl训练环境。训练和测试过程需搭建虚拟环境并安装相关依赖,执行训练和测试脚本时可能遇到若干错误,需相应调整代码以确保正确运行。使用官方模型可获得较高的识别准确率,自行训练时建议增加训练轮数以提升效果。
|
2月前
|
人工智能 开发工具 计算机视觉
AI计算机视觉笔记三十:yolov8_obb旋转框训练
本文介绍了如何使用AUTODL环境搭建YOLOv8-obb的训练流程。首先创建虚拟环境并激活,然后通过指定清华源安装ultralytics库。接着下载YOLOv8源码,并使用指定命令开始训练,过程中可能会下载yolov8n.pt文件。训练完成后,可使用相应命令进行预测测试。
|
2月前
|
人工智能 并行计算 测试技术
AI计算机视觉笔记三十一:基于UNetMultiLane的多车道线等识别
该项目基于开源数据集 VIL100 实现了 UNetMultiLane,用于多车道线及车道线类型的识别。数据集中标注了六个车道的车道线及其类型。项目详细记录了从环境搭建到模型训练与测试的全过程,并提供了在 CPU 上进行训练和 ONNX 转换的代码示例。训练过程约需 4 小时完成 50 个 epoch。此外,还实现了视频检测功能,可在视频中实时识别车道线及其类型。
|
3天前
|
机器学习/深度学习 人工智能 供应链
AI技术在医疗领域的应用与未来展望###
本文深入探讨了人工智能(AI)技术在医疗领域的多种应用及其带来的革命性变化,从疾病诊断、治疗方案优化到患者管理等方面进行了详细阐述。通过具体案例和数据分析,展示了AI如何提高医疗服务效率、降低成本并改善患者体验。同时,文章也讨论了AI技术在医疗领域面临的挑战和未来发展趋势,为行业从业者和研究人员提供参考。 ###
|
3天前
|
机器学习/深度学习 人工智能 算法
AI技术在医疗领域的应用与挑战
【10月更文挑战第21天】 本文探讨了人工智能(AI)在医疗领域的多种应用,包括疾病诊断、治疗方案推荐、药物研发和患者管理等。通过分析这些应用案例,我们可以看到AI技术如何提高医疗服务的效率和准确性。然而,AI在医疗领域的广泛应用也面临诸多挑战,如数据隐私保护、算法透明度和伦理问题。本文旨在为读者提供一个全面的视角,了解AI技术在医疗领域的潜力和面临的困难。
|
3天前
|
机器学习/深度学习 人工智能 搜索推荐
AI在医疗健康领域的应用与前景
随着科技的不断进步,人工智能(AI)技术已经深入到我们生活的方方面面,特别是在医疗健康领域。本文将探讨AI在医疗健康领域的应用现状、面临的挑战以及未来的发展前景。
|
4天前
|
人工智能 自然语言处理 监控
AI技术在文本情感分析中的应用
【10月更文挑战第22天】本文将探讨人工智能(AI)如何改变我们对文本情感分析的理解和应用。我们将通过实际的代码示例,深入了解AI如何帮助我们识别和理解文本中的情感。无论你是AI新手还是有经验的开发者,这篇文章都将为你提供有价值的信息。让我们一起探索AI的奇妙世界吧!
12 3
|
2天前
|
人工智能 分布式计算 数据可视化
大模型私有化部署全攻略:硬件需求、数据隐私、可解释性与维护成本挑战及解决方案详解,附示例代码助你轻松实现企业内部AI应用
【10月更文挑战第23天】随着人工智能技术的发展,企业越来越关注大模型的私有化部署。本文详细探讨了硬件资源需求、数据隐私保护、模型可解释性、模型更新和维护等方面的挑战及解决方案,并提供了示例代码,帮助企业高效、安全地实现大模型的内部部署。
9 1

热门文章

最新文章