RK3576 YOLO Pose นับ Pull-up แบบ Real-Time

YOLO Pose มองเห็นแขน ขา ข้อมือ และใบหน้าได้ แต่ยังไม่รู้ว่า “ดึงข้อครบ 1 ครั้ง” ต้องนับตรงไหน โปรเจกต์นี้เลยเอา YOLO11n Pose มารันบน RK3576 NPU แล้วเขียน State Machine อีกชั้น เพื่อเปลี่ยน Keypoint จาก AI ให้กลายเป็น Pull-up Counter แบบ Real-Time

ระบบตรวจจับคน, วาด Bounding Box, วาด Pose Skeleton 17 จุด, ประมาณตำแหน่งบาร์ และนับจำนวน Pull-up ทั้งหมดบน Edge Computer

Browser ไม่ได้เป็นคนรัน YOLO และวิดีโอต้นฉบับไม่ต้องถูกส่งขึ้น Cloud เพราะฝั่ง RK3576 ทำทั้ง Inference และ Counting ก่อนส่งเฉพาะภาพที่ Annotate แล้ว กับข้อมูล Status ไปยังหน้า Web

จุดน่าสนใจจึงไม่ใช่แค่ “ใช้ AI ดูคนออกกำลังกาย” แต่เป็นการเห็นชัด ๆ ว่า AI Model ให้ข้อมูลอะไร และเราต้องเขียน Logic ต่ออีกแค่ไหน ถึงจะกลายเป็น Application ที่ใช้งานได้จริง

ตัวอย่าง Real-Time Pull-Up Counter ที่ใช้ YOLO Pose ตรวจบุคคลและ Pose Keypoints ก่อนนับจำนวนครั้งด้วย Logic บน RK3576

Key Takeaways

  • Hardware หลักคือ Seeed Studio reComputer RK3576
  • ใช้โมเดล YOLO11n Pose แบบ Pretrained โดย Project ไม่ได้ Train โมเดลเพิ่ม
  • YOLO คืน Bounding Box และ COCO Pose Keypoints จำนวน 17 จุด
  • Pull-up ไม่ได้ถูกนับโดย YOLO โดยตรง แต่ถูกตัดสินด้วย Temporal State Machine
  • ใช้ตำแหน่งข้อมือซ้าย/ขวา ช่วยประมาณตำแหน่ง Pull-up Bar
  • ใช้ Exponential Moving Average ลดอาการ Keypoint สั่น
  • ระยะต่าง ๆ ถูก Normalize ด้วยความสูง Bounding Box ของคน
  • Nose เป็น Top-position Signal หลัก และใช้ Shoulders เป็น Fallback เมื่อใบหน้าถูก Bar บัง
  • ใช้ Hysteresis ด้วย Top / Bottom Threshold แยกกัน
  • ต้อง Stable หลาย Frame ก่อนเปลี่ยน State หรือนับ Rep
  • Input รองรับ Video File, USB Camera และ HTTP / RTSP Stream ที่ OpenCV รองรับ
  • RK3576 Deployment ใช้ YOLO11n Pose แบบ FP16 ขนาด Input 640×640
  • NPU Inference ที่รายงาน อยู่ราว 70–80 ms ต่อ Frame
  • Full Web Pipeline ทำงานประมาณ 7 FPS ใน Test Environment ของผู้สร้าง
  • Browser รับ Annotated MJPEG และ Status Data ไม่ได้รัน Model เอง

Source มีสองชุดที่ไม่ควรนำมาปนกัน: หน้า Hackster อธิบาย RK3576 Deployment Package ที่มี RKNN Model, Offline Wheels, install.sh, run_demo.sh และ run_web.sh แต่ Public GitHub Repository ที่เปิดอยู่ปัจจุบันมีโครงสร้างเล็กกว่า และ README อธิบาย Python / Ultralytics Version ที่รันด้วย pullup_counter.py ดังนั้น Command ในบทความนี้จะระบุให้ชัดว่า มาจาก Source ชุดใด

RK3576 Pull-Up Counter คืออะไร?

Project นี้เปลี่ยน RK3576 Edge Computer ให้กลายเป็นระบบนับ Pull-up แบบ Real-Time

Pipeline เริ่มจาก Video แล้วใช้ YOLO11n Pose ตรวจคนและ Pose Skeleton ก่อนส่งข้อมูล Keypoint ไปยัง Logic สำหรับนับ Rep

Video / USB Camera / RTSP

YOLO11n Pose

Person Box + 17 Pose Keypoints

Pull-Up State Machine

Rep Count + Current State

Annotated MJPEG + Browser Dashboard

ระบบเดียวกัน ถูกใช้ทั้งใน Offline Video Processor และ Web Application จึงไม่ต้องมี Counting Logic คนละชุดระหว่าง Demo กับ Live Camera

ทำไม Project นี้ถึงเป็น Edge AI จริง?

จุดสำคัญคือ Inference อยู่บน RK3576 ไม่ได้ส่ง Video ไปให้ Cloud ช่วยวิเคราะห์

Board ทำงานหลัก:

  • Decode Video
  • Preprocess Frame
  • Run YOLO Pose บน NPU
  • Post-process Keypoints
  • Update Pull-up State Machine
  • วาด Bounding Box และ Skeleton
  • Encode JPEG
  • ส่ง MJPEG ให้ Browser

Browser จึงเป็นหน้าจอแสดงผล มากกว่าจะเป็น AI Compute Client

ข้อดีใน Architecture ของ Project: แม้อินเทอร์เน็ตภายนอกจะหลุด การนับยังดำเนินต่อได้ เพราะ Model และ State Machine ทำงานอยู่บน Board

Hardware มีน้อย แต่ Input เลือกได้ 3 แบบ

Hardware หลักที่หน้า Project ระบุคือ:

Hardware หน้าที่
Seeed Studio reComputer RK3576 รัน Pose Model, Counting Logic และ Web Application

ตัว Application รองรับ Input 3 แบบ:

1

Prerecorded Video

เหมาะสำหรับเริ่ม Test เพราะใช้คลิปเดิมซ้ำได้ และเทียบผลการนับได้ง่าย

2

USB Camera

เลือกกล้องผ่าน Device Index เช่น Source 0

3

HTTP / RTSP Stream

ใช้ Network Camera Stream ที่ OpenCV รองรับ

ถ้าเพิ่งลอง Project: Source รองรับให้เริ่มจาก Video File ก่อนขยับไป USB Camera หรือ RTSP โดยไม่ต้องเปลี่ยน Counting Logic

YOLO11n Pose ทำอะไรให้เรา?

Project ใช้ YOLO11n Pose pretrained model แบบมาตรฐาน โดยไม่ได้ Train เพิ่มสำหรับ Pull-up

Model ทำหน้าที่:

  • Detect Person
  • คืน Bounding Box
  • คืน Detection Confidence
  • คืน 17 COCO Pose Keypoints

Keypoint ที่เกี่ยวกับ Counting Logic โดยตรง ได้แก่:

  • Nose
  • Left Shoulder
  • Right Shoulder
  • Left Wrist
  • Right Wrist

ส่วน Skeleton ที่แสดงบนภาพ ยังประกอบด้วย Elbows, Hips, Knees, Ankles และ Landmark อื่นในชุด COCO Pose

อย่าเข้าใจว่า YOLO ถูก Train ให้รู้จัก “Pull-up”: Model รู้ตำแหน่งคนและข้อต่อ ส่วนความหมายว่า “ขึ้นสุดแล้ว” หรือ “กลับมาห้อยแล้ว” ถูกสร้างขึ้นใน Counting Logic ภายหลัง

Model Spec สำหรับ RK3576 Deployment

รายการ ข้อมูลจาก Project
Architecture YOLO11n Pose
Precision FP16
Input RGB uint8, NHWC, 1 × 640 × 640 × 3
Normalization Mean [0, 0, 0]
Normalization Std [255, 255, 255]
Output 1 × 56 × 8400
Target Platform RK3576
Conversion ONNX → RKNN-Toolkit2 2.3.2

Output ของ Pose Model ประกอบด้วย:

  • 4 ค่า Bounding Box
  • 1 ค่า Person Confidence
  • 17 ชุดของ x, y และ Confidence สำหรับ Keypoint

หลัง Inference Post-processing จะเอา Letterbox Padding ออก ก่อน Map Coordinate กลับไปยังขนาด Frame ต้นฉบับ

ทำไมผู้สร้างเลือก FP16 ก่อน INT8?

เพราะการนับ Pull-up ไม่ได้ต้องการแค่ Detect คนได้ แต่ต้องพึ่ง ตำแหน่ง Keypoint ที่ Stable

ผู้สร้างจึงเริ่ม Deployment ด้วย FP16 เพื่อรักษา Pose Quality ก่อน

INT8 อาจช่วยเรื่องความเร็ว แต่ Source เตือนว่า ควร Calibrate ด้วยภาพ Exercise ที่ใกล้เคียงกับการใช้งานจริง แล้ว Validate ผลลัพธ์เทียบกับ FP16

ประเด็นสำคัญ: สำหรับ Pose Counter Model ที่เร็วขึ้น แต่ตำแหน่ง Nose / Wrist แกว่งมากขึ้น อาจทำให้ State Machine นับผิดได้ จึงต้องดูทั้ง Speed และ Keypoint Stability

หัวใจของ Project: YOLO ไม่ได้นับ Pull-up ให้เอง

หลัง YOLO คืน Keypoint ผู้สร้างต้องแปลง Coordinate เหล่านั้นเป็น Logic ของการออกกำลังกาย

ขั้นตอนหลักมี 6 ส่วน:

  1. ประมาณตำแหน่งบาร์จากข้อมือ
  2. Smooth Bar, Nose และ Shoulder
  3. Normalize ระยะด้วย Bounding Box Height
  4. ใช้ Nose เป็น Top Signal หลัก
  5. สร้าง Top / Bottom Threshold แยกกัน
  6. ต้อง Stable หลาย Frame ก่อนเปลี่ยน State

แนวคิดนี้ทำให้ Model กับ Application Logic แยกหน้าที่กันชัดเจน:

YOLO Pose
= “คนอยู่ตรงไหน ข้อต่ออยู่ตรงไหน”

Pull-Up Counter
= “ตอนนี้อยู่ช่วง Hang, Pulling หรือ Top”

ขั้นแรก: ใช้ข้อมือประมาณตำแหน่ง Pull-up Bar

ระบบดูตำแหน่งแนวตั้ง ของ:

  • Left Wrist
  • Right Wrist

แล้วเฉลี่ยค่าของข้อมือ ที่มองเห็นอยู่ เพื่อ Estimate ตำแหน่งแนวตั้งของ Bar

เหตุผลที่วิธีนี้ใช้ได้กับ Setup นี้ คือระหว่าง Pull-up มือของ Athlete อยู่กับ Bar

Bar Estimate จึงกลายเป็น Reference สำหรับเปรียบเทียบว่า Nose หรือ Shoulder อยู่สูงหรือต่ำกว่าบาร์แค่ไหน

Keypoint สั่นได้ — เลยต้องมี EMA มาช่วย

Pose Keypoint ไม่ได้อยู่ Pixel เดิมนิ่ง ๆ ทุก Frame

แม้คนจะอยู่แทบตำแหน่งเดิม Model ก็อาจคืน Coordinate ขยับเล็กน้อยได้

Project ใช้ Exponential Moving Average เพื่อ Smooth:

  • Bar Position
  • Nose Position
  • Shoulder Position

Current Public GitHub Code ยังแสดงแนวคิดนี้ตรง ๆ: Bar ใช้การ Smooth ที่ช้ากว่า ส่วน Nose / Shoulder ตอบสนองเร็วกว่า

ทำไมไม่ใช้ระยะ Pixel แบบตายตัว?

ถ้าใช้ Threshold แบบ:

“Nose ต้องห่าง Bar ไม่เกิน 40 pixels”

เมื่อ Athlete เดินเข้าใกล้หรือไกลจากกล้อง ขนาดคนในภาพจะเปลี่ยน และ 40 pixels จะไม่ได้แทนสัดส่วนร่างกายเท่าเดิม

Project จึง Normalize ระยะในแนวตั้ง ด้วยความสูงของ Person Bounding Box

ทำให้ Threshold อิงกับสัดส่วนของคนใน Frame มากกว่าจำนวน Pixel ล้วน ๆ

Nose เป็นตัวหลัก แต่ Bar บังหน้าได้

ตำแหน่งบนสุด ใช้ Nose เป็น Signal หลัก

แต่ปัญหาคือ ตอนดึงขึ้นสูง Bar อาจบังบริเวณใบหน้า จน Nose Keypoint หายหรือ Confidence ต่ำ

Project จึงใช้ Shoulder Position เป็น Fallback ในกรณีที่ Nose มองไม่เห็น

นี่เป็น Pattern ที่เจอบ่อยใน Computer Vision: อย่าผูก Decision สำคัญ กับ Landmark เพียงจุดเดียว หากสภาพจริงมีโอกาส Occlusion ของ Landmark นั้น

Hysteresis ช่วยกันอาการ +1 รัว ๆ ตอนค้างอยู่ด้านบน

ถ้าใช้ Threshold เดียว Keypoint ที่สั่นอยู่ใกล้เส้นตัดสิน อาจเด้ง:

ผ่าน → ไม่ผ่าน → ผ่าน → ไม่ผ่าน

แล้วกลายเป็นนับ Rep ซ้ำ

Project เลยใช้:

  • Top Threshold
  • Bottom Threshold

แยกจากกัน เพื่อสร้าง Dead Zone ระหว่าง Transition

ใน Public GitHub Code ปัจจุบันใช้:

Top Threshold = 0.08
Bottom Threshold = 0.12

ค่าพวกนี้ไม่ใช่มาตรฐาน Pull-up สากล: ผู้สร้างระบุว่า Threshold ถูก Tune สำหรับกล้อง ที่ค่อนข้าง Fixed และ Front-facing หากเปลี่ยนมุมกล้อง อาจต้อง Tune ใหม่

State Machine ทำให้ “Pose” กลายเป็น “Rep”

State หลักที่ Project อธิบายมี:

WAITING HANG PULLING TOP

และมี State สำหรับกรณี NO PERSON

Rep ถูกนับเมื่อไร?

ต้องเริ่มจาก Stable Hanging Position แล้วขึ้นไปถึง Stable Top Position

หลัง Count แล้ว ระบบต้องเห็น Athlete กลับลงสู่ HANG ก่อน ถึงจะอนุญาตให้ Count รอบใหม่

Stable Frame ช่วยอีกชั้น

Public GitHub Revision ปัจจุบัน ใช้:

  • 3 Stable Frames ก่อนเข้าสู่ HANG
  • 2 Stable Frames ที่ Top ก่อนเพิ่ม Count

นั่นหมายความว่า Frame เดียวที่ Keypoint เด้งผิด จะไม่ทำให้ Counter เปลี่ยน State ทันที

ถ้ามีหลายคนใน Frame ระบบเลือกใคร?

Application เลือก Person ที่มี Detection Confidence สูงที่สุด

จุดประสงค์คือ ลดโอกาสที่ระบบ จะสลับไปนับคนที่เดินผ่านไกล ๆ ใน Scene

แต่ Highest Confidence Selection ไม่ใช่ Multi-person Tracking: Source ระบุชัดว่า Logic ปัจจุบันออกแบบมา สำหรับ Single-athlete Scene มากกว่า Gym ที่มีคนหลายคน หากต้องการ Multi-athlete จริง Future Improvement คือเพิ่ม Person Tracking

Web Architecture: เปิดหลาย Browser แต่ไม่ควรโหลด Model หลายรอบ

Web Application ใช้ Background Thread เพียงหนึ่งตัว เป็นเจ้าของ RKNN Runtime

แนวคิดคือ:

Camera / Video Source

Single Inference Background Thread

RKNN Runtime + Pull-Up State Machine

Latest Annotated JPEG Frame

Shared ให้ Browser Clients

Latest JPEG Frame ถูก Share ไปยัง Client ผ่าน Condition Variable

ส่วนหน้า Web Poll JSON Status Endpoint ประมาณ 2 ครั้งต่อวินาที

เปิด Dashboard เพิ่มไม่ได้แปลว่า Run YOLO เพิ่มทุกหน้าจอ: Inference หลักอยู่บน Board แล้วส่งผลลัพธ์ล่าสุด ให้ Browser แต่ละเครื่อง

เตรียม RK3576 Deployment Package ตาม Hackster

หน้า Hackster อธิบาย Deployment Folder ที่เตรียมสำหรับ RK3576 โดยรวม:

  • RKNN Model
  • Python Programs
  • Test Video
  • Launch Scripts
  • Integrity Manifest
  • Python 3.11 AArch64 Wheels

เป้าหมายของชุดนี้คือ ให้ติดตั้ง Board ได้แบบ Offline โดยไม่ต้องเข้า PyPI

Copy Package ไป Board

ใช้ SCP ส่ง Folder ไปยัง /home/seeed/

Run Offline Installer

Installer จะสร้าง .venv, ติดตั้ง Dependency จาก Wheel ที่ Bundled มา และทดสอบ NPU ด้วยหนึ่ง Frame

ถ้าสำเร็จ Source ระบุว่าควรเห็น:

Environment check: PASS

ตรวจ Integrity

สามารถใช้ MANIFEST.sha256 ตรวจไฟล์หลัง Transfer ได้

คำสั่งกลุ่มนี้อ้างถึง Package บนหน้า Hackster: Public GitHub Repository ที่เปิดอยู่ตอนนี้ ไม่ได้มี Offline Wheel Bundle, install.sh, run_demo.sh หรือ run_web.sh อยู่ใน Root ที่ตรวจพบ จึงไม่ควร Clone Public Repo แล้วคาดว่าจะใช้คำสั่งชุดนี้ได้ทันที

เริ่มจาก Offline Video Demo ก่อน Live Camera

Hackster Package มี Test Video และ Script:

run_demo.sh

เมื่อทำงานเสร็จ จะสร้าง:

  • video/output/test_counted.mp4
  • video/output/test_counted.csv

MP4 เอาไว้ดูภาพ

Output Video มี Bounding Box, Skeleton, State และ Count วาดอยู่บน Frame

CSV เอาไว้ Debug Logic

CSV เก็บข้อมูลราย Frame เช่น:

  • Frame Number
  • Timestamp
  • Rep Count
  • Current State
  • Person Confidence
  • Estimated Bar Position
  • Nose Position
  • Normalized Nose-to-Bar Distance

เวลานับผิด อย่าดูแค่ Video: CSV ช่วยย้อนดูได้ว่า Frame ไหน State เปลี่ยน, Nose อยู่ตรงไหน และค่าระยะผ่าน Threshold หรือยัง เหมาะมากสำหรับ Tune Counter เมื่อต้องเปลี่ยน Camera Angle

Web Dashboard ดูอะไรได้บ้าง?

ตาม Hackster Deployment เมื่อ Start Web Application ให้เปิด:

http://BOARD_IP:8000

จากโทรศัพท์หรือคอมพิวเตอร์ ที่อยู่ Network เดียวกัน

Dashboard แสดง:

  • Annotated Live Video
  • Repetition Count
  • Current State
  • Stream Frame Rate
  • NPU Inference Latency
  • Person Confidence
  • Video Progress
  • Pause / Resume
  • Reset Count

USB Camera

ใช้ Device Index เช่น 0

RTSP Camera

สามารถส่ง RTSP URL เข้าเป็น Source ตาม Command ของ Project

Port 8000 ถูกใช้แล้ว?

ถ้าเจอ:

Address already in use

Source ระบุว่า Service เดิมอาจยังรันอยู่ หรือสามารถเปลี่ยนไปใช้ Port อื่น เช่น 8080

Performance ที่ผู้สร้างวัดได้

Test Environment ที่หน้า Project ระบุ:

  • AArch64 Linux
  • Python 3.11
  • RKNNLite2 2.3.2
  • RKNN Runtime 2.3.0
  • RKNPU Driver 0.9.8
รายการ ผลที่รายงาน
NPU Inference ประมาณ 70–80 ms ต่อ Frame
Full Web Pipeline ประมาณ 7 FPS
Person Confidence ใน Test Sequence ประมาณ 0.91–0.92

70–80 ms ไม่ได้หมายความว่า Web Stream ต้องได้ 12–14 FPS: ตัวเลขแรกคือเวลา NPU Inference ส่วน Full Pipeline ยังมี Video Decode, Preprocessing, Post-processing, Skeleton Drawing, JPEG Encoding และ Streaming จึงรายงานประมาณ 7 FPS สำหรับระบบครบชุด

Public GitHub ปัจจุบันเป็นอีก Package หนึ่ง

Public Repository inteintegrity/yolo-pullup-counter ที่เปิดอยู่ปัจจุบัน มี Main Script:

pullup_counter.py

และ Dependency:

  • Ultralytics
  • OpenCV
  • NumPy

README อธิบายการรันด้วย yolo11n-pose.pt และระบุว่า Default Version รองรับ CPU Inference

ครั้งแรก Ultralytics สามารถ Download Weight ให้โดยอัตโนมัติ ตาม Workflow ใน README

Public README ยังระบุทางเลือก:

  • เปลี่ยนเป็น yolo11s-pose.pt เพื่อเพิ่ม Pose Accuracy
  • เพิ่ม --imgsz 960 หากคนใน Frame เล็ก
  • ปรับ --keypoint-conf ลงเป็น 0.25 หาก Keypoint ไม่ Stable
  • เปิด --debug เพื่อดูความสัมพันธ์ Bar / Head

ตรงนี้จึงต้องแยกให้ชัด: Public GitHub Version ช่วยศึกษา Pull-up Logic และรันด้วย Ultralytics ได้ แต่ไม่ใช่หลักฐานว่า RK3576 Offline Web Deployment Package ที่ Hackster อธิบาย ถูก Public ไว้ครบทุกไฟล์ใน Repository เดียวกัน

Commands และ Code Snippets จาก Source

เนื่องจาก Source มีทั้ง Hackster RK3576 Package และ Public GitHub Version จึงแยก Command ตามต้นทางให้ชัด

ชุดที่ 1: RK3576 Deployment Commands จาก Hackster

Command ชุดนี้อ้างถึง “Exercise count” Deployment Folder ที่หน้า Hackster อธิบาย ไม่ใช่ Public GitHub Root ที่เปิดอยู่ปัจจุบัน

Copy Package to RK3576
scp -r "Exercise count" seeed@BOARD_IP:/home/seeed/
Offline Install
ssh seeed@BOARD_IP
cd "/home/seeed/Exercise count"
bash install.sh
Verify Transferred Files
sha256sum -c MANIFEST.sha256
Run Offline Demo
cd "/home/seeed/Exercise count"
bash run_demo.sh
Start Web Dashboard
cd "/home/seeed/Exercise count"
bash run_web.sh
Use USB Camera
bash run_web.sh --source 0
Use RTSP Camera
bash run_web.sh --source 'rtsp://user:password@camera/stream'
Change Web Port
bash run_web.sh --port 8080

ชุดที่ 2: Public GitHub Version ปัจจุบัน

Install Python Dependencies
python -m pip install -r requirements.txt
Run Public Pull-Up Counter
python pullup_counter.py --source video/input/test.mp4
Debug Mode
python pullup_counter.py --source video/input/test.mp4 --debug

ตัวอย่าง Threshold จาก Public GitHub Code

Pull-Up Hysteresis Thresholds
top_threshold = 0.08
bottom_threshold = 0.12

ค่า Threshold ข้างต้นมาจาก Public Code Revision ที่ตรวจในบทความนี้ และถูก Tune สำหรับ Scene ของผู้สร้าง ไม่ควรนำไปถือเป็นค่ามาตรฐาน สำหรับทุกกล้องหรือทุกท่าดึงข้อ

ข้อจำกัดที่ต้องรู้ก่อนเอาไปวางใน Gym จริง

1. Threshold ถูก Tune กับกล้องค่อนข้าง Fixed

Source ระบุว่า Setup ปัจจุบัน เน้นกล้องมุม Front-facing ที่ค่อนข้างคงที่

2. Wrist ควรมองเห็นใกล้ Bar

เพราะตำแหน่ง Wrist ถูกใช้ Estimate ตำแหน่ง Pull-up Bar

3. Occlusion มีผลต่อ Stability

ถ้าแขน, หน้า หรือ Landmark ถูกบังหนัก Keypoint อาจไม่ Stable

4. Camera ขยับทำให้ Reference เปลี่ยน

ระบบเหมาะกับกล้อง ที่ติดตั้งค่อนข้างนิ่ง มากกว่ากล้อง Handheld ที่ขยับตลอดเวลา

5. คนเล็กมากใน Frame ทำให้ Pose ยากขึ้น

เมื่อ Athlete กินพื้นที่ภาพน้อยมาก Keypoint Stability สามารถลดลงได้

6. Multi-person ยังไม่ใช่เป้าหมายหลัก

Highest-confidence-person เหมาะกับ Scene ที่มี Athlete หลักเพียงคนเดียว

7. Flask Built-in Server สำหรับ Local Demo

Source ระบุว่า Flask Built-in Server เหมาะกับ Local Demo หากจะนำไป Production ควรใช้ Production WSGI Server และมี Network Access Control ที่เหมาะสม

YOLO ตัวเดิม เปลี่ยน State Machine ก็ไป Exercise อื่นได้

Future Improvement ใน Source เสนอว่า Pose Pipeline เดิม สามารถนำไปใช้กับ:

  • Push-up
  • Squat
  • Sit-up
  • Exercise อื่น

สิ่งที่ต้องเปลี่ยนหลัก ๆ คือ Counting State Machine และ Landmark / Threshold ที่ใช้ตัดสินท่านั้น

Source ยังเสนอแนวทางพัฒนา:

  • Person Tracking สำหรับ Multi-athlete
  • Representative INT8 Calibration Dataset
  • User-selectable Exercise Modes
  • Session History
  • Automatic Camera-angle Calibration

ทั้งหมดนี้เป็น Future Improvements: ไม่ควรเขียนหรือเข้าใจว่า Public Version ปัจจุบัน มี Push-up, Squat, Multi-person Tracking หรือ Session History พร้อมใช้งานแล้ว

ภาพ System และผลลัพธ์เพิ่มเติม

Hero แสดง Demo หลักทันที ส่วนภาพอื่นจาก Source ถูกซ่อนไว้ใน View more เพื่อลดความยาวหน้า ตอนเปิดบนมือถือ

ภาพประกอบระบบ YOLO Pose Pull-Up Counter จากโปรเจกต์ต้นฉบับ
ภาพประกอบจากโปรเจกต์ต้นฉบับ สำหรับทำความเข้าใจระบบ YOLO Pose Pull-Up Counter
ภาพผลลัพธ์หรือ Architecture ของ RK3576 Pull-Up Counter
ภาพประกอบเพิ่มเติม ของ Pipeline / Output จาก Project ต้นฉบับ
ภาพ Web Dashboard หรือผลลัพธ์ Pose Counter จากโปรเจกต์ต้นฉบับ
ภาพผลลัพธ์เพิ่มเติม จาก Real-Time Pull-Up Counter บน RK3576

Project นี้ค่อนข้างลึก — Build จริงควรอ่านต้นฉบับควบคู่กัน

โดยเฉพาะเรื่อง:

  • RKNN Deployment Package
  • Model Conversion
  • NPU Runtime Version
  • Threshold Tuning
  • Camera Angle
  • Web Server Deployment
  • Public GitHub vs Hackster Package

แนะนำให้อ่านต้นฉบับก่อนลงมือ: เปิด Real-Time Pull-Up Counter on RK3576 with YOLO Pose เพื่อดู RK3576 Deployment Workflow และเปิด Public GitHub Repository ของ YOLO Pull-Up Counter เพื่อดู Python Source และ Counting Logic ปัจจุบัน

FAQ: RK3576 YOLO Pull-Up Counter

Project ใช้ AI Model ตัวไหน?

ใช้ YOLO11n Pose pretrained model โดยหน้า Project ระบุว่า ไม่มีการ Train Model เพิ่ม สำหรับ Pull-up

YOLO เป็นตัวนับ Pull-up โดยตรงไหม?

ไม่ YOLO ให้ Person Detection และ Pose Keypoints ส่วนการนับ Rep ทำด้วย Temporal State Machine ที่ผู้สร้างเขียนเพิ่มเอง

ทำไมต้องดูข้อมือ?

Project ใช้ตำแหน่งแนวตั้งเฉลี่ย ของข้อมือที่มองเห็น เพื่อประมาณตำแหน่ง Pull-up Bar

ทำไมใช้ Nose ในการนับ?

Nose เป็น Top-position Signal หลัก แต่ถ้าถูก Bar บัง ระบบใช้ Shoulder เป็น Fallback

State Machine มีไว้ทำไม?

เพื่อให้ระบบรู้ลำดับของการเคลื่อนไหว เช่น HANG → PULLING → TOP และบังคับให้กลับมา HANG ก่อนนับ Rep ใหม่

ทำไมต้องใช้ Top และ Bottom Threshold คนละค่า?

เพื่อสร้าง Hysteresis ลดการนับซ้ำจาก Keypoint Jitter ใกล้เส้นตัดสิน

รองรับหลายคนพร้อมกันไหม?

Version นี้เลือกคนที่ Detection Confidence สูงที่สุด และ Source ระบุว่าเหมาะกับ Single-athlete Scene มากกว่าการ Track คนหลายคนใน Gym

ต้องใช้ Cloud ไหม?

Inference และ Counting ทำบน RK3576 Browser รับผลลัพธ์ที่ประมวลผลแล้ว จึงไม่ต้อง Upload Video ไป Cloud สำหรับ Architecture นี้

รองรับ USB Camera หรือไม่?

รองรับ Hackster ระบุว่าสามารถเลือก USB Camera ผ่าน Device Index เช่น --source 0

รองรับ RTSP Camera ไหม?

รองรับ HTTP / RTSP Stream ที่ OpenCV สามารถเปิดได้

NPU รันได้กี่ FPS?

Source รายงาน NPU Inference ประมาณ 70–80 ms ต่อ Frame แต่ Full Web Pipeline ทำงานประมาณ 7 FPS ใน Environment ที่ผู้สร้างทดสอบ

ทำไม Full Web Pipeline ช้ากว่า NPU Inference?

เพราะยังมี Video Decode, Preprocessing, Post-processing, Pose Drawing, JPEG Encoding และ Streaming นอกเหนือจากเวลาที่ NPU ใช้ Infer

ใช้ INT8 แทน FP16 ได้ไหม?

Source ระบุว่า INT8 อาจเร็วกว่า แต่ควร Calibrate ด้วยภาพ Exercise ที่เหมาะสม และ Validate เทียบกับ FP16 ก่อน Deploy

Public GitHub มี run_web.sh ไหม?

Public Repository ที่ตรวจในบทความนี้ ไม่พบ Script ชุดดังกล่าวใน Root ขณะที่หน้า Hackster อธิบาย Deployment Package ที่มีไฟล์มากกว่า จึงควรแยก Source สองชุดนี้ออกจากกัน

เอา Logic นี้ไปนับ Squat ได้เลยไหม?

Pose Pipeline สามารถนำไปต่อยอดได้ แต่ต้องเปลี่ยน Counting State Machine และ Threshold ตาม Exercise โดย Squat / Push-up / Sit-up ยังถูกระบุเป็น Future Improvement ใน Source

บทเรียนจาก Project นี้: AI เห็น Pose แต่ Application ต้องเข้าใจเวลา

ถ้ามองแค่ Screenshot อาจรู้สึกว่าเป็น “YOLO ดูคนแล้วนับ 1, 2, 3”

แต่พอแกะ Architecture จริง จะเห็นว่ามีหลายชั้น:

Camera → YOLO Pose → Keypoints → Smoothing → Normalization → Hysteresis → State Machine → Rep Count

YOLO เป็นเพียงส่วนหนึ่งของระบบ

สิ่งที่ทำให้ Counter ใช้งานได้จริงขึ้น คือการเอา Pose Landmark ไปเชื่อมกับ Temporal Logic เพื่อเข้าใจว่า Athlete เริ่มจากตรงไหน, ขึ้นถึงไหน และกลับลงมาแล้วหรือยัง

นี่จึงเป็นตัวอย่างที่ดีมาก สำหรับ Maker ที่อยากขยับจาก “ลองรัน AI Model” ไปสู่ “สร้าง Application จากผลของ AI”

References / แหล่งข้อมูลต้นฉบับ

อยากเริ่ม Edge AI Project แต่ยังไม่รู้จะเริ่มจาก Board หรือ Camera ก่อน?

Project แบบนี้มีทั้ง AI / Edge Computing, Camera Input, Python, Computer Vision และ Embedded Hardware ถ้ากำลังหา Development Board, Camera Module, USB Camera หรืออุปกรณ์ Maker สำหรับเริ่ม Prototype สามารถเข้ามาดูสินค้า คุยกับ Community หรือส่งโจทย์ให้ทีม Globalbyte ช่วยแนะนำอุปกรณ์ได้

บทความนี้ไม่ได้ยืนยันว่า Globalbyte มี reComputer RK3576 รุ่นเดียวกับต้นฉบับพร้อมจำหน่าย แนะนำให้สอบถาม Stock และความเหมาะสมของ Hardware ผ่าน LINE OA ก่อนสั่งซื้อ

 


Blog posts