返回顶部
首页 > 资讯 > 后端开发 > Python >OpenCV实战之实现手势虚拟缩放效果
  • 518
分享到

OpenCV实战之实现手势虚拟缩放效果

OpenCV手势虚拟缩放OpenCV虚拟缩放OpenCV手势 2022-11-13 19:11:00 518人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录0、项目介绍1、项目展示2、项目搭建3、项目的代码与讲解0、项目介绍 本篇将会以HandTrackingModule为模块,这里的模块与之前的有所不同,请按照本篇为准,前面的Ha

0、项目介绍

本篇将会以HandTrackingModule为模块,这里的模块与之前的有所不同,请按照本篇为准,前面的HandTrackingModule不足以完成本项目,本篇将会通过手势对本人的博客海报进行缩放,具体效果可以看下面的效果展示。

1、项目展示

2、项目搭建

首先在一个文件夹下建立HandTrackingModule.py文件以及gesture_zoom.py,以及一张图片,你可以按照你的喜好选择,建议尺寸不要过大。

在这里用到了食指的索引8,可以完成左右手食指的手势进行缩放。

3、项目的代码与讲解

HandTrackingModule.py:

import cv2
import mediapipe as mp
import math
 
 
class handDetector:
 
    def __init__(self, mode=False, maxHands=2, detectionCon=0.5, minTrackCon=0.5):
        self.mode = mode
        self.maxHands = maxHands
        self.detectionCon = detectionCon
        self.minTrackCon = minTrackCon
 
        self.mpHands = mp.solutions.hands
        self.hands = self.mpHands.Hands(static_image_mode=self.mode, max_num_hands=self.maxHands,
                                        min_detection_confidence=self.detectionCon,
                                        min_tracking_confidence=self.minTrackCon)
        self.mpDraw = mp.solutions.drawing_utils
        self.tipIds = [4, 8, 12, 16, 20]
        self.fingers = []
        self.lmList = []
 
    def findHands(self, img, draw=True, flipType=True):
        imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        self.results = self.hands.process(imgRGB)
        allHands = []
        h, w, c = img.shape
        if self.results.multi_hand_landmarks:
            for handType, handLms in zip(self.results.multi_handedness, self.results.multi_hand_landmarks):
                myHand = {}
                ## lmList
                mylmList = []
                xList = []
                yList = []
                for id, lm in enumerate(handLms.landmark):
                    px, py, pz = int(lm.x * w), int(lm.y * h), int(lm.z * w)
                    mylmList.append([px, py])
                    xList.append(px)
                    yList.append(py)
 
                ## bbox
                xmin, xmax = min(xList), max(xList)
                ymin, ymax = min(yList), max(yList)
                boxW, boxH = xmax - xmin, ymax - ymin
                bbox = xmin, ymin, boxW, boxH
                cx, cy = bbox[0] + (bbox[2] // 2), \
                         bbox[1] + (bbox[3] // 2)
 
                myHand["lmList"] = mylmList
                myHand["bbox"] = bbox
                myHand["center"] = (cx, cy)
 
                if flipType:
                    if handType.classification[0].label == "Right":
                        myHand["type"] = "Left"
                    else:
                        myHand["type"] = "Right"
                else:
                    myHand["type"] = handType.classification[0].label
                allHands.append(myHand)
 
                ## draw
                if draw:
                    self.mpDraw.draw_landmarks(img, handLms,
                                               self.mpHands.HAND_CONNECTIONS)
                    cv2.rectangle(img, (bbox[0] - 20, bbox[1] - 20),
                                  (bbox[0] + bbox[2] + 20, bbox[1] + bbox[3] + 20),
                                  (255, 0, 255), 2)
                    cv2.putText(img, myHand["type"], (bbox[0] - 30, bbox[1] - 30), cv2.FONT_HERSHEY_PLaiN,
                                2, (255, 0, 255), 2)
        if draw:
            return allHands, img
        else:
            return allHands
 
    def fingersUp(self, myHand):
        myHandType = myHand["type"]
        myLmList = myHand["lmList"]
        if self.results.multi_hand_landmarks:
            fingers = []
            # Thumb
            if myHandType == "Right":
                if myLmList[self.tipIds[0]][0] > myLmList[self.tipIds[0] - 1][0]:
                    fingers.append(1)
                else:
                    fingers.append(0)
            else:
                if myLmList[self.tipIds[0]][0] < myLmList[self.tipIds[0] - 1][0]:
                    fingers.append(1)
                else:
                    fingers.append(0)
 
            # 4 Fingers
            for id in range(1, 5):
                if myLmList[self.tipIds[id]][1] < myLmList[self.tipIds[id] - 2][1]:
                    fingers.append(1)
                else:
                    fingers.append(0)
        return fingers
 
    def findDistance(self, p1, p2, img=None):
        x1, y1 = p1
        x2, y2 = p2
        cx, cy = (x1 + x2) // 2, (y1 + y2) // 2
        length = math.hypot(x2 - x1, y2 - y1)
        info = (x1, y1, x2, y2, cx, cy)
        if img is not None:
            cv2.circle(img, (x1, y1), 15, (255, 0, 255), cv2.FILLED)
            cv2.circle(img, (x2, y2), 15, (255, 0, 255), cv2.FILLED)
            cv2.line(img, (x1, y1), (x2, y2), (255, 0, 255), 3)
            cv2.circle(img, (cx, cy), 15, (255, 0, 255), cv2.FILLED)
            return length, info, img
        else:
            return length, info
 
 
def main():
    cap = cv2.VideoCapture(0)
    detector = handDetector(detectionCon=0.8, maxHands=2)
    while True:
        # Get image frame
        success, img = cap.read()
        # Find the hand and its landmarks
        hands, img = detector.findHands(img)  # with draw
        # hands = detector.findHands(img, draw=False)  # without draw
 
        if hands:
            # Hand 1
            hand1 = hands[0]
            lmList1 = hand1["lmList"]  # List of 21 Landmark points
            bbox1 = hand1["bbox"]  # Bounding box info x,y,w,h
            centerPoint1 = hand1['center']  # center of the hand cx,cy
            handType1 = hand1["type"]  # Handtype Left or Right
 
            fingers1 = detector.fingersUp(hand1)
 
            if len(hands) == 2:
                # Hand 2
                hand2 = hands[1]
                lmList2 = hand2["lmList"]  # List of 21 Landmark points
                bbox2 = hand2["bbox"]  # Bounding box info x,y,w,h
                centerPoint2 = hand2['center']  # center of the hand cx,cy
                handType2 = hand2["type"]  # Hand Type "Left" or "Right"
 
                fingers2 = detector.fingersUp(hand2)
 
                # Find Distance between two Landmarks. Could be same hand or different hands
                length, info, img = detector.findDistance(lmList1[8][0:2], lmList2[8][0:2], img)  # with draw
                # length, info = detector.findDistance(lmList1[8], lmList2[8])  # with draw
        # Display
        cv2.imshow("Image", img)
        cv2.waiTKEy(1)
 
 
if __name__ == "__main__":
    main()

gesture_zoom.py :

import cv2
import mediapipe as mp
import time
import HandTrackingModule as htm
 
startDist = None
scale = 0
cx, cy = 500,200
wCam, hCam = 1280,720
pTime = 0
 
cap = cv2.VideoCapture(0)
cap.set(3, wCam)
cap.set(4, hCam)
cap.set(10,150)
 
detector = htm.handDetector(detectionCon=0.75)
 
while 1:
    success, img = cap.read()
    handsimfORMation,img=detector.findHands(img)
 
    img1 = cv2.imread("1.png")
    # img[0:360, 0:260] = img1
    if len(handsimformation)==2:
 
        # print(detector.fingersUp(handsimformation[0]),detector.fingersUp(handsimformation[1]))
        #detector.fingersUp(handimformation[0]右手
        if detector.fingersUp(handsimformation[0]) == [1, 1, 1, 0, 0] and \
                detector.fingersUp(handsimformation[1]) == [1, 1, 1 ,0, 0]:
            lmList1 = handsimformation[0]['lmList']
            lmList2 = handsimformation[1]['lmList']
            if startDist is None:
                #lmList1[8],lmList2[8]右、左手指尖
 
                # length,info,img=detector.findDistance(lmList1[8],lmList2[8], img)
                length, info, img = detector.findDistance(handsimformation[0]["center"], handsimformation[1]["center"], img)
                startDist=length
            length, info, img = detector.findDistance(handsimformation[0]["center"], handsimformation[1]["center"], img)
            # length, info, img = detector.findDistance(lmList1[8], lmList2[8], img)
            scale=int((length-startDist)//2)
            cx, cy=info[4:]
            print(scale)
    else:
        startDist=None
    try:
        h1, w1, _ = img1.shape
        newH, newW = ((h1 + scale) // 2) * 2, ((w1 + scale) // 2) * 2
        img1 = cv2.resize(img1, (newW, newH))
 
        img[cy-newH//2:cy+ newH//2, cx-newW//2:cx+newW//2] = img1
    except:
        pass
    #################打印帧率#####################
    cTime = time.time()
    fps = 1 / (cTime - pTime)
    pTime = cTime
    cv2.putText(img, f'FPS: {int(fps)}', (40, 50), cv2.FONT_HERSHEY_COMPLEX,
                1, (100, 0, 255), 3)
 
    cv2.imshow("image",img)
    k=cv2.waitKey(1)
    if k==27:
        break
 

前面的类模块,我不做过多的讲解,它的新添加功能,我会在讲解主文件的时候提到。

1.首先,导入我们需要的模块,第一步先编写打开摄像头的代码,确保摄像头的正常,并调节好窗口的设置——长、宽、亮度,并且用htm(HandTrackingModule的缩写,后面都是此意)handDetector调整置信度,让我们检测到手更准确。

2.其次,用findHands的得到手的landmark,我所设定的手势是左右手的大拇指、食指、中指高于其他四指,也就是这六根手指竖起,我们按照[1, 1, 1, 0, 0],[1, 1, 1, 0, 0]来设定,如果你不能确定,请解除这里的代码;

#print(detector.fingersUp(handsimformation[0]),detector.fingersUp(handsimformation[1]))

3.然后,在这里有两个handsimformation[0]['lmList'],handsimformation[0]["center"],分别代表我要取食指,和手掌中心点,那么展示的时候是用的中心点,可以按照个人的喜好去选择手掌的索引,startDist=None表示为没有检测到的手时的起始长度,而经过每次迭代后,获得的距离length-起始长度,如果我增大手的距离,我就能得到一个较大的scale,由于打印的scale太大,我不希望它变化太快,所以做了二分后取整,如果得到的是一个负值,那么就缩小图片,那么我们没有检测到手时,就要令startDist=None。

4.之后来看,info = (x1, y1, x2, y2, cx, cy),根据索引得到中心值,然后,我们来获取现在海报的大小,然后加上我们scale,实现动态的缩放,但在这里要注意,这里进行了整出2,在乘以2的操作,如果是参数是偶数,我们无需理会,但如果遇到了奇数就会出现少一个像素点的问题,比如,值为9,整除2后得到的为4,4+4=8<9,所以为了确保正确,加了这一步。加入try...except语句是因为图像超出窗口时发出会发出警告,起到超出时此代码将不起作用,回到窗口时,可以继续操作。

5.最后,打印出我们的帧率

到此这篇关于OpenCV实战之实现手势虚拟缩放效果的文章就介绍到这了,更多相关OpenCV手势虚拟缩放内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: OpenCV实战之实现手势虚拟缩放效果

本文链接: https://lsjlt.com/news/170860.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • OpenCV实战之实现手势虚拟缩放效果
    目录0、项目介绍1、项目展示2、项目搭建3、项目的代码与讲解0、项目介绍 本篇将会以HandTrackingModule为模块,这里的模块与之前的有所不同,请按照本篇为准,前面的Ha...
    99+
    2022-11-13
    OpenCV手势虚拟缩放 OpenCV 虚拟缩放 OpenCV 手势
  • Python使用OpenCV实现虚拟缩放效果
    目录介绍要求目标构建结论介绍 OpenCV 彻底改变了整个图像处理领域。从图像分类到对象检测,我们不仅可以使用 OpenCV 库做一些很酷的事情,而且还可以构建一流的应用程序。 今天...
    99+
    2024-04-02
  • OpenCV利用手势识别实现虚拟拖放效果
    目录第一步第二步第三步完整代码本文将实现一些通过手拖放一些框,我们可以使用这个技术实现一些游戏,控制机械臂等很多有趣的事情。 第一步 通过opencv设置显示框和调用摄像头显示当前画...
    99+
    2024-04-02
  • OpenCV如何利用手势识别实现虚拟拖放效果
    这篇文章主要介绍OpenCV如何利用手势识别实现虚拟拖放效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!第一步通过opencv设置显示框和调用摄像头显示当前画面import cv2cap =&n...
    99+
    2023-06-26
  • opencv实现图像缩放效果
    本文实例为大家分享了opencv实现图像缩放效果的具体代码,供大家参考,具体内容如下 图像缩放: 图像缩放即对图像的大小进行调整,即放大或者缩小 cv2.resize(src,d...
    99+
    2024-04-02
  • opencv如何实现图像缩放效果
    这篇文章主要介绍了opencv如何实现图像缩放效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。图像缩放:图像缩放即对图像的大小进行调整,即放大或者缩小cv2.resize(...
    99+
    2023-06-14
  • Android使用ImageView实现支持手势缩放效果
    TouchImageView继承自ImageView具有ImageView的所有功能;除此之外,还有缩放、拖拽、双击放大等功能,支持viewpager和scaletype,并伴...
    99+
    2022-06-06
    手势 Android
  • C++OpenCV实战之手势识别
    目录前言一、手部关键点检测1.1 功能源码1.2 功能效果二、手势识别2.1算法原理2.2功能源码三、结果显示3.1功能源码3.2效果显示四、源码总结前言 本文将使用OpenCV C...
    99+
    2024-04-02
  • Python+OpenCV实战之拖拽虚拟方块的实现
    目录一、项目效果二、核心流程三、代码流程1. 读取摄像头视频,画矩形2. 导入mediapipe处理手指坐标3. 位置计算完整代码一、项目效果 学校宿舍今天搬家,累麻了,突然发现展...
    99+
    2024-04-02
  • Android实现手势滑动多点触摸放大缩小图片效果
    网上文章虽多,但是这种效果少之又少,我真诚的献上以供大家参考 实现原理:自定义ImageView对此控件进行相应的layout(动态布局). 这里你要明白几个方法执行的流程: ...
    99+
    2022-06-06
    小图 图片 手势 Android
  • Android实现手势滑动多点触摸缩放平移图片效果
    现在app中,图片预览功能肯定是少不了的,用户基本已经形成条件反射,看到小图,点击看大图,看到大图两个手指开始进行放大,放大后,开始移动到指定部位。 一、概述 想要做到图片支持...
    99+
    2022-06-06
    图片 手势 Android
  • Python+OpenCV怎么实现拖拽虚拟方块效果
    一、项目效果二、核心流程1、openCV读取视频流、在每一帧图片上画一个矩形。2、使用mediapipe获取手指关键点坐标。3、根据手指坐标位置和矩形的坐标位置,判断手指点是否在矩形上,如果在则矩形跟随手指移动。三、代码流程环境准备:pyt...
    99+
    2023-05-15
    Python OpenCV
  • Android实现手势滑动多点触摸缩放平移图片效果(二)
    上一篇已经带大家实现了自由的放大缩小图片,简单介绍了下Matrix;具体请参考:Android实现手势滑动多点触摸缩放平移图片效果,本篇继续完善我们的ImageView。 首先...
    99+
    2022-06-06
    图片 手势 Android
  • 如何使用Python+OpenCV实现拖拽虚拟方块效果
    本篇内容主要讲解“如何使用Python+OpenCV实现拖拽虚拟方块效果”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何使用Python+OpenCV实现拖拽虚拟方块效果”吧!一、核心流程op...
    99+
    2023-07-06
  • css3怎么实现缩放动画效果
    这篇文章主要介绍css3怎么实现缩放动画效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! css中,可利用“@keyframes”规则、animatio...
    99+
    2024-04-02
  • Android手势控制实现缩放、移动图片
    本文实例为大家分享了Android手势控制实现缩放、移动图片的方法,供大家参考,具体内容如下 新建一个触摸监听器类 package com.liyong.btprinter;...
    99+
    2022-06-06
    图片 Android
  • Android实现点击缩略图放大效果
    本文实例为大家分享了Android点击缩略图放大效果的具体代码,供大家参考,具体内容如下import android.animation.Animator;import android.animation.AnimatorListenerA...
    99+
    2023-05-30
    android 缩略图 放大
  • Android通过手势实现的缩放处理实例代码
    网络上传言HTC的HERO-ROM支持多点触摸的论证大多源于浏览网页和图片时,能像IPhone一样通过手势来控制页面的大小。下面的例子是利用现有的API实现HERO浏览图片和网...
    99+
    2022-06-06
    手势 Android
  • Android手势滑动实现ImageView缩放图片大小
    本文推出了两种Android手势实现ImageView缩放图片大小的方法,分享给大家供大家参考,具体内容如下 方法一: 将以下代码写到MulitPointTouchListen...
    99+
    2022-06-06
    图片 Android
  • Flutter Animation实现缩放和滑动动画效果
    本文实例为大家分享了Flutter Animation实现缩放和滑动动画的具体代码,供大家参考,具体内容如下 Animation对象是Flutter动画库中的一个核心类,它生成指导动...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作