1. 실습에 필요한 2개의 파일을 다운로드 받습니다.

    https://cafe.daum.net/oracleoracle/Sl3Y/600

  2. 아주 기본적인 구현 코드이고 개선해야할 부분을 직접 개선해서 쓸 수 있도록 만든 코드

  3. 테스트 데이터의 정확도가 84% 인 모델을 내려 받습니다.

  4. 화면 구현에 필요한 함수 2가지에 대한 설명

    image.png

  5. 내가 직접 구현하는 화면이라는 제목으로 새 노트를 엽니다.

  6. 함수 생성 코딩

    1. upload_sound 함수

      #1. 필요한 패키지를 전부 임폴트 합니다.
      import tkinter as tk
      from tkinter import filedialog
      from tkinter import *
      from PIL import ImageTk, Image
      import numpy  as  np
      from keras.models import load_model
      import cv2
      import numpy
      import glob
      import librosa
      
      #2. upload_image 함수 생성
      def upload_image():
          try:
              file_path=filedialog.askopenfilename()  # 윈도우 탐색기를 엽니다.
              print(file_path)
              # show_classify_button(file_path)  # 음성 분류를 하는 함수에 음성 파일을 입력
          except:
              pass  # try 와 except 사이에 문제가 생겨도 그냥 무시해라!
      
      upload_image()
      #3. upload_image 의 file_path 를 전역변수로 생성합니다. 
      
                                      # C:/data/cats_dogs/cat_1.wav
      
      #1. 필요한 패키지를 전부 임폴트 합니다. 
      import tkinter as tk
      from tkinter import filedialog
      from tkinter import *
      from PIL import ImageTk, Image
      import numpy  as  np
      from keras.models import load_model
      import cv2
      import numpy 
      import glob
      import librosa
      
      #2. upload_sound 함수 생성 
      
      def upload_sound():
          try:
              global file_path
              file_path=filedialog.askopenfilename()  # 윈도우 탐색기를 엽니다. 
          except:
              pass  # try 와 except 사이에 문제가 생겨도 그냥 무시해라!
          
      upload_sound()    
      print(file_path)  # 전역 변수이므로 함수 밖에서 사용할 수 있습니다. 
                          # 또는 다른 함수에서도 사용할 수 있습니다. 
      

    #3. sound_classify 함수의 역활은 음성---> 모델 ---> 결과를 출력하는 것입니다. 그런데 편하게 sound_classify 함수를 만들기 위해서 다음의 함수를 미리 만듭니다.

             model = load_model('d:\\\\\\\\sound2\\\\\\\\model_keras.h5')
    
            모델을 불러오는 코드는 미리 준비합니다.
               ↑
     음성---> 모델 ---> 결과
          ↑
    음성에서 특징을 뽑아는 함수
    
    

    #4. 음성에 특징을 뽑아내는 함수 생성

    # 4. 음성에 특징을 뽑아내는 함수 생성 
    # 특징은 소리의 주파수 스팩트럼 데이터 40개 + zero_crossing_rate 1개 
    
    def extract_features(audio_samples, sample_rate): # 음성의 특징을 추출하는 함수 
        extracted_features = np.empty((0, 41, )) # (1,41) 은 아니고 그냥 41개의 값을 받을 비어있는 리스트를 할당하겠다는 뜻
        if not isinstance(audio_samples, list):# 리스트가 아니라면 
            audio_samples = [audio_samples] #  리스트화 해라        
    
        for sample in audio_samples:  # 진폭 데이터 리스트를 하나씩 가져옵니다. 
            zero_cross_feat = librosa.feature.zero_crossing_rate(sample).mean() # 음성 신호 파형이 중심축(0) 을 통과하는 횟수
            mfccs = librosa.feature.mfcc(y=sample, sr=sample_rate, n_mfcc=40) # <https://youdaeng-com.tistory.com/5>
            mfccsscaled = np.mean(mfccs.T,axis=0)  # 각 주파수별 평균값을 구합니다. 
            mfccsscaled = np.append(mfccsscaled, zero_cross_feat)  
            mfccsscaled = mfccsscaled.reshape(1, 41, )  # 41개의 값을 학습 데이터로 구성합니다. [[293,291,293,...392]]
            extracted_features = np.vstack((extracted_features, mfccsscaled)) #[[293,291,293,...392]]
            # 41개의 변수를 가진 훈련데이터 419개를 vstack으로 쌓아 만듬. 
        return extracted_features
    
    #5. file_path 에 들어있는 음성 파일을 숫자로 변환한다.
    
    upload_sound()   # 음성을 선택해서 파일위치와 이름을 file_path 에 담는 함수를 실행합니다.
    print(file_path)   # C:/Users/YYS/Downloads/archive/cats_dogs/train/dog/dog_barking_11.wav
    x_test = librosa.load(file_path)[0]   # 해당 음성을 숫자로 변환해서 x_test 에 담습니다.
    print(x_test)
    
    #6. file_path 에 들어있는 음성 파일의 sample rate (주파수 대역) 정보를 추출합니다.
    
    upload_sound() 
    wave_rate = librosa.load(file_path)[1] 
    print(wave_rate) 
                                                    # 22050
    
    #7. 위에서 얻은 두개의 값을 extract_features 함수에 넣어서 모델에 넣을 41개의 데이터를 출력하시오!
    
    upload_sound()              # 소리 데이터 선택하게 하는 윈도우 탐색기 열리게 하고 
    x_test = librosa.load(file_path)[0]    # 그 소리의 진폭값들을 x_test 에 담아내고 
    
    wave_rate = librosa.load(file_path)[1]  # 그 소리의 대표 주파수를 wave_rate 에 담아내고 
    x_test_features = extract_features( x_test, wave_rate ) # 소리의 특징을 추출 합니다. 
    print( x_test_features )
    

    #8. 음성을 모델에 넣고 결과를 출력하는 classify 라는 함수를 생성하시오 !

    음성---> 모델 ---> 결과 ↑ 음성에서 특징을 뽑아는 함수

    model = load_model('c:\\\\data\\\\model_keras.keras')
    print(model)
    
    def  classify():
        upload_sound()                                             # 음성을 선택해서 
        x_test = librosa.load(file_path)[0]                     # 숫자로 변환하고  
        wave_rate = librosa.load(file_path)[1]               # 주파수 대역을 추출해서 
        x_test_features = extract_features( x_test, wave_rate )  # 41개의 학습 데이터를 만든후에 
        pred = model.predict( x_test_features.reshape( 1, 41, ) )   # 모델에 넣고 예측해라 
        print(pred) 
    
    classify()
    
    # 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 210ms/step
    # [[9.9998152e-01 1.8478753e-05]]
    
    #9. 위에서 출력되는 확률 백터 [[0.11749879 0.8825012 ]] 를 cat 또는 dog 로 출력되게 하시오!
    
    #  음성---> 모델 ---> 결과(cat 또는 dog)
    
    def  classify():
        upload_sound()                                            # 음성을 선택해서 
        x_test = librosa.load(file_path)[0]                     # 숫자로 변환하고  
        wave_rate = librosa.load(file_path)[1]               # 주파수 대역을 추출해서 
        x_test_features = extract_features( x_test, wave_rate )  # 41개의 학습 데이터를 만든후에 
        pred = model.predict( x_test_features.reshape( 1, 41, ) )   # 모델에 넣고 예측해라 
        a = np.argmax(pred)                                               # 가장 큰 원소의 인덱스 번호를 추출합니다.
        if  a == 0:                                                           
            print('cat')
        else:
            print('dog')
    
    classify()
    
    # 1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 18ms/step
    # dog
    
    #10. 사용자 인터페이스 배경 판을 생성합니다.
    
    top=tk.Tk()                                # tkinter(사용자 인터페이스 전문 모듈) 를 객체화 시키겠다.
    top.geometry('800x600')                   # 화면 크기를 결정합니다.
    top.title('cat and dog sound Classification')  # 맨위에 제목을 붙입니다.
    top.configure(background='coral')  # 판의 바탕 색깔, 구글에서 #CDCDCD 검색
    
    # top.mainloop()
    
    #11. 사운드를 업로드 하는 버튼을 만듭니다.
    
    upload=Button(top,text="Upload an sound",command=upload_sound,padx=10,pady=5)
    upload.configure(background='crimson', foreground='white',font=('arial',10,'bold'))  #버튼 색깔
    upload.pack(side=BOTTOM, pady=50)  # 버튼의 위치 , TOP, BOTTOM, LEFT, RIGHT 를 쓸 수 있음
    upload.place(relx=0.2, rely=0.8)  # <--- 이 부분 추가
    
    # top.mainloop()  # 이 코드는 무조건 맨아래에 하나만 있으면 됩니다.
    
    #12. 분류하는 버튼을 판에 올립니다.
    
    #분류 버튼 구현
    
    classify_bt=Button(top,text="classify an sound",command= classify ,padx=10,pady=5)
    classify_bt.configure(background='crimson', foreground='white',font=('arial',10,'bold'))  #버튼 색깔
    classify_bt.pack(side=TOP, pady=50)  # 버튼의 위치 , TOP, BOTTOM, LEFT, RIGHT 를 쓸 수 있음
    classify_bt.place(relx=0.6, rely=0.8)  # <--- 이 부분 추가
    
    # top.mainloop()  # 이 코드는 무조건 맨아래에 하나만 있으면 됩니다.
    # ※ 위의 작업을 수행할때 classify 함수 안에 upload_image 함수 실행코드를 주석으로 막습니다.
    
    #13.  cat 과 dog 가 화면 판에 출력되게 합니다. 
    
    # 1. classify 함수에서 cat 과 dog 를 print 하지 말고 변수에 담게 수정합니다. 
    
    def  classify():
        #upload_sound()                                         # 음성을 선택해서 
        x_test = librosa.load(file_path)[0]                     # 숫자로 변환하고  
        wave_rate = librosa.load(file_path)[1]               # 주파수 대역을 추출해서 
        x_test_features = extract_features( x_test, wave_rate )  # 41개의 학습 데이터를 만든후에 
        pred = model.predict( x_test_features.reshape( 1, 41, ) )   # 모델에 넣고 예측해라 
        a = np.argmax(pred)                                               # 가장 큰 원소의 인덱스 번호를 추출합니다.
        if  a == 0:                                                           
            sign='cat'
        else:
            sign='dog'
    
        label.configure(foreground='#011638', text= sign)  # 판에 자리잡은 영역에 글씨를 붙입니다. 
    
    # 2. 아래쪽에서 화면에 글씨를 출력합니다.
    
    # 화면에 출력할 결과 구현 
    label = Label( top, background='coral' , font =('arial', 48, 'bold') )
    label.pack(side=BOTTOM,expand=True)
    
    top.mainloop()