[TH] QRCode Detected!

บทความนี้อธิบายวิธีการใช้ OpenCV เพื่อค้นหา QRCode จากภาพที่ได้จาก Web Camera ที่พ่วงต่อจากพอร์ต USB ของ Raspberry Pi เมื่อพบ QRCode ในภาพจะทำการถอดรหัสและแสดงผลข้อความที่ถอดรหัสได้ โดยตัวอย่างของบทความนี้ประกอบด้วยตัวอย่างการอ่านแสดงผลจากกล้องเว็บ และออกจากโปรแกรมด้วยการกดแป้น ESC กับตัวอย่างการค้นหารหัส QRCode และถอดรหัสข้อความภายในภาพพร้อมจัดเก็บผลลัพธ์ของภาพลงไฟล์ภาพ

ภาพที่ 1

อุปกรณ์

ในการทดลองของบทความนี้ใช้อุปกรณ์ต่อไปนี้

  1. บอร์ด Raspberry Pi 3 หรือ 4
  2. กล้อง Web Camera แบบ USB

ชุดคำสั่งที่ควรรู้

การใช้งาน OpenCV ต้องเรียกใช้คลังไลบรารี opencv โดยคำสั่งสำหรับใช้งานที่เกี่ยวข้องกับบทความนี้เป็นดังนี้

  1. วัตถุกล้อง = cv2.VideoCapture( ลำดับกล้อง ) สำหรับเชื่อมต่อกล้อง โดยต้องระบุลำดับของกล้องที่เชื่อมต่อให้ถูกต้อง
  2. ผลลัพธ์ = วัตถุกล้อง.isOpened( ) คืนค่าสถานะการพร้อมใช้ของกล้อง ถ้าเป็น True หมายถึงกล้องพร้อมใช้งาน และถ้าเป็น False หมายถึงกล้องไม่พร้อมทำงาน
  3. ผลลัพธ์,ภาพ = วัตถุกล้อง.read() อ่านข้อมูลจากกล้อง โดยผลลัพธ์เป็น true หมายถึงอ่านสำเร็จ และเก็บข้อมูลของภาพ
  4. cv2.imshow( “ชื่อหน้าต่าง”, ภาพ ) นำภาพแสดงผลบนจอแสดงผล
  5. cv2.destroyAllWindows() สำหรับสั่งปิดหน้าต่างที่เปิดไว้
  6. ผลลัพธ์ = cv2.waitKey( 1 ) สำหรับอ่านค่าจากแป้นพิมพ์ และเก็บรหัสของแป้นพิมพ์ไว้ในผลลัพธ์
  7. วัตถุ = cv2.QRCodeDetector() สร้างวัตถุสำหรับตรวจสอบ QRCode
  8. text, points = qrCodeDetector.detectAndDecode( ภาพ ) ถอดรหัส QRCode จากในภาพ ถ้า points เป็น none แสดงว่าไม่พบ QRCode ในภาพ และ text เก็บผลลัพธ์การถอดรหัส QRCode เป็นข้อความ
  9. cv2.imwrite( “ชื่อไฟล์”, ภาพ ) บันทึกภาพลงไฟล์ภาพ โดยในชื่อภาพต้องระบุนามสกุลของภาพด้วย
  10. วัตถุกล้อง.release() สำหรับปล่อยการถือครองการใช้กล้อง

ตัวอย่างที่ 1

ตัวอย่างโปรแกรม code24-1 เป็นตัอย่างการใช้งานกล้องตัวที่ 1 (ลำดับ 0) เพื่ออ่านข้อมูลภาพและนำข้อมูลภาพมาแสดงผล โดยโปรแกรมจะสิ้นสุดการทำงานเมื่อผู้ใช้กดแป้น ESC โดยในการทำงานแต่ละรอบทำการนับค่าลำดับของเฟรมการแสดงผลไปด้วย

# code24-1
import sys
import cv2
import time
camera = cv2.VideoCapture(0)
if (camera.isOpened() == False):
    print("Can not open camera #0.")
    sys.exit(0)
print("Camera ready")
frameCounter = 0
doAgain = True
while doAgain:
    ret, image = camera.read()
    if ret:
        frameCounter += 1
        print("frame no.{}".format(frameCounter))
        cv2.imshow("Image", image)
        key = cv2.waitKey(1) & 0xFF
        if key == 27: # ESC
            cv2.destroyAllWindows()
            doAgain = False
camera.release()

ตัวอย่างที่ 2

ตัวอย่างโปรแกรม code24-2 เป็นการนำ code24-1 มาปรับปรุงเพิ่มเติมการตรวจสอบ QRCode ในภาพ และเมื่อพบ QRCode ในภาพจะทำการถอดรหัสและบันทึกภาพที่พบลงไฟล์ result.jpg ดังตัวอย่างในภาพที่ 2 และ 3

#code24-2
import sys
import cv2
import time
camera = cv2.VideoCapture(0)
if (camera.isOpened() == False):
    print("Can not open camera #0.")
    sys.exit(0)
print("Camera ready")
doAgain = True
while doAgain:
    ret, image = camera.read()
    if ret:
        qrCodeDetector = cv2.QRCodeDetector()
        text, points = qrCodeDetector.detectAndDecode(image)
        if points is not None:
            print(text)
            cv2.imwrite("./result.jpg",image)
        else:
            print("QR code not detected")
        cv2.imshow("Image", image)
        key = cv2.waitKey(1) & 0xFF
        if key == 27: # ESC
            cv2.destroyAllWindows()
            doAgain = False
camera.release()
ภาพที่ 2 ผลลัพธ์จากการพบ QRCode และผลของการถอดรหัส
ภาพที่ 3 ตัวอย่างผลลัพธ์ที่ code24-2 บันทึกเมื่อพบ QRCode ในภาพ

สรุป

จากบทความนี้ผู้อ่านจะพบว่า การใช้งาน openCV เพื่ออ่านค่าข้อมูลที่ได้จากกล้องนั้นมีความสะดวกและไม่ซับซ้อน และมีไลบรารีที่เตรียมไว้ให้ใช้งานได้โดยตรงลดการเขียนโค้ด ซึ่งจากตัวอย่างในบทความนี้ผู้อ่านจะสามารถเขียนโปรแกรมเพื่อแสดงภาพจากกล้องเว็บที่เชื่อมต่อกับพอร์ต USB ของบอร์ด Raspberry Pi3/4 หรือกับเครื่อง PC บนระบบปฏิบัติการ Windows, Linux หรือ macOS หลังจากนั้นในตัวอย่างที่ 2 จะพบว่าเมื่อสร้างวัตถุประเภท QRCode จะทำให้สามารถตรวจสอบจำนวน QRCode ที่พบในภาพ พร้อมทั้งถอดรหัสของ QRCode ที่พบให้เป็นข้อความ

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

(C) 2020, โดย อ.ดนัย เจษฎาฐิติกุล/อ.จารุต บุศราทิจ
ปรับปรุงเมื่อ 2020-12-09
ปรับปรุงเมื่อ 2021-09-09