ระบบตอบโต้ข้อความเสียงสำหรับงานทะเบียน “น้องศรี” (Assistant Bot) With Python + MySQL

ผู้เขียนบทความ :

070 นายนัสรี ม่องพร้า COE #16                  

061 นายชานนท์ เส็นหนับ COE #16      

088 นายทักษกร อเปสริยาโย COE #16  

049 นายฮานาฟี ยูโซ๊ะ COE #16    

คณะวิศวกรรมศาสตร์ สาขาวิชา วิศวกรรมคอมพิวเตอร์

วิชา : 04-513-201 การโปรแกรมคอมพิวเตอร์ขั้นสูง 1/2567

1.ความเป็นมา

ปัจจุบันนักศึกษาได้ประสบกับปัญหาการดำเนินการด้านเอกสารจากฝ่ายทะเบียน โดยการที่นักศึกษาไม่รู้ขั้นตอนหรือมีความเข้าใจผิดในการทำเรื่องเอกสาร จึงทำให้ต้องมาสอบถามเจ้าหน้าที่อีกครั้ง ทำให้เสียเวลาและสร้างความยุ่งยากแก่ตัวนักศึกษาและเจ้าหน้าที่ฝ่ายทะเบียนเอง ด้วยเหตุนี้พวกเราจึงได้ระดมความคิดออกแบบระบบตอบคำถามเรื่องที่เกี่ยวกับงานทะเบียนให้แก่นักศึกษาเพื่ออำนวยความสะดวกให้นักศึกษาและยังแบ่งเบาภาระหน้าที่ของเจ้าหน้าที่ฝ่ายทะเบียน ประกอบไปด้วยในปัจจุบัน ระบบสารสนเทศเข้าถึงได้ง่าย ทำให้พวกเราตัดสินใจที่จะสร้างระบบ “น้องศรี assistant bot” ขี้นโดยที่จะเป็นในรูปแบบ ตอบโต้ด้วยเสียง เพื่อแก้ปัญหาข้างต้นและยังสามารถเข้าถึงข้อมูลได้อย่างรวดเร็ว และมีประสิทธิภาพ

2.วัตถุประสงค์

2.1 เพื่อช่วยแก้ปัญหาให้กับบุคลากร หรือ นักศึกษา ที่ต้องการสอบถามกิจกรรมหรือกำหนดการต่างๆเกี่ยวกับงานทะเบียน สามารถเข้าถึงข้อมูลได้ทันที

2.2 เพื่อลดขั้นตอนความยุ่งยากแก่ผู้มาสอบถามงานทะเบียน โดยสามารถสนทนากับน้องศรีถึงข้อมูลที่ต้องการได้

2.3 เพื่อช่วยลดภาระของเจ้าหน้าที่เกี่ยวกับงานทะเบียน จากคำถามทั่วไปหรือกำหนดการต่างๆของมหาวิทยาลัย

3.ขอบเขต

3.1 สามารถรับข้อความเสียงของผู้ใช้งานแล้วแปลงเป็นข้อความ แสดงออกทางหน้าจอได้ทันที

3.2 สามารถถอดข้อความเสียงภาษาไทยได้แม่นยำถึง 80% หรือ มากกว่านั้น

3.3สามารถแยกคำถามที่สามารถตอบได้หรือไม่สามารถตอบได้

4.ประโยช์นที่คิดว่าจะได้รับ

4.1 ทำให้บุคลากร หรือ นักศึกษา ที่ต้องการสอบถามกิจกรรมหรือกำหนดการต่างๆเกี่ยวกับงานทะเบียน สามารถเข้าถึงข้อมูลได้ทันที

4.2 สามารถแยกแยะภาษาที่รับเข้ามาแล้วตอบโต้กลับไปยังต้นทางได้

4.3 สามารถแยกคำและจับใจความสำคัญของคำถามได้

5.ข้อมูลที่เกี่ยวข้อง

-โมดูล gTTs คือ โมดูลที่ดึง Google TTS (Text-to-Speech) API เข้ามาใช้งาน โดยจะสร้างไฟล์เสียงสังเคราะห์ขึ้นมาในรูปแบบ mp3 ไม่จำกัดความยาว รองรับภาษาต่าง ๆ รวมถึงภาษาไทยด้วย
-โมดูล speech recognition เป็นไลบรารีที่ออกแบบมาเพื่อช่วยให้การประมวลผลคำพูดเป็นข้อความทำได้ง่ายขึ้น โดยมันรองรับการทำงานกับหลาย API และระบบบริการการรู้จำเสียง (speech recognition) รวมถึง Google Speech Recognition, Microsoft Bing Voice Recognition, IBM Speech to Text และอื่นๆ อีกหลายบริการ
-โมดูล pygame เป็นไลบรารีในภาษา Python ที่ใช้สำหรับพัฒนาเกม 2D และงานมัลติมีเดียต่าง ๆ เช่น การเล่นเสียง, การแสดงผลภาพกราฟิก และการจัดการการอินเทอร์แอคชั่นกับผู้ใช้ (เช่น คีย์บอร์ด, เมาส์, จอยสติ๊ก) นอกจากนี้ยังมีการจัดการเฟรมเรต (Frame Rate) เพื่อการแสดงผลที่ราบรื่น
– ฐานข้อมูล Data Base คือ ฐานข้อมูลช่วยในการจัดเก็บข้อมูลอย่างเป็นระเบียบ โดยสามารถใช้จัดเก็บข้อมูลที่จำเป็น เช่น ข้อความที่สามารถค้นหาหรือข้อมูลต่างๆ ที่โปรแกรมต้องการ โดยใช้ SQL สำหรับการเข้าถึงและจัดการข้อมูล ทำให้สามารถดึงข้อมูลที่ต้องการได้อย่างรวดเร็วและมีประสิทธิภาพ และยังสามารถช่วยให้โปรแกรมสามารถจัดการข้อมูลจำนวนมากได้ โดยไม่ต้องเก็บไว้ในหน่วยความจำทั้งหมด

6.การดำเนินงาน

ออกแบบการทำงานของโปรแกรม

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

ส่วนหลักของโปรแกรม

import pygame # สำหรับเล่นไฟล์เสียง และ สร้างเฟรมแสดงอนิเมชั่น
import mysql.connector # ใช้ในการเชื่อมต่อกับฐานข้อมูล
from fuzzywuzzy import fuzz # ไลบรารีสำหรับวัดความคล้ายคลึงของข้อความ
from gtts import gTTS # สำหรับแปลงข้อความเป็นเสียง
import os # สำหรับจัดการไฟล์
import time # สำหรับหน่วงเวลา
import speech_recognition as sr # สำหรับแปลงเสียงเป็นข้อความ

# เชื่อมต่อกับฐานข้อมูล MySQL
mydb = mysql.connector.connect(
    host="localhost",
    user="root",
    password="",
    database="gtts"
)
mycursor = mydb.cursor()

# เริ่มต้น Pygame
pygame.init()
screen_width, screen_height = 800, 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Nongsri Assistant")
clock = pygame.time.Clock()

# โหลดภาพ PNG ขณะพูดและไม่พูด
idle_image = pygame.image.load("ani1.png").convert_alpha()  # ขณะไม่พูด
speaking_image = pygame.image.load("ani2.png").convert_alpha()  # ขณะพูด

current_image = idle_image  # เริ่มด้วยการแสดงผลขณะไม่พูด
center_x = (screen_width - current_image.get_width()) // 2
center_y = (screen_height - current_image.get_height()) // 2

# ฟังก์ชันพูดข้อความ
def speak(text):
    global current_image, speaking, mode  # อัปเดตสถานะการพูดและโหมด
    output_message = text
    filename = f"speech_{int(time.time())}.mp3"
    tts = gTTS(text=text, lang='th')
    tts.save(filename)
    pygame.mixer.music.load(filename)
    pygame.mixer.music.play()

    current_image = speaking_image  # เปลี่ยนเป็นภาพขณะพูด
    speaking = True  # ตั้งค่าสถานะการพูดเป็น True

    while speaking:  # รอจนกว่าจะเสียงเล่นเสร็จ
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                mycursor.close()
                mydb.close()
                os.remove(filename)  # ลบไฟล์เสียงเมื่อออกจากโปรแกรม
                exit()

        # แสดงอนิเมชันขณะพูด
        screen.fill((100, 100, 100))  # เติมพื้นหลังให้เป็นสีเทา
        display_image()  # แสดงภาพขณะพูด
        pygame.display.flip()
        clock.tick(10)

        if not pygame.mixer.music.get_busy():  # ตรวจสอบว่าเสียงหยุดเล่นหรือไม่
            speaking = False  # เปลี่ยนสถานะเมื่อเสียงหยุดเล่น
            pygame.mixer.music.stop()
            pygame.mixer.music.unload()
            time.sleep(1)
            os.remove(filename)  # ลบไฟล์เสียงหลังจากเล่นเสร็จ
            current_image = idle_image  # เปลี่ยนกลับไปแสดงภาพขณะไม่พูด
            mode = "None"  # เปลี่ยนกลับไปที่โหมดเริ่มต้น

# ฟังก์ชันรับเสียงจากไมโครโฟน
def listen_speech():
    recog = sr.Recognizer()
    with sr.Microphone() as source:
        print("กำลังฟัง...")
        speak("กำลังฟังค่ะ")
        audio = recog.listen(source)
        try:
            text = recog.recognize_google(audio, language='th')
            print(f"คุณพูดว่า: {text}")
            return text
        except sr.UnknownValueError:
            print("ไม่เข้าใจเสียง")
            return None
        except Exception as e:
            print(f"Error recognizing speech: {e}")
            return None

# ฟังก์ชันดึงข้อมูลจาก MySQL
def fetch_data():
    mycursor.execute("SELECT * FROM gtts_db")
    return mycursor.fetchall()

# ค้นหาข้อความที่คล้ายที่สุด
def find_best_match(user_input, data):
    best_score = 0
    best_match = None
    for row in data:
        db_text = row[1]
        score = fuzz.partial_ratio(user_input, db_text)
        if score > best_score:
            best_score = score
            best_match = row
    if best_score >= 80:
        return best_match
    return None

# ฟังก์ชันแสดงภาพ
def display_image():
    screen.blit(current_image, (center_x, center_y))

# โหลดฟอนต์ที่รองรับภาษาไทย
font_path = "THSarabunNew.ttf"
font_size = 36
font = pygame.font.Font(font_path, font_size)

# วาดปุ่ม
def draw_button(text, x, y, width, height, color):
    pygame.draw.rect(screen, color, (x, y, width, height))
    text_surface = font.render(text, True, (255, 255, 255))
    text_rect = text_surface.get_rect(center=(x + width // 2, y + height // 2))
    screen.blit(text_surface, text_rect)

# ตรวจสอบการคลิกปุ่ม
def button_clicked(mouse_pos, button_rect):
    return button_rect.collidepoint(mouse_pos)

# กำหนดสถานะเริ่มต้น
mode = "None"
input_text = ""
output_message = ""
speaking = False  # สถานะการพูด

# วนลูปหลัก
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            mouse_pos = pygame.mouse.get_pos()
            if button_clicked(mouse_pos, pygame.Rect(100, 550, 200, 50)):
                mode = "Chat"
                input_text = ""
                output_message = ""
            elif button_clicked(mouse_pos, pygame.Rect(500, 550, 200, 50)):
                mode = "Talk"
                output_message = ""
            elif button_clicked(mouse_pos, pygame.Rect(300, 550, 200, 50)):
                mode = "None"
                output_message = ""

        # เช็คการกดคีย์ในโหมด Chat
        if mode == "Chat" and event.type == pygame.KEYDOWN:
            if event.key == pygame.K_BACKSPACE:
                input_text = input_text[:-1]
            elif event.key == pygame.K_RETURN:
                if input_text.lower() == "ปิดโปรแกรม" or input_text.lower() == "exit":
                    running = False
                else:
                    data = fetch_data()
                    best_match = find_best_match(input_text, data)
                    if best_match:
                        message = best_match[2]
                        output_message = message
                        print(message)
                        speak(message)
                    else:
                        msg = "น้องศรีไม่พบข้อมูลค่ะ"
                        output_message = msg
                        print(msg)
                        speak(msg)
                    input_text = ""
            else:
                input_text += event.unicode

    # วาดพื้นหลังและตัวละคร
    screen.fill((255, 255, 255))
    display_image()

    # วาดปุ่ม
    draw_button("Chat", 100, 550, 200, 50, (0, 128, 0))
    draw_button("Talk", 500, 550, 200, 50, (0, 0, 128))
    draw_button("Back to None", 300, 550, 200, 50, (128, 0, 0))

    # แสดงโหมดปัจจุบัน
    mode_text = font.render(f"Mode: {mode}", True, (255, 255, 255))
    screen.blit(mode_text, mode_text.get_rect(center=(screen_width // 2, 50)))

    # แสดงกล่องพิมพ์ข้อความในโหมด Chat
    if mode == "Chat":
        pygame.draw.rect(screen, (0, 0, 0), (100, 500, 600, 40))
        input_surface = font.render(input_text, True, (255, 255, 255))
        screen.blit(input_surface, (105, 505))

    # ฟังเสียงในโหมด Talk
    if mode == "Talk" and not speaking:  # ตรวจสอบว่ากำลังพูดหรือไม่
        search_term = listen_speech()
        if search_term:
            if search_term.lower() == "ปิดโปรแกรม" or search_term.lower() == "exit":
                running = False
            elif search_term.lower() == "เปลี่ยนโหมด":  # เปลี่ยนโหมดกลับไปที่ Chat
                mode = "Chat"
                output_message = "กลับไปที่โหมดเริ่มต้นค่ะ"
                speak(output_message)
            else:
                data = fetch_data()
                best_match = find_best_match(search_term, data)
                if best_match:
                    message = best_match[2]
                    output_message = message
                    print(message)
                    speak(message)
                else:
                    msg = "น้องศรีไม่พบข้อมูลค่ะ"
                    output_message = msg
                    print(msg)
                    speak(msg)

    pygame.display.flip()
    clock.tick(10)

pygame.quit()
mycursor.close()
mydb.close()

วิธีใช้งาน

  1. กดเริ่มโปรแกรม
  2. เลือกโหมดการทำงาน ระหว่าง โหมดพิมพ์ข้อความ กับ โหมดการพูด
  3. ถ้าเลือกโหมดพิมพ์ข้อความ สามารถพิมพ์ข้อความที่ต้องการสอบถามได้
  4. ถ้าเลือกโหมดการพูด สามารถพูดข้อความที่ต้องการสอบถามได้
  5. โปรแกรมจะถอดข้อความเสียงที่ได้รับมาเป็นข้อความกลุ่มคำ
  6. โปรแกรมจะตรวจสอบคำในข้อความที่ถอดความมาว่าตรงกับคำใน Data Base หรือไม่
  7. หากตรงกับคำไหนใน Data Base โปรแกรมจะทำการพูดประโยคนั้นออกมา หากไม่มีคำไหนที่ตรงจะแสดงข้อความ”น้องศรีเองก็ไม่ทราบค่ะ” แล้วทำการรับคำพูดใหม่อีกครั้ง

โดยคำใน Data Base และ คำตอบที่ได้สามารถปรับเปลี่ยนได้ตามต้องการในโปรแกรม

การทดลอง

รันโปรแกรมและเลือก โหมด 1 (พิมพ์ข้อความ)

  • กรอกข้อความ เช่น “สวัสดี”
  • ตรวจสอบว่าโปรแกรมค้นหาได้ถูกต้องและแสดงข้อความที่ตอบกลับพร้อมแปลงเป็นเสียง

ผลการทดลองที่ได้

รันโปรแกรมใหม่และเลือก โหมด 2 (พูดข้อความ)

  • พูดข้อความ เช่น “สวัสดี”
  • ตรวจสอบว่าข้อความถูกต้อง และมีการตอบกลับทั้งในรูปแบบข้อความและเสียง

ผลการทดลองที่ได้

7.สรุปผลและข้อเสนอแนะ

1. สรุปผลการทดลอง

  1. โหมด 1: พิมพ์ข้อความ
    • เมื่อผู้ใช้กรอกข้อความ “สวัสดี” โปรแกรมสามารถค้นหาข้อมูลในฐานข้อมูลได้อย่างถูกต้อง
    • โปรแกรมแสดงข้อความที่ตอบกลับและแปลงเป็นเสียงเรียบร้อย
    • ผลการทดลองที่ได้: สามารถแสดงผลการตอบกลับของข้อมูลเป็นข้อความเป็นเสียงได้อย่างถูกต้อง
  2. โหมด 2: พูดข้อความ
    • เมื่อผู้ใช้พูดข้อความ “สวัสดี” โปรแกรมสามารถแปลงเสียงเป็นข้อความได้อย่างแม่นยำ
    • โปรแกรมแสดงผลข้อความที่ถูกต้องและตอบกลับด้วยเสียงเช่นเดียวกัน
    • ผลการทดลองที่ได้: สามารถแสดงผลการตอบกลับของข้อมูลเป็นข้อความเป็นเสียงได้อย่างถูกต้อง

2. ข้อเสนอแนะ

  • ปรับปรุงความแม่นยำของการจดจำเสียง: ควรทดสอบในสภาพแวดล้อมที่มีเสียงรบกวนต่ำเพื่อเพิ่มความแม่นยำในการจดจำเสียง
  • เพิ่มฟีเจอร์: สามารถพิจารณาเพิ่มฟีเจอร์การค้นหาข้อมูลแบบมีเงื่อนไข (เช่น ค้นหาตามประเภท) เพื่อเพิ่มประสิทธิภาพการค้นหา
  • ปรับปรุงการจัดการข้อผิดพลาด: เพิ่มการจัดการข้อผิดพลาดในกรณีที่ไม่พบข้อมูลที่ตรงกันในฐานข้อมูล เช่น การให้คำแนะนำหรือการค้นหาข้อมูลเพิ่มเติม
  • เพิ่มกราฟิคภาพเคลื่อนไหว (Animation): พิจารณาเพิ่มภาพเคลื่อนไหว 3D หรือกราฟิกที่ดึงดูดเพื่อทำให้ประสบการณ์ผู้ใช้มีความน่าสนใจและมีชีวิตชีวามากขึ้น

8.ข้อมูลอ้างอิง

[1] UItimate Python. (2021, มิถุนายน 9). ถอดเสียงเป็นข้อความ real-time ใน 10 บรรทัด! Python Speech to Text [วิดีโอ]. Youtube. https://youtu.be/9OC_XZj46OY?si=q-VtQzOh0Pxb1PXY

[2] EXPERT-PROGRAMMING-TUTOR.COM. (2566). การใช้งาน Xampp. สืบค้นเมื่อ 12 ตุลาคม 2567. จาก https://expert-programming-tutor.com/tutorial/java/21_Xampp.php

[3] Max O’Didily. (2023, มิถุนายน 27). How to Play Mp3 Files Using Python (Simple) [วิดีโอ]. Youtube. https://youtu.be/PSFM8-byvAE?si=hW8iLjKlmg_CDGQN

วิดิโอนำเสนอการทำงานของระบบตอบโต้ข้อความเสียงสำหรับงานทะเบียน “น้องศรี” (Assistant Bot)

You may also like...

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *