<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Moji</title>
    <description>The latest articles on DEV Community by Moji (@64120501043).</description>
    <link>https://dev.to/64120501043</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1431508%2F3352908b-017c-4bd1-a377-98362699c050.png</url>
      <title>DEV Community: Moji</title>
      <link>https://dev.to/64120501043</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/64120501043"/>
    <language>en</language>
    <item>
      <title>Ai detec มือ เพื่อใช้ในการเล่น game</title>
      <dc:creator>Moji</dc:creator>
      <pubDate>Wed, 17 Apr 2024 15:18:46 +0000</pubDate>
      <link>https://dev.to/64120501043/ai-detec-muue-ephuueaichainkaareln-game-95j</link>
      <guid>https://dev.to/64120501043/ai-detec-muue-ephuueaichainkaareln-game-95j</guid>
      <description>&lt;p&gt;&lt;strong&gt;Dino Game&lt;/strong&gt; เป็นเกมที่เล่นใน Google Chrome เมื่อไม่มีอินเทอร์เน็ต โดยควบคุมไดโนเสาร์ให้กระโดดเพื่อหลีกเลี่ยงอุปสรรค คะแนนเพิ่มขึ้นเรื่อยๆ โดยเกมจะเริ่มช้าและเร่งขึ้นตามเวลา ซึ่งเป็นเกมที่นิยมในเว็บ&lt;br&gt;
โดยใช้ Computer vision ในการเล่นโดยใช้ Mediapipe และ OpenCV เพื่อติดตามมือผู้เล่น เลือกจุดสำคัญบนมือแต่ละข้อ เพื่อกดปุ่ม Spacebar ในเกม แทนการกดปุ่มด้วยมือ ทำให้เล่นเกมสะดวกสบายและสนุกมากขึ้น&lt;br&gt;
&lt;strong&gt;มาดูขั้นตอนการรันโค้ดเลยค้าบ&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import cv2
import pyautogui
import mediapipe as mp
import time
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;เป็นการ import opencv ใช้สำหรับการประมวลผลภาพและวิดีโอใน Python&lt;/li&gt;
&lt;li&gt;เป็นไลบรารีที่ใช้สำหรับควบคุมคีย์บอร์ดและเมาส์ผ่าน Python&lt;/li&gt;
&lt;li&gt;เป็นไลบรารีที่ใช้สำหรับการประมวลผลภาพ&lt;/li&gt;
&lt;li&gt;เป็นไลบรารีสำหรับการจัดการเวลาใน Python
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cap = cv2.VideoCapture(0)

mp_hands = mp.solutions.hands
hands = mp_hands.Hands(static_image_mode=False, max_num_hands=1,
                       min_detection_confidence=0.5, min_tracking_confidence=0.5)

mp_drawing = mp.solutions.drawing_utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;เปิดการใช้งานกล้องหรือวิดีโอจากอุปกรณ์ที่เปิดตัวเป็นกล้อง โดยเลข 0 หมายถึงการใช้กล้องของคอมพิวเตอร์&lt;/li&gt;
&lt;li&gt;เป็นการกำหนดตัวแปร mp_hand &lt;/li&gt;
&lt;li&gt;hands โดยกำหนดเป็นพารามิเตอร์ เป็น 
static_image_mode=False คือ การกำหนดให้โมเดลมือทำงานในโหมดวิดีโอแทนโหมดภาพเคลื่อนไหว
max_num_hands=1 คือ การกำหนดให้ตรวจจับมือได้มือเพียงหนึ่งมือเท่านั้น
min_detection_confidence=0.5 คือ การกำหนดค่าคงที่ขั้นต่ำในการตรวจจับมือ
min_tracking_confidence=0.5 คือ การกำหนดค่าคงที่ขั้นต่ำในการติดตามการเคลื่อนไหวของมือ&lt;/li&gt;
&lt;li&gt;mp_drawing = mp.solutions.drawing_utils เป็นการเพิ่มความสามารถในการแสดงผล โดยการวาดเส้นเชื่อมจุดต่างๆของมือบนภาพ
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;while True:
    ret, frame = cap.read()
    if not ret:
        break

    image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    results = hands.process(image_rgb)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;สร้างลูป while True เพื่ออ่านภาพจากกล้อง โดยใช้คำสั่ง cap.read และเก็บภาพที่ได้ไว้ในตัวแปร frame และตรวจสอบในการอ่านภาพว่าสำเร็จไหม ด้วยตัวแปร ret ถ้าอ่านไม่ได้ ให้หยุดลูปนั้น ด้วยคำสั่ง break&lt;/li&gt;
&lt;li&gt;ทำการแปลงสีของภาพจาก BGR ให้เป็น RGB ด้วยคำสั่ง cv2.cvtColor()&lt;/li&gt;
&lt;li&gt;เรียกใช้ตัวแปร hands ที่กำหนดไว้ มาทำการประมวลผลภาพของมือที่ได้รับจากกล้อง โดยใช้ภาพที่แปลงสีแล้ว ด้วยคำสั่ง hands.process(image_rgb) ซึ่งผลการตรวจจับมือจะเก็บมาไว้ในตัวแปร results
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if results.multi_hand_landmarks:
        for hand_landmarks in results.multi_hand_landmarks:
            mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)

            thumb_tip = hand_landmarks.landmark[mp_hands.HandLandmark.THUMB_TIP]
            index_finger_tip = hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP]
            middle_finger_tip = hand_landmarks.landmark[mp_hands.HandLandmark.MIDDLE_FINGER_TIP]
            ring_finger_tip = hand_landmarks.landmark[mp_hands.HandLandmark.RING_FINGER_TIP]
            pinky_tip = hand_landmarks.landmark[mp_hands.HandLandmark.PINKY_TIP]

            index_finger_mcp = hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_MCP]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;เป็นการตรวจสอบว่ามือที่ตรวจจับได้ในภาพหรือไม่ หากมีการตรวจจับได้ จะทำการลูปผ่านพิกัดของมือทั้งหมด ด้วยคำสั่ง for hand_landmarks in results.multi_hand_landmarks&lt;/li&gt;
&lt;li&gt;ทำการวาดเส้นเชื่อมต่อระหว่างจุดบนมือด้วยคำสั่ง mp_drawing.draw_landmarks() โดยแสดงเส้นเชื่อม ตามข้อมูลการเชื่อมที่ได้จากคำสั่ง mp_hands.HAND_CONNECTIONS&lt;/li&gt;
&lt;li&gt;เก็บพิกัดของจุดที่สำคัญบนมือ เช่น ปลายนิ้วมือต่างๆ ในตัวแปรต่างๆ thumb_tip , index_finger_tip , middle_finger_tip , ring_finger_tip , pinky_tip , index_finger_mcp&lt;/li&gt;
&lt;li&gt;เป็นการเข้าถึงพิกัดจุดที่สำคัญบนมือ ด้วยการใช้ mp_hands.HandLandmark.INDEX_FINGER_MCP ซึ่ง จะเป็นผลลัพธ์ของการตรวจจับมือที่ได้จาก Mediapipe ในภาพ และกำหนดค่าไว้ในตัวแปร index_finger_mcp
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cv2.putText(frame, f"Thumb tip y: {round(thumb_tip.y, 2)}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
            cv2.putText(frame, f"Index tip y: {round(index_finger_tip.y, 2)}", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
            cv2.putText(frame, f"Middle tip y: {round(middle_finger_tip.y, 2)}", (10, 90), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
            cv2.putText(frame, f"Ring tip y: {round(ring_finger_tip.y, 2)}", (10, 120), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
            cv2.putText(frame, f"Pinky tip y: {round(pinky_tip.y, 2)}", (10, 150), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;cv2.putText() เป็นการแสดงข้อความบนภาพวิดีโอที่มาจากกล้อง และแสดงค่าพิกัด y ของปลายนิ้วทั้ง 5 ซึ่งมี 
Thumb tip y : พร้อมกับค่าพิกัด y ของปลายนิ้วโป้ง และ แสดงบนภาพที่ตำแหน่ง (10,30)
Index tip y : พร้อมกับค่าพิกัด y ของปลายนิ้วชี้ และ แสดงบนภาพที่ตำแหน่ง (10,60)
Middle tip y : พร้อมกับค่าพิกัด y ของปลายนิ้วกลาง และ แสดงบนภาพที่ตำแหน่ง (10,90)
Ring tip y : พร้อมกับค่าพิกัด y ของปลายนิ้วนาง และ แสดงบนภาพที่ตำแหน่ง (10,120)
Pinky tip y : พร้อมกับค่าพิกัด y ของปลายนิ้วก้อย และ แสดงบนภาพที่ตำแหน่ง (10,150)&lt;/li&gt;
&lt;li&gt;cv2.FONT_HERSHEY_SIMPLEX แต่ละข้อความจะใช้ฟอนต์ และขนาดข้อความ 1 และสีข้อความเป็นสีเขียว (0,255,0) และความหนาของตัวอักษรเป็น 2
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; is_hand_closed = (
                index_finger_tip.y &amp;gt; thumb_tip.y and
                middle_finger_tip.y &amp;gt; thumb_tip.y and
                ring_finger_tip.y &amp;gt; thumb_tip.y and
                pinky_tip.y &amp;gt; thumb_tip.y
            )
            is_hand_jump = (
                index_finger_tip.y &amp;lt; index_finger_mcp.y and
                middle_finger_tip.y &amp;lt; index_finger_mcp.y and
                ring_finger_tip.y &amp;gt; thumb_tip.y and
                pinky_tip.y &amp;gt; thumb_tip.y
            )

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;กำหนดเงื่อนไขสำหรับการตรวจสถานะของมือ โดย กำหนดขึ้นมา 2 ตัวแปร is_hand_closed และ is_hand_jump ที่จะเก็บค่า (true,false)ตามเงื่อนไข&lt;/li&gt;
&lt;li&gt;is_hand_closed เป็นการตรวจสอบว่ามือปิดหรือไม่โดยการดูจากตำแหน่ง y ของปลายนิ้วทั้ง 5 นิ้ว ว่า ตำแหน่งนิ้วก้อยอยู่ต่ำกว่าต่ำแหน่งนิ้วโป้งหรือไม่&lt;/li&gt;
&lt;li&gt;ถ้าปลายนิ้วทั้ง 4 อยู่ต่ำกว่าปลายนิ้วโป้ง แสดงว่ามือกำลังจะปิด และเก็บค่าเป็นค่า true &lt;/li&gt;
&lt;li&gt;is_hand_jump เป็นการตรวจสอบว่าปลายนิ้วชี้และนิ้วกลางอยู่ต่ำกว่าจุด MCP ของนิ้วชี้หรือไม่
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if is_hand_closed:
                pass
            if is_hand_jump:
                pyautogui.press('space')
                time.sleep(0.1)


    cv2.imshow('CV', frame)

    if cv2.waitKey(1) &amp;amp; 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;คำสั่ง if is_hand_closed ตรวจสอบว่า มือปิดหรือไม่ ถ้าใช่ จะเป็น pass &lt;/li&gt;
&lt;li&gt;คำสั่ง if is_hand_jump ตรวจสอบว่ามือกำลังมีการเคลื่อนไหวหรือกระโดด ถ้าใช่ จะเป็นการใช้ pyautogui.press('space') เพื่อจำลองการกดปุ่ม space บนแป้นพิมพ์ การหน่วงเวลา 0.1 วินาทีหลังการกดปุ่มเพื่อป้องกันการกดซ้ำที่รวดเร็วเกินไป&lt;/li&gt;
&lt;li&gt;cv2.imshow('CV', frame) เป็นการแสดงผลภาพวิดีโอที่ได้จากกล้อง&lt;/li&gt;
&lt;li&gt;คำสั่ง if cv2.waitKey(1) &amp;amp; 0xFF == ord('q'): เป็นการใช้สำหรับการออกจาก loop และปิดหน้าต่างโปรแกรมเมื่อผู้ใช้กดปุ่ม 'q'&lt;/li&gt;
&lt;li&gt;คำสั่ง cap.release() และ cv2.destroyAllWindows() เป็นการใช้สำหรับปิดการจับภาพวิดีโอและปิดหน้าต่าง GUI ทั้งหมดตามลำดับ&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;สรุปผล&lt;/strong&gt;&lt;br&gt;
Dino Game การเล่นจะมีความท้าทายเพิ่มมากขึ้นตามความเร็วที่เพิ่มขึ้น Computer vision ในการเล่นเกมโดยใช้ Mediapipe และ OpenCV เพื่อทำให้ผู้เล่นสามารถควบคุมไดโนเสาร์ด้วยการขยับมือหรือนิ้วแทนการกดปุ่ม Spacebar ในคีย์บอร์ด การนำไปต่อยอดในการเพิ่มความสะดวกสบายและความสนุกในการเล่นเกมที่มีความหลากหลายมากขึ้นจากวิธีการเล่นแบบเดิมๆ ด้วยการใช้ Computer vision เพื่อแทนการกดปุ่ม Spacebar ในกระโดดของเกม Dino Game&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ตัวอย่างการ detec มือ&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvz32gs3xtc3xtoz860dw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvz32gs3xtc3xtoz860dw.jpg" alt="Image description" width="630" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=QekxFU0YDqM"&gt;https://www.youtube.com/watch?v=QekxFU0YDqM&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/rocketingdatascience/Gaming_with_Hand_Gestures_Recognition/blob/main/OpenCV%20Play%20Dino%20Game.py"&gt;https://github.com/rocketingdatascience/Gaming_with_Hand_Gestures_Recognition/blob/main/OpenCV%20Play%20Dino%20Game.py&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>gamedev</category>
      <category>python</category>
    </item>
  </channel>
</rss>
