yahboom
HomeLearn
Solution
Blog
Online Store
About Us
EN/中文
DOFBOT SE📖
1.First Trial
  • 1.First Trial
  • 2.Analysis of common problems
  • 3.Calibration offset
  • 4.Precautions for DIY Robotic Arm
  • 5.Robotic arm gripping anomaly solutions
2.Assembly Course
  • 1.Installation video
  • 2.Calibrate the Robotic Arm
  • 3.Install the map
3.Remote Control Course
  • 1.Mobile APP control
  • 2.USB handle control
  • 3.PC software control
4.Preparation
  • 1.Manage APP control service
  • 2.Manage JupyterLab service
  • 3.Write STM32 firmware
  • 4.Introduction to expansion board
5.Basic Control Course
  • 1.Control RGB light
  • 2.Control buzzer
  • 3.Control single servo
  • 4.Read servo angle
  • 5.Control all servo
  • 6.DOFBOT up down left right
  • 7.DOFBOT dancing
  • 8.DOFBOT memory action
  • 9.DOFBOT grab block
  • 10.Porter
  • 11.Stack block
  • 12.USB camera display
  • 13.Synchronous action
6.AI Vision Basic Course
  • 1.Gesture Recognition
  • 2.Color threshold adjustment Color calibration
  • 3.Color recognition
  • 4.Face recognition
  • 5.Garbage recognition
  • 6.Yolo object recognition
  • 7.Real-time web view
7.2D Visual Tracking Course
  • 1.PID algorithm basics
  • 2.Color block positioning
  • 3.Color block tracking
  • 4.Face positioning
  • 5.Face tracking
  • 6.Gesture recognition fixed action
8.2D Visual Grasping Course
  • 0.Visual positioning
  • 1.Gesture recognition stack blocks
  • 2.Color recognition grab blocks
  • 3.Catch game
  • 4.Color sorting and stacking
  • 5.Garbage sorting
  • 6.Color interaction
9.2D Mediapipe Course
  • 1.Hand detection
  • 2.Posture detection
  • 3.Overall inspection
  • 4.Face detection
  • 5.Face recognition
  • 6.Face effects
  • 7.3D object recognition
  • 8.Paintbrush
  • 9.Finger control
  • 10.Gesture recognition
  • 11.Gesture control robotic arm action group
  • 12.Arm posture control robotic arm
  • 13.Palm Targeting
  • 14.Robotic arm tracks the palm
  • 15.Fingertip trajectory recognition
  • 16.Fingertip trajectory control robotic arm
  • 17.Gesture Grasp and Release Objects
  • 18.Finger Control Robot Arm
10.AI Large Model Voice Module (Must Read)
  • 1. Introduction to AI Large Model Voice Module
  • 2. Flash the firmware (Must read)
  • 3. Modify the wake-up word and command word
11.2D Voice Control Course
  • 1.Simple Voice Control
  • 2.Smart Voice Control
  • 3.Voice Action Control
  • 4.Memory Learning Mode
  • 5.Color Recognition with Voice Broadcast
  • 6.Color Recognition and Grasping with Voice Broadcast
  • 7.Color Recognition and Sorting with Voice Broadcast
  • 8.Voice Recognition Target Tracking
  • 9.Voice Control Stacking
  • 10.Voice Control Color Sorting
  • 11.Garbage Recognition with Voice Broadcast
  • 12.Garbage Sorting with Voice Broadcast
12.Robotic Arm Control and Inverse Kinematics
  • 1. Robotic arm ROS control
  • 2. Inverse solution
13.3D Sorting and Grasping Course
  • 1.AprilTag ID sorting
  • 2.MediaPipe Gesture-AprilTag ID sorting
  • 3.MediaPipe Gesture-AprilTag distance sorting
  • 4.Block color sorting
  • 5.Block different shape sorting
  • 6.Yolov11 garbage sorting
14.3D Tracking Course
  • 1.AprilTag Tracking
  • 2.Color Block Tracking
  • 3.KCF Object Tracking
15.3D Voice Control for Sorting & Tracking Course
  • 1.Voice Control AprilTag ID Sorting
  • 2.Voice Control Color Block Sorting
  • 3.Voice Control Yolov11 Garbage Recognition Sorting
  • 4.Voice Control AprilTag Tracking
  • 5.Voice Control Color Block Tracking
  • 6.Voice Control Object Tracking
16.AI Model Basics
  • 1.AI large model types and principles
  • 2.RAG retrieval enhancement and model training samples
  • 3.Embodied intelligent robot system architecture
  • 4.Embodied intelligent functions core source code
17.AI Model Development
  • 1. Register a model service provider account
  • 2. Configure API-KEY
  • 3. Introduction to Dify
  • 4. Basic Dify Features
  • 5. AI Large Model Development - chatbot
  • 6. Deploy the RAG knowledge base
  • 7. RAG knowledge base + chatbot
  • 8. AI agent workflow
18.AI Model – Text Version
  • 1.Semantic understand instruction following
  • 2.Multimodal visual understand
  • 3.Text Large Model + robotic arm control
  • 4.Multimodal Large Model+video understanding
  • 5.Multimodal Large Model+robotic arm gripping
  • 6.Multimodal Large Model+robotic arm tracking
  • 7.Multimodal Large Model+robotic arm sorting
  • 8.Multimodal Large Model+robotic arm handling
  • 9.Multimodal Large Model+Color Blocks Back In Place
  • 10.Multimodal Large Model + Intent Prediction + Robotic Arm Gripping
  • 11.Text Large Model + YOLOv11 + Intelligent Garbage Classification
19.AI Model – Voice Version
  • 1.Semantic understand instruction following
  • 2.Multimodal visual understand
  • 3.Text Large Model + robotic arm control
  • 4.Multimodal Large Model+video understanding
  • 5.Multimodal Large Model+robotic arm gripping
  • 6.Multimodal Large Model+robotic arm tracking
  • 7.Multimodal Large Model+robotic arm sorting
  • 8.Multimodal Large Model+robotic arm handling
  • 9.Multimodal Large Model+Color Blocks Back In Place
  • 10.Multimodal Large Model + Intent Prediction + Robotic Arm Gripping
  • 11.Text Large Model + YOLOv11 + Intelligent Garbage Classification
20.AI Model – Fun Applications
  • 1.AI Butler-Intent Inference
  • 2.AI Encyclopedia-Arithmetic Master
  • 3.AI Encyclopedia-You asked I Pointed
  • 4.AI Encyclopedia-Nutritional Analysis
  • 5.AI Encyclopedia-Problem Solving Expert
  • 6.AI Encyclopedia-English Spelling
  • 7.AI Butler-Garbage Sorting
  • 8.AI Top Chef
21.MoveIt2 Course
  • 1. MoveIt Configuration
  • 2. MoveIt Usage
  • 3. MoveIt Drive Real Robot
  • 4. MoveIt Random Movement
  • 5. MoveIt Forward Kinematics Design
  • 6. MoveIt Inverse Kinematics Design
  • 7. MoveIt Cartesian Path
  • 8. MoveIt Scene Design
  • 9. MoveIt Trajectory Planning
  • 10. MoveIt Collision Detection
22.YOLOv11 Development Course
  • 1. YOLO Environment Setup
  • 2. CLI Usage
  • 3. Object Detection
  • 4. Instance Segmentation
  • 5. Pose Estimation
  • 6. Image Classification
  • 7. Oriented Bounding Boxes Object Detection
  • 8. Model Conversion
  • 9. Model Prediction
23. Linux Operating System
  • 1.Introduction to Linux system
  • 2.Ubuntu file system
  • 3.Ubuntu common commands
  • 4.Ubuntu common editors
  • 5.Ubuntu software operation commands
  • 6.Virtual machine installation
  • 7.SSH remote control
  • 8.VNC remote control
  • 9.Transfer files remotely
  • 10.Driver library and communication
  • 11.Static IP and hotspot mode
  • 12.Bind device ID
  • 13.Capacity expansion and resource allocation
  • 14.Update system software sources
  • 15.Set root user password
  • 16.sudo free password
  • 17.Connect to WiFi network
  • 18.View system version
  • 19.Customized service management
  • 20.Back up system image
24.OpenCV Course
  • 1.Introduction to Open Source CV
  • 2.Image reading and display
  • 3.Picture writing
  • 4.Image Quality
  • 5.Pixel operations
  • 6.Image zoom
  • 7.Picture cut
  • 8.Picture pan
  • 9.Picture mirroring
  • 10.Affine transformation
  • 11.Picture rotation
  • 12.perspective transformation
  • 13.Grayscale processing
  • 14.Binary image
  • 15.Edge green detection
  • 16.Line segment drawing
  • 17.Rectangular circle drawing
  • 18.Text and picture drawing
25.Advanced Visuals Course
  • 1. QR Code
  • 2. Human Pose Estimation
  • 3. Object Detection
  • 4. AR Vision
  • 5. ROS + OpenCV Basics
26.ROS2 Basic Course
  • 1.Introduction to ROS2
  • 2.ROS2 install Humble
  • 3.ROS2 development environment
  • 4.ROS2 workspace
  • 5.ROS2 function package
  • 6.ROS2 node
  • 7.ROS2 topic communication
  • 8.ROS2 service communication
  • 9.ROS2 action communication
  • 10.ROS2 custom interface message
  • 11.ROS2 parameter service case
  • 12.ROS2 meta-function package
  • 13.ROS2 distributed communication
  • 14.ROS2 DDS
  • 15.ROS2 time related API
  • 16.ROS2 common command tools
  • 17.ROS2 rviz2 use
  • 18.ROS2 rqt toolbox
  • 19.ROS2 Launch startup file configuration
  • 20.ROS2 recording and playback tool
  • 21.ROS2 URDF model
  • 22.ROS2 Gazebo simulation platform
  • 23.ROS2 TF2 coordinate transformation
27.Jupyter Lab Usage Course
  • 0.Read the document before operation
  • 1.Jupyter Lab environment construction
  • 2.Basic use of Jupyter Widgets
  • 3.Launch JupyterLab
  • 4.How to Use JupyterLab
Download
  • APP(iOS/Android)
  • VM File
  • Instruction manual
  • Hardware_3DModelFile
  • PC_Software
  • Code
  • Communication Protocol-Python Library
  • Tools
Download ZIP

Welcome to DOFBOT SE repository

8.Paintbrush

Paintbrush

8.1、Introduction

MediaPipe is a data stream processing machine learning application development framework developed and open-sourced by Google. It is a graph-based data processing pipeline for building with various forms of data sources such as video, audio, sensor data, and any time series data. MediaPipe is cross-platform and can run on embedded platforms (Raspberry Pi, etc.), mobile devices (iOS and Android), workstations and servers, and supports mobile GPU acceleration. MediaPipe provides cross-platform, customizable ML solutions for real-time and streaming media.

MediaPipe's core framework is implemented in C++ and provides support for Java and Objective C. The main concepts of MediaPipe include Packet, Stream, Calculator, Graph, and Subgraph.

MediaPipe features:

  • End-to-end acceleration: Built-in fast ML inference and processing accelerates even on ordinary hardware.
  • Build once, deploy anywhere: Unified solutions work on Android, iOS, desktop/cloud, web, and IoT.
  • Ready-to-use solutions: Cutting-edge ML solutions that showcase all framework features.
  • Free and open source: Framework and solutions under Apache 2.0, fully extensible and customizable.

8.2、Paintbrush

When the right hand index finger and middle finger are together, it is the selection state, and a color selection box pops up at the same time. When the two fingertips move to the corresponding color position, that color is selected (black is the eraser); when the index finger and middle finger are separated, it is the drawing state, and you can draw freely on the canvas.

8.2.1、Startup

Enter in terminal,

xxxxxxxxxx
ros2 run dofbot_mediapipe 08_VirtualPaint

image-20231016112807709

8.2.2、Source Code

Source location: /home/yahboom/dofbot_ws/src/dofbot_mediapipe/dofbot_mediapipe/08_VirtualPaint.py

​x
#!/usr/bin/env python3
# encoding: utf-8
​
import math
import time
import cv2 as cv
import numpy as np
import mediapipe as mp
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
​
class HandDetector:
    def __init__(self, mode=False, maxHands=2, detectorCon=0.5, trackCon=0.5):
        self.tipIds = [4, 8, 12, 16, 20]
        self.mpHand = mp.solutions.hands
        self.mpDraw = mp.solutions.drawing_utils
        self.hands = self.mpHand.Hands(
            static_image_mode=mode,
            max_num_hands=maxHands,
            min_detection_confidence=detectorCon,
            min_tracking_confidence=trackCon )
        self.lmDrawSpec = mp.solutions.drawing_utils.DrawingSpec(color=(0, 0, 255), thickness=-1, circle_radius=15)
        self.drawSpec = mp.solutions.drawing_utils.DrawingSpec(color=(0, 255, 0), thickness=10, circle_radius=10)
​
    def findHands(self, frame, draw=True):
        self.lmList = []
        img_RGB = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
        self.results = self.hands.process(img_RGB)
        if self.results.multi_hand_landmarks:
            for handLms in self.results.multi_hand_landmarks:
                if draw: self.mpDraw.draw_landmarks(frame, handLms, self.mpHand.HAND_CONNECTIONS, self.lmDrawSpec, self.drawSpec)
                else: self.mpDraw.draw_landmarks(frame, handLms, self.mpHand.HAND_CONNECTIONS)
            for id, lm in enumerate(self.results.multi_hand_landmarks[0].landmark):
                h, w, c = frame.shape
                cx, cy = int(lm.x * w), int(lm.y * h)
                self.lmList.append([id, cx, cy])
        return frame, self.lmList
​
    def fingersUp(self):
        fingers=[]
        if (self.calc_angle(self.tipIds[0], self.tipIds[0] - 1, self.tipIds[0] - 2) > 150.0) and (
                self.calc_angle(self.tipIds[0] - 1, self.tipIds[0] - 2, self.tipIds[0] - 3) > 150.0): 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)
        return fingers
​
    def get_dist(self, point1, point2):
        x1, y1 = point1
        x2, y2 = point2
        return abs(math.sqrt(math.pow(abs(y1 - y2), 2) + math.pow(abs(x1 - x2), 2)))
​
    def calc_angle(self, pt1, pt2, pt3):
        point1 = self.lmList[pt1][1], self.lmList[pt1][2]
        point2 = self.lmList[pt2][1], self.lmList[pt2][2]
        point3 = self.lmList[pt3][1], self.lmList[pt3][2]
        a = self.get_dist(point1, point2)
        b = self.get_dist(point2, point3)
        c = self.get_dist(point1, point3)
        try:
            radian = math.acos((math.pow(a, 2) + math.pow(b, 2) - math.pow(c, 2)) / (2 * a * b))
            angle = radian / math.pi * 180
        except:
            angle = 0
        return abs(angle)
​
class HandPaintingNode(Node):
    def __init__(self):
        super().__init__('hand_painting_node')
        self.publisher_ = self.create_publisher(Image, 'hand_painting_image', 10)
        self.timer = self.create_timer(0.1, self.timer_callback)
        self.bridge = CvBridge()
        self.hand_detector = HandDetector(detectorCon=0.85)
        self.xp = self.yp = self.pTime = self.boxx = 0
        self.tipIds = [4, 8, 12, 16, 20]
        self.imgCanvas = np.zeros((480, 640, 3), np.uint8)
        self.brushThickness = 5
        self.eraserThickness = 100
        self.top_height = 50
        self.Color = "Red"
        self.ColorList = {
            'Red': (0, 0, 255),
            'Green': (0, 255, 0),
            'Blue': (255, 0, 0),
            'Yellow': (0, 255, 255),
            'Black': (0, 0, 0),
        }
        self.capture = cv.VideoCapture(0, cv.CAP_V4L2)
        self.capture.set(6, cv.VideoWriter.fourcc('M', 'J', 'P', 'G'))
        self.capture.set(cv.CAP_PROP_FRAME_WIDTH, 640)
        self.capture.set(cv.CAP_PROP_FRAME_HEIGHT, 480)
​
    def timer_callback(self):
        ret, frame = self.capture.read()
        if not ret:
            self.get_logger().error('Failed to capture frame')
            return
​
        h, w, c = frame.shape
        frame, lmList = self.hand_detector.findHands(frame, draw=False)
        if len(lmList) != 0:
            x1, y1 = lmList[8][1:]
            x2, y2 = lmList[12][1:]
            fingers = self.hand_detector.fingersUp()
            if fingers[1] and fingers[2]:
                if y1 < self.top_height:
                    if 0 < x1 < int(w / 5) - 1:
                        self.boxx = 0
                        self.Color = "Red"
                    if int(w / 5) < x1 < int(w * 2 / 5) - 1:
                        self.boxx = int(w / 5)
                        self.Color = "Green"
                    elif int(w * 2 / 5) < x1 < int(w * 3 / 5) - 1:
                        self.boxx = int(w * 2 / 5)
                        self.Color = "Blue"
                    elif int(w * 3 / 5) < x1 < int(w * 4 / 5) - 1:
                        self.boxx = int(w * 3 / 5)
                        self.Color = "Yellow"
                    elif int(w * 4 / 5) < x1 < w - 1:
                        self.boxx = int(w * 4 / 5)
                        self.Color = "Black"
                cv.rectangle(frame, (x1, y1 - 25), (x2, y2 + 25), self.ColorList[self.Color], cv.FILLED)
                cv.rectangle(frame, (self.boxx, 0), (self.boxx + int(w / 5), self.top_height), self.ColorList[self.Color], cv.FILLED)
                cv.rectangle(frame, (0, 0), (int(w / 5) - 1, self.top_height), self.ColorList['Red'], 3)
                cv.rectangle(frame, (int(w / 5) + 2, 0), (int(w * 2 / 5) - 1, self.top_height), self.ColorList['Green'], 3)
                cv.rectangle(frame, (int(w * 2 / 5) + 2, 0), (int(w * 3 / 5) - 1, self.top_height), self.ColorList['Blue'], 3)
                cv.rectangle(frame, (int(w * 3 / 5) + 2, 0), (int(w * 4 / 5) - 1, self.top_height), self.ColorList['Yellow'], 3)
                cv.rectangle(frame, (int(w * 4 / 5) + 2, 0), (w - 1, self.top_height), self.ColorList['Black'], 3)
            if fingers[1] and fingers[2] == False and math.hypot(x2 - x1, y2 - y1) > 50:
                if self.xp == self.yp == 0: self.xp, self.yp = x1, y1
                if self.Color == 'Black':
                    cv.line(frame, (self.xp, self.yp), (x1, y1), self.ColorList[self.Color], self.eraserThickness)
                    cv.line(self.imgCanvas, (self.xp, self.yp), (x1, y1), self.ColorList[self.Color], self.eraserThickness)
                else:
                    cv.line(frame, (self.xp, self.yp), (x1, y1), self.ColorList[self.Color], self.brushThickness)
                    cv.line(self.imgCanvas, (self.xp, self.yp), (x1, y1), self.ColorList[self.Color], self.brushThickness)
                cv.circle(frame, (x1, y1), 15, self.ColorList[self.Color], cv.FILLED)
                self.xp, self.yp = x1, y1
            else: self.xp = self.yp = 0
​
        imgGray = cv.cvtColor(self.imgCanvas, cv.COLOR_BGR2GRAY)
        _, imgInv = cv.threshold(imgGray, 50, 255, cv.THRESH_BINARY_INV)
        imgInv = cv.cvtColor(imgInv, cv.COLOR_GRAY2BGR)
        frame = cv.bitwise_and(frame, imgInv)
        frame = cv.bitwise_or(frame, self.imgCanvas)
​
        if cv.waitKey(1) & 0xFF == ord('q'):
            self.capture.release()
            cv.destroyAllWindows()
            rclpy.shutdown()
​
        cTime = time.time()
        fps = 1 / (cTime - self.pTime)
        self.pTime = cTime
        text = "FPS : " + str(int(fps))
        cv.rectangle(frame, (20, h - 100), (50, h - 70), self.ColorList[self.Color], cv.FILLED)
        cv.putText(frame, self.Color, (70, h - 75), cv.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 1)
        cv.putText(frame, text, (20, h-30), cv.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 1)
​
        msg = self.bridge.cv2_to_imgmsg(frame, "bgr8")
        self.publisher_.publish(msg)
​
        cv.imshow('frame', frame)
​
def main(args=None):
    rclpy.init(args=args)
    hand_painting_node = HandPaintingNode()
    rclpy.spin(hand_painting_node)
    hand_painting_node.destroy_node()
    rclpy.shutdown()
​
if __name__ == '__main__':
    main()
3D object recognition
Finger control

COMPANY

  • About us
  • Team Style
  • Blog

LEARNING & EXPLORATION

  • Tutorials
  • Edge AI hardware
  • Educational robots
  • Embedded intelligent hardware

WHERE TO BUY

  • Yahboom Online Store
  • Amazon
  • Alibaba
  • AliExpress
  • Mercado

TECHNOLOGY SUPPORT

  • Email: support@yahboom.com

BE A DISTRIBUTOR

  • Email: sales@yahboom.com
QR Code

Copyright © 2017-2026 Yahboom. All Rights Reserved.

EN/中文