Gaming with Programmer: Basic OpenCV

Max, Who's done well on his jobs
TakoDigital
Published in
3 min readDec 14, 2023

หลังจากที่เราใช้ app แบบ Programmer ไปแล้ว (ตามข่าว) วันนี้เราก็จะมาเล่น game แบบ Programmer พร้อมกับเรียนเขียน Python ควบคู่ไปด้วย มาเริ่มกันดีกว่า ไปให้สุดแล้วหยุดที่โดนแบน

ก่อนอื่นเราต้องรู้ก่อนว่าเครื่องมือแล้วก็ภาษาที่ใช้ในการเล่นเกมของเรามีอาไรบ้าง เริ่มจากภาษาแล้วก็ Libs ที่ใช้ก่อนก็แล้วกัน ส่วนโปรแกรมเขียน Code อยากใช้ตัวไหนก็ได้แล้วแต่ถนัดเลย

  • Python3 (ในตัวอย่างใช้ version 3.9.xx)
  • OpenCV2
  • numpy
  • YOLO
  • Pyautogui or Pywin32

สี่ตัวล่างจะเป็น libs หลักที่ใช้เลย อันดับแรกเราก็ต้องรู้พื้นฐานกันก่อน โดยจะเริ่มจาก OpenCV2 เพราะส่วนตัวก็ยังไม่เคยศึกษา Python แบบจริงจังมาก่อน ค่อยๆเรียนรู้จากการทำบอททีเดียวเลย

OpenCV2

OpenCV2 ก็เปรียบเสมือนตาของเรา สามารถศึกษา OpenCV2 เพิ่มเติมได้ที่ link นี้ถ้าใครสนใจ เราเน้นทำจริงไปก่อนแล้วค่อยมาอ่าน Documents ทีหลัง

เริ่มจากดึงไฟล์รูปที่เราจะให้วาดกรอบมารอไว้ก่อน

ระวัง Path รูปต้องถูกด้วยนะ ถ้าไม่อย่างนั้นเมื่อเรากดรันโปรแกรม โปรแกรมรันได้ปกติ แต่จะไม่มี Error ฟ้องขึ้นมาว่าผิดที่ไหน

เวลาเราทำงานเกี่ยวกับรูป ถ้าไฟล์รูปมีความละเอียดสูง จะทำให้คอมเราใช้ทรัพยากรณ์มากเกินความจำเป็น เราสามารถใช้วิธี resize image ได้ หรือว่าว่าจะใช้เทคนิค ทำให้รูปเป็นสีขาวดำ (gray scale) หรือ Algorithm อื่นๆ ก็ได้ กดรันโปรแกรมได้เลย

จะได้รูปแมวแบบนี้ขึ้นมา ต่อไปเราจะใช้ OpenCV2 วาดกรอบให้กับแมวส้ม

รูปภาพจะเริ่มนับ x, y จากซ้ายบนของรูปเป็น (x, y) หรือ (0, 0) แล้วขวาล่างก็จะเป็น x + ความกว้างของรูปและ y + ความสูงของรูป ตามลำดับ

เราจะเรียกจุดเริ่มเป็น x1, y1 แล้วจุดสิ้นสุดจะเป็น x2, y2 ก็แล้วกันเพิ่อความง่าย

พอเรารู้ตำแหน่งหัวของแมวส้มแล้ว ก็มาใส่ใน code เลยก็จะได้ประมาณนี้

กดรันได้

เรียบร้อยยยยย แถมแมวดำไปอีกตัว

ต่อไปเราจะมาหา ตำแหน่งของมอนสเตอร์ในแผนที่โดนใช้ function ที่ OpenCV2 ให้มานะครับ ตามรูปด้านล่าง

ก่อนอื่นมาเตรียมรูปรอได้เลย ซึ่งรูปที่ต้องการก็คือรูปของ มอนสเตอร์ ที่เราจะไปตี แล้วก็ screen capture ของเกมส์ ตามตัวอย่างด้านล่างนี้

ต่อไปใน code เราก็ต้อง ดึงรูปที่เราเตรียมไว้มาแล้วใช้ function ที่ชื่อว่า matchTemplate ในการหากระต่ายในเกมส์

ทุกคนจะเห็นว่า matchTemplate มีรับค่า รูปในเกมส์, รูปกระต่าย แล้วอันสุดท้ายคืออะไร (.TM_CCOEFF_NOMED) ทำไมต้องใส่ บอกเลยว่าตัวสำคัญที่สุดคือตัวนี้แหละที่ทำให้หากระต่ายเจอ มันคือ Algorithm ซึ่งมีให้ใช้หลายตัวเลยเข้าไปอ่านหรือศึกษาเพิ่มเติมได้จาก OpenCV: Template Matching ได้เลยนะครับ

มาถึงตรงนี้กดรันอีกรอบ เราก็จะได้ตำแหน่งของกระต่ายมาเรียบร้อยแล้ว ตามรูปด้านล่าง

แต่เอ๊ะในเกมส์มันมีกระต่ายหลายตัวทำไมมันมีกรอบเดียวละ

เพราะว่าเราต้อง loop ยังไงละ เพราะว่า matchingResult เป็น list ทั้งหมด ส่วนใน code ด้านบนเราดึงมาเฉพาะตำแหน่งของกระต่ายที่ได้ค่าความมั่นใจมากที่สุดมาแสดง

แต่ไม่ใช่กระต่ายอย่างเดียวที่เจอนะ จุดขาวคือจุดที่โปรแกรมมีค่าความมั่นใจสูงสุด ส่วนตำแหน่งอื่นๆก็จะมีค่าลดลงไป

เราก็ต้องใช้ตัวช่วยหรือเทคนิคเพิ่ม ที่เรียกว่า threshold ซึ่งค่าของ threshold จะขึ้นอยู่กับผลลัพธ์ของรูปที่เราหาอีกที เราต้องเป็นคนกำหนดเองอีกที่ว่าค่าที่เหมาะสมของ threshold จะต้องมีค่าเท่าไหร่ อาจจะเริ่มตั้งค่าตัวเลขน้อยๆไว้ก่อน อย่างเช่น 0.70–0.80 ไปก่อนแล้วค่อยมาปรับให้สูงขึ้นในรอบต่อไปเพื่อให้ตรงกับความต้องการของเรา

กดรันอีกรอบ

มาแล้วกระต่ายหลายตัว แต่เอ๊ะอีกรอบทำไมกรอบมันหนาผิดปกติ มันเป็นเพราะว่าตอนที่เทียบรูปมันเจอที่ใกล้เคียงกันที่มัน threshold ที่สูงเกิน 0.80

แล้วทำไมเราไม่ตั้งค่าใน threshold สูงๆไปเลยละ มันก็มีเหตุผลของมันอยู่ว่า บางรูปที่ความละเอียดต่ำหรือว่ามีอะไรมาบังมันก็จะมีค่า threshold ที่ต่ำลงไป แล้วถ้าเป็นแบบนี้เราต้องทำยังไง ไปลุยกันต่อเลย

อธิบายกันต่อ ใน code ด้านบนเราใช้เทคนิคการ grouping โดยใช้ function ที่เรียกว่า groupRectangles แต่ก่อนที่จะใช้ function นี้ได้เราก็ต้อง loop กระต่ายที่เจอทั้งหมดก่อนเพื่อให้กลุ่มของกระต่ายมีความชัดเจนยิ่งขึ้น หลังจากได้ผลลัพธ์แล้วก็เอามาวาดกรอบให้มันอีกที

กดรันโปรแกรมอีกรอบ

มาแล้วววว กระต่ายสองตัวของเราาาาา

ในบทความต่อไปเราจะไปตีกระต่ายกันนนน

--

--