← Back to list

MediaPipe — ทำ Six Seven Counter … ทำไม?

ช่วงนี้ ถ้าใครได้เลื่อนดู shorts หรือ reels ก็คงจะเห็นโปรเจคแนว ๆ นี้กันบ้าง ที่เป็นคนเปิดกล้องแล้วทำท่า “six seven” หลังจากนั้นก็ให้ AI…

RuffLogix · 2026-07-03 07:45 · 0 claps · 2.5 min read
#pose-estimation #computer-vision #mediapipe #python #machine-learning
Open on Medium ↗
Wiki topics: ML · Machine Learning EDU · Education & Learning

MediaPipe — ทำ Six Seven Counter … ทำไม?

ช่วงนี้ ถ้าใครได้เลื่อนดู shorts หรือ reels ก็คงจะเห็นโปรเจคแนว ๆ นี้กันบ้าง ที่เป็นคนเปิดกล้องแล้วทำท่า “six seven” หลังจากนั้นก็ให้ AI นับว่าเราทำไปกี่ครั้งแล้ว? หรือ ภายในเวลาที่กำหนดเราทำได้ทั้งหมดกี่ครั้ง (ฟีล ๆ wpm แต่เป็น 67pm แทน) เนื่องจากระหว่างนี้ได้ลองทำโปรเจคเกี่ยวกับ pose estimation พอดีเลยอยากลองทำ AI นับ 67 ดู ถือว่าลองทำโปรเจคจริง (?) สักอย่างก่อนไปทำอย่างอื่นต่อ 555

Six Sevennnnnnn (Thanks ChatGPT)

Six Sevennnnnnn (Thanks ChatGPT)

รู้จักกับ Pose Estimation

Pose Estimation เป็น งานทางด้านภาพประเภทหนึ่งที่ใช้ในการ “ระบุจุด หรือ keypoint ในภาพ” ตัวอย่าง เช่น ไหล่ ข้อศอก ข้อมือ หรือ ขา เพื่อนำไปใช้ต่อกับงานอื่น ๆ อีก

Pose Estimation I (Thanks ChatGPT)

Pose Estimation I (Thanks ChatGPT)

ซึ่งหลัก ๆ แล้วสิ่งที่เราจะได้มาจากขั้นตอนดังกล่าวจะประกอบไปด้วย (i) Landmark (ii) Connection เพื่อระบุว่าเรามีจุดและเส้นเชื่อมจากจุดไหนไปจุดไหนบ้าง

Mediapipe

Mediapipe เป็น framework เกี่ยวกับงานด้านภาพจาก Google ซึ่งหนึ่งเครื่องมือที่สามารถนำมาใช้ได้ก็คือ Pose Estimation

[embed]MediaPipe Solutions guide | Google AI Edge | Google for Developers MediaPipe Solutions provides a suite of libraries and tools for you to quickly apply artificial intelligence (AI) and…developers.google.com

Let’s Code!

ในขั้นตอนนี้เราจะแบ่งโค้ดหลัก ๆ เป็น 2 ส่วน

  1. Pose Estimation
  2. Six Seven Counter

Pose Estimation

หลัก ๆ เราจะใช้ feature ของ mediapipe ที่เป็น live stream ในการทำงานร่วมกับกล้อง webcam สำหรับการทำ real time pose estimation ซึ่งขั้นตอนหลัก ๆ ของเราจะแบ่งเป็น

(i) Setup Model Options

ในขั้นนี้โมเดลที่เลือกจะเป็น LITE_MODEL ซึ่งเป็นโมเดลขนาดที่เล็กที่สุดแล้ว

options = PoseLandmarkerOptions(
    base_options=BaseOptions(model_asset_path=model_path),
    running_mode=VisionRunningMode.LIVE_STREAM,
    result_callback=self._pose_landmarker_result_callback,
)

(ii) Inference Pose Estimation

with PoseLandmarker.create_from_options(self.options) as landmarker:
    landmarker.detect_async(input_image, timestamp_ms)

หลังจากที่เราทำกระบวนการที่ (ii) เราจะได้ผลลัพธ์เป็น ข้อมูล landmark และ connection ของ joint ต่าง ๆ ที่พร้อมสำหรับการนำไปใช้ต่อแล้ว

Pose Estimation II(Thanks ChatGPT)

Pose Estimation II(Thanks ChatGPT)

Six Seven Counter

หลังจากที่เราได้ตัวของ landmark กับ connection กันมาแล้ว เราจะใช้ข้อมูลส่วนนี้ในการคำนวณการขึ้นลงของมือกัน

เราจะนิยามว่า “การทำ six seven 1 รอบ คือ การที่มือแต่ละข้าง ขึ้น-ลง อย่างน้อย 1 ครั้ง” แล้วคำถามถัดมาคือ “เราจะรู้ได้ยังไงว่ามือนั้น ขึ้น-ลง แล้ว?”

เราสามารถมอง connection ระหว่าง joint เป็น vector แล้วเราจะทำการหามุมระหว่าง vector นั้น ๆ แทน ซึ่งเราจะหามุมระหว่าง ไหล่-ศอก-ข้อมือ

def _calculate_angle(self, shoulder, elbow, wrist):
    a = np.array(shoulder)
    b = np.array(elbow)
    c = np.array(wrist)

    ba = a - b
    bc = c - b

    cosine_angle = np.dot(ba, bc) / (np.linalg.norm(ba) * np.linalg.norm(bc))
    angle = np.arccos(cosine_angle)

    return np.degrees(angle)

โดย เราจะดึงข้อมูล landmark ของ ไหล่-ศอก-ข้อมือ ได้จาก index ของ landmark

# Right Hand
right_shoulder = (
    landmarks[mp.tasks.vision.PoseLandmark.RIGHT_SHOULDER].x,
    landmarks[mp.tasks.vision.PoseLandmark.RIGHT_SHOULDER].y,
)
right_elbow = (
    landmarks[mp.tasks.vision.PoseLandmark.RIGHT_ELBOW].x,
    landmarks[mp.tasks.vision.PoseLandmark.RIGHT_ELBOW].y,
)
right_wrist = (
    landmarks[mp.tasks.vision.PoseLandmark.RIGHT_WRIST].x,
    landmarks[mp.tasks.vision.PoseLandmark.RIGHT_WRIST].y,
)

# Left Hand
left_shoulder = (
    landmarks[mp.tasks.vision.PoseLandmark.LEFT_SHOULDER].x,
    landmarks[mp.tasks.vision.PoseLandmark.LEFT_SHOULDER].y,
)
left_elbow = (
    landmarks[mp.tasks.vision.PoseLandmark.LEFT_ELBOW].x,
    landmarks[mp.tasks.vision.PoseLandmark.LEFT_ELBOW].y,
)
left_wrist = (
    landmarks[mp.tasks.vision.PoseLandmark.LEFT_WRIST].x,
    landmarks[mp.tasks.vision.PoseLandmark.LEFT_WRIST].y,
)

จากนั้นเราจะนิยาม state ของ counter เราดังนี้ ถ้ามุมที่คำนวณได้น้อยกว่า 90 องศา ให้หมายถึงว่าเรากำลังยกแขนขึ้น แต่ถ้ามากกว่านั้นถือว่ายกแขนลง

State Diagram (Thanks ChatGPT)

State Diagram (Thanks ChatGPT)

  • IDLE (0 หรือ 00)กรณีที่ยังไม่ได้ยกมือ
  • LEFT_UP (1 หรือ 01)กรณีที่เคยยกมือข้างซ้ายแล้ว
  • RIGHT_UP (2 หรือ 10)กรณีที่เคยยกมือข้างขวาแล้ว
  • BOTH_UP (3 หรือ 11)กรณีที่เคยยกมือทั้งสองข้าง (เราจะนับแต้มกันใน state นี้)
def _update_state(self, left_arm_up, right_arm_up):
    if left_arm_up and self.prev_left == 2:
        self.state |= 1 << 0
    if right_arm_up and self.prev_right == 2:
        self.state |= 1 << 1

    if self.state == 3:
        self.count += 1
        self.state = 0
        self.prev_left = 0
        self.prev_right = 0

    self._update_prev_state(left_arm_up, right_arm_up)

ในส่วนของ prev_state ของมือแต่ละข้างจะแบ่งเป็น

  • 0 คือ ยังไม่เคยยกมือมาก่อน
  • 1 คือ กำลังยกมือขึ้น
  • 2 คือ เคยยกมือขึ้นแล้วเอาลงอย่างน้อย 1 รอบ

หลังจากนั้นไม่ว่าจะขึ้นหรือลงก็จะค้างที่ 2 เสมอ จนกว่าจะเข้า BOTH_UP ถึงจะกลับไปที่ 0 ใหม่ (สรุป 0 -> 1 -> 2 -> 0 -> …)

ผลลัพธ์ที่ได้:

Result from Our Counter!

Result from Our Counter!

จริง ๆ ช่วงนี้ทำอยู่หลายโปรเจคเลยทำให้ไม่ค่อยได้เขียนโค้ดเองเล่น ๆ แบบนี้สักพักแล้ว ส่วนมากจะ vibe เอา 555 สำหรับคนที่สนใจลองจิ้ม ๆ ดูโค้ดได้ในนี้เลยครับบ

[embed]GitHub - RuffLogix/simple-pose-estimation: A simple pose estimation project for practice and… A simple pose estimation project for practice and learning. - RuffLogix/simple-pose-estimationgithub.com


메타데이터
post_id
d3fbfae98c6b
slug
mediapipe-ทำ-six-seven-counter-ทำไม-d3fbfae98c6b
url
https://medium.com/@rufflogix/mediapipe-%E0%B8%97%E0%B8%B3-six-seven-counter-%E0%B8%97%E0%B8%B3%E0%B9%84%E0%B8%A1-d3fbfae98c6b
canonical_url
https://medium.com/@rufflogix/mediapipe-%E0%B8%97%E0%B8%B3-six-seven-counter-%E0%B8%97%E0%B8%B3%E0%B9%84%E0%B8%A1-d3fbfae98c6b
author_url
https://medium.com/@rufflogix
status
ok
fetched_at
2026-08-12 23:48:45