opencv实战项目 手势识别-实现尺寸缩放效果

 手势识别系列文章目录

手势识别是一种人机交互技术,通过识别人的手势动作,从而实现对计算机、智能手机、智能电视等设备的操作和控制。

1.  opencv实现手部追踪(定位手部关键点)

2.opencv实战项目 实现手势跟踪并返回位置信息(封装调用)

3.手势识别-手势音量控制(opencv)

4.opencv实战项目 手势识别-手势控制鼠标

5.opencv实战项目 手势识别-手部距离测量

6.opencv实战项目 手势识别-实现尺寸缩放效果

未完待续

目录

 手势识别系列文章目录

1.HandTraqckModule模块

2、主模块


 本项目是使用了谷歌开源的框架mediapipe,里面有非常多的模型提供给我们使用,例如面部检测,身体检测,手部检测等

在这里插入图片描述

代码需要用到opencv   HandTraqckModule模块   mediapipe模块

1.HandTraqckModule模块

如下:

定义 HandDetector 类,用于检测手势并提取相关信息:

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
        # 初始化 Mediapipe 模块和相关对象
        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 = []

findHands 函数:在图像中找到手部,并返回手部信息以及绘制的图像。

    def findHands(self, img, draw=True, flipType=True):
        # 找到手部,并绘制相关信息
        imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        self.results = self.hands.process(imgRGB)
        allHands = []

        # 处理每个检测到的手
        if self.results.multi_hand_landmarks:
            for handType, handLms in zip(self.results.multi_handedness, self.results.multi_hand_landmarks):
                # 提取手部关键点和边界框信息
                myHand = {}
                mylmList = []
                xList = []
                yList = []

                for id, lm in enumerate(handLms.landmark):
                    px, py = int(lm.x * w), int(lm.y * h)
                    mylmList.append([px, py])
                    xList.append(px)
                    yList.append(py)

                # 计算边界框信息
                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)

                # 绘制手部信息
                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

fingersUp 函数:检测手指的状态,返回一个列表表示手指是否抬起。

    def fingersUp(self, myHand):
        # 检测手指状态,返回列表表示手指是否抬起
        myHandType = myHand["type"]
        myLmList = myHand["lmList"]
        if self.results.multi_hand_landmarks:
            fingers = []

            # 大拇指
            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)

            # 其他四指
            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

findDistance 函数:计算两点间的距离,可选是否在图像上绘制。

    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

HandTraqckModule模块整体代码

"""
Hand Tracking Module
"""

import cv2
import mediapipe as mp
import math


class HandDetector:
    """
    Finds Hands using the mediapipe library. Exports the landmarks
    in pixel format. Adds extra functionalities like finding how
    many fingers are up or the distance between two fingers. Also
    provides bounding box info of the hand found.
    """

    def __init__(self, mode=False, maxHands=2, detectionCon=0.5, minTrackCon=0.5):
        """
        :param mode: In static mode, detection is done on each image: slower
        :param maxHands: Maximum number of hands to detect
        :param detectionCon: Minimum Detection Confidence Threshold
        :param minTrackCon: Minimum Tracking Confidence Threshold
        """
        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):
        """
        Finds hands in a BGR image.
        :param img: Image to find the hands in.
        :param draw: Flag to draw the output on the image.
        :return: Image with or without drawings
        """
        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 = int(lm.x * w), int(lm.y * h)
                    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 findPosition(self, img, handNo=0, draw=True):
        """
        Finds landmarks of a single hand and puts them in a list
        in pixel format. Also finds the bounding box around the hand.
        :param img: main image to find hand in
        :param handNo: hand id if more than one hand detected
        :param draw: Flag to draw the output on the image.
        :return: list of landmarks in pixel format; bounding box
        """

        xList = []
        yList = []
        bbox = []
        bboxInfo = []
        self.lmList = []
        if self.results.multi_hand_landmarks:
            myHand = self.results.multi_hand_landmarks[handNo]
            for id, lm in enumerate(myHand.landmark):
                h, w, c = img.shape
                px, py = int(lm.x * w), int(lm.y * h)
                xList.append(px)
                yList.append(py)
                self.lmList.append([px, py])
                if draw:
                    cv2.circle(img, (px, py), 5, (255, 0, 255), cv2.FILLED)
            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)
            bboxInfo = {"id": id, "bbox": bbox, "center": (cx, cy)}

            if draw:
                cv2.rectangle(img, (bbox[0] - 20, bbox[1] - 20),
                              (bbox[0] + bbox[2] + 20, bbox[1] + bbox[3] + 20),
                              (0, 255, 0), 2)

        return self.lmList, bboxInfo

    def fingersUp(self,myHand):
        """
        Finds how many fingers are open and returns in a list.
        Considers left and right hands separately
        :return: List of which fingers are up
        """
        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):
        """
        Find the distance between two landmarks based on their
        index numbers.
        :param p1: Point1
        :param p2: Point2
        :param img: Image to draw on.
        :param draw: Flag to draw the output on the image.
        :return: Distance between the points
                 Image with output drawn
                 Line information
        """

        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], lmList2[8], 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()

2、主模块

原理:

  1. 当检测到两只手时,并且两只手的拇指和食指都抬起时,通过计算拇指指尖之间的距离来获取初始距离 startDist

  2. 当两只手的拇指和食指都抬起时,计算当前拇指指尖之间的距离,并根据距离变化来调整缩放因子 scale。这个变化可以通过当前距离减去初始距离得到。

  3. 根据计算得到的 scale 值,调整图像的尺寸,将另一张图像按照 scale 进行缩放。

这样,当你用两只手的拇指和食指模拟捏取的动作时,可以实现图像的放大和缩小效果。两只手之间的距离越大,图像缩小得越多;两只手之间的距离越小,图像放大得越多。

这个应用可以在许多场景中使用,比如在展示图像、视频播放或地图应用中,通过手势来实现图像的交互式缩放效果。这个示例,展示了手势识别在图像处理和交互中的潜在应用。

导入所需的库:

import cv2
from HandTrackingModule import *

配置摄像头,创建手势检测器对象:

cap = cv2.VideoCapture(0)
cap.set(3, 1280)  # 设置摄像头的宽度
cap.set(4, 720)   # 设置摄像头的高度

detector = HandDetector(detectionCon=0.8)  # 创建手势检测器对象,设置检测置信度阈值

定义变量用于手势缩放操作:

startDist = None  # 用于存储初始距离
scale = 0  # 缩放值
cx, cy = 500, 500  # 缩放中心的坐标

进入主循环,读取视频帧并执行手势识别和图像操作:

while True:
    success, img = cap.read()  # 读取视频帧
    hands, img = detector.findHands(img)  # 手势检测

    # 读取一张图像用于操作
    img1 = cv2.imread("cvarduino.jpg")

    if len(hands) == 2:
        # 如果检测到两只手
        if detector.fingersUp(hands[0]) == [1, 1, 0, 0, 0] and \
                detector.fingersUp(hands[1]) == [1, 1, 0, 0, 0]:

            lmList1 = hands[0]["lmList"]  # 第一只手的关键点列表
            lmList2 = hands[1]["lmList"]  # 第二只手的关键点列表
            
            # 计算两个手指尖之间的距离作为缩放参考
            if startDist is None:
                length, info, img = detector.findDistance(lmList1[8], lmList2[8], img)
                startDist = length

            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

    cv2.imshow("Image", img)  # 显示处理后的图像
    cv2.waitKey(1)  # 等待按键

主模块

全部代码:

import cv2
# from cvzone.HandTrackingModule import HandDetector
from HandTrackingModule import *
cap = cv2.VideoCapture(0)
cap.set(3, 1280)
cap.set(4, 720)

detector = HandDetector(detectionCon=0.8)
startDist = None
scale = 0
cx, cy = 500,500
while True:
    success, img = cap.read()
    hands, img = detector.findHands(img)
    img1 = cv2.imread("cvarduino.jpg")

    if len(hands) == 2:
        # print('Zoom Gesture')
        # print(detector.fingersUp(hands[0]),detector.fingersUp(hands[1]))
        if detector.fingersUp(hands[0]) == [1, 1, 0, 0, 0] and \
                detector.fingersUp(hands[1]) == [1, 1, 0, 0, 0]:

            # print('zhenque ')
            lmList1 = hands[0]["lmList"]
            lmList2 = hands[1]["lmList"]
            # point 8 is the tip of the index finger
            if startDist is None:
                length, info, img = detector.findDistance(lmList1[8], lmList2[8], img)
                # print(length)
                startDist = length

            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

    cv2.imshow("Image", img)
    cv2.waitKey(1)

 

有遇到的问题欢迎评论区留言!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/73879.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算法与数据结构(二十四)最优子结构原理和 dp 数组遍历方向

注&#xff1a;此文只在个人总结 labuladong 动态规划框架&#xff0c;仅限于学习交流&#xff0c;版权归原作者所有&#xff1b; 本文是两年前发的 动态规划答疑篇open in new window 的修订版&#xff0c;根据我的不断学习总结以及读者的评论反馈&#xff0c;我给扩展了更多…

结构体的定义与赋值

1、结构体定义 首先定义一个学生结构体&#xff0c;如下所示&#xff1a; struct Student {int num;char name[32];char sex;int age; }; 接着在主函数中对学生进行声明&#xff0c;如下所示&#xff1a; #include<iostream> using namespace std;struct Student {in…

《零基础实践深度学习》(第2版)学习笔记,(五)深度学习与计算机视觉

文章目录 1. 计算机视觉概述2. 图像分类3. 目标检测 1. 计算机视觉概述 图像分类 目标检测 2. 图像分类 3. 目标检测

Java课题笔记~ EL

1.EL (1).JSP脚本的缺点 使用JSP脚本可以实现页面输出显示&#xff0c;那为什么还需要使用EL简化输出呢&#xff1f; 这是因为单纯使用JSP脚本与HTML标签混合&#xff0c;实现输出显示的方式存在一些弊端&#xff0c;归纳如下&#xff1a; 代码结构混乱&#xff0c;可读性差…

Scala(第六章 面向对象)

文章目录 6.1 Scala包 6.1.1 包的命名6.1.2 包说明&#xff08;包语句&#xff09;6.1.3 包对象6.1.4 导包说明 6.2 类和对象 6.2.1 定义类6.2.2 属性 6.3 封装 6.3.1 访问权限6.3.2 方法6.3.3 创建对象6.3.4 构造器6.3.5 构造器参数 6.4 继承与多态6.5 抽象类 6.5.1 抽象属性和…

Datawhale Django入门组队学习Task01

Task01 一.创建虚拟环境 python -m venv django_learn &#xff08;django_learn那里是自己定的环境名字&#xff09; 之前一直用conda管理虚拟环境&#xff0c;没咋用过virtualenv&#xff0c;然后我的powershell之前也设置了默认启动了base环境&#xff0c;然后输入activat…

鸿蒙剥离 AOSP 不兼容 Android 热门问题汇总,不吹不黑不吵

上周发了一篇 《鸿蒙终于不套壳了&#xff1f;纯血 HarmonyOS NEXT 即将到来》的相关资讯&#xff0c;没想到大家「讨&#xff08;fa&#xff09;论&#xff08;xie&#xff09;」的热情很高&#xff0c;莫名蹭了一波流量&#xff0c;虽然流量对我来说也没什么用&#xff0c;但…

WebRTC音视频通话-新增或修改SDP中的码率Bitrate限制

WebRTC音视频通话-新增或修改SDP中的码率Bitrate限制参数 之前搭建ossrs服务&#xff0c;可以查看&#xff1a;https://blog.csdn.net/gloryFlow/article/details/132257196 之前实现iOS端调用ossrs音视频通话&#xff0c;可以查看&#xff1a;https://blog.csdn.net/gloryFlo…

6.2 口令破解攻击

数据参考&#xff1a;CISP官方 目录 口令安全问题口令破解攻击口令破解安全防护口令使用安全管理 一、口令安全问题 什么是口令 身份验证的机制&#xff0c;俗称 “密码"&#xff0c;对应英文单词为 password成本较低&#xff0c;得到广泛应用信息安全中的 “密码”…

重置mariadb数据库密码

使用场景重置步骤 重置数据库root用户密码为空重置数据库密码 文档暂时只支持未开启ha时manager使用的mariadb&#xff0c;开启ha的txsql和kundb类似&#xff0c;my.cnf文件地址和登录数据库命令不同 使用场景 manager数据库密码是通过调用接口并根据db.properties文件获取的…

24届近5年南京大学自动化考研院校分析

今天给大家带来的是南京大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 一、南京大学 学校简介 南京大学是一所历史悠久、声誉卓著的高等学府。其前身是创建于1902年的三江师范学堂&#xff0c;此后历经两江师范学堂、南京高等师范学校、国立东南大学、国立第四中…

Linux网络基础(中)

目录&#xff1a; 再谈“协议” HTTP协议 认识URL&#xff1a; urlnecode和urldecode HTTP协议格式&#xff1a; HTTP的方法&#xff1a; 简易HTTP服务器&#xff1a; 传输层 再谈端口号&#xff1a; 端口号范围划分&#xff1a; netstat&#xff1a; pidof&…

Flutter实现倒计时功能,秒数转时分秒,然后倒计时

Flutter实现倒计时功能 发布时间&#xff1a;2023/05/12 本文实例为大家分享了Flutter实现倒计时功能的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下 有一个需求&#xff0c;需要在页面进行显示倒计时&#xff0c;倒计时结束后&#xff0c;做相应的逻辑处理。 实…

【设计模式】原型模式

原型模式&#xff08;Prototype Pattern&#xff09;是用于创建重复的对象&#xff0c;同时又能保证性能。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式之一。 这种模式是实现了一个原型接口&#xff0c;该接口用于创建当前对象的克隆。当直接…

OSI参考模型及TCP/IP协议栈

一、网络概述 1.1、什么是网络&#xff1f; 1、网络的本质就是实现资源共享 2、将各个系统联系到一起&#xff0c;形成信息传递、接收、共享的信息交互平台 1.2、典型的园区网拓扑 1.3、网络历史发展&#xff0c;ARPA和ARPANET 1、1969年&#xff0c;美国国防部高级研究计…

【Git】大大大问题之syntax error near unexpected token `(‘ 的错误解决办法

话不多说&#xff0c;先上图&#xff1a; 如图&#xff0c;因为在linux环境里&#xff0c;文件路径中含有括号&#xff08;&#xff09;&#xff0c;因此报错&#xff01; 解决办法 等同于 &#xff1a;linux下解决bash: syntax error near unexpected token (’ 的错误&am…

【数据结构•堆】轮廓线

题目描述 轮廓线   • 每一个建筑物用一个三元组表示(L, H, R), 表示左边界, 高度和右边界。   • 轮廓线用X, Y, X, Y…这样的交替式表示。   • 右图的轮廓线为: (1, 11, 3, 13, 9, 0, 12, 7, 16,3, 19, 18, 22, 3, 23, 13, 29, 0) 。   • 给N个建筑&#xff0c;求…

备战秋招012(20230808)

文章目录 前言一、今天学习了什么&#xff1f;二、动态规划1.概念2.题目 总结 前言 提示&#xff1a;这里为每天自己的学习内容心情总结&#xff1b; Learn By Doing&#xff0c;Now or Never&#xff0c;Writing is organized thinking. 提示&#xff1a;以下是本篇文章正文…

最新版彩虹知识付费商城源码 V3.4

介绍 最新彩虹知识付费商城初创体验版&#xff0c;支持二级分类&#xff0c;多级分销&#xff0c;秒杀&#xff0c;砍价&#xff0c;团购&#xff0c;首页继续浏览&#xff0c;分站个人虚拟余额自定义&#xff0c;最新批量对接&#xff0c;批量下载图片&#xff0c;批量替换标…

安装Tomac服务器——安装步骤以及易出现问题的解决方法

文章目录 前言 一、下载Tomcat及解压 1、选择下载版本&#xff08;本文选择tomcat 8版本为例&#xff09; 2、解压安装包 二、配置环境 1、在电脑搜索栏里面搜索环境变量即可 2、点击高级系统设置->环境变量->新建系统变量 1) 新建系统变量&#xff0c;变量名为…