문제1. 직접 이미지를 웹스크롤링 해서 신경망을 만듭니다.

  1. 대상1 스크롤링

    구글에서 웹스크롤링 하는 전체 코드

    https://cafe.daum.net/oracleoracle/Sp62/555

    고라니 사진으로 스크롤링 합니다. 그중에 잘나온 100장을 선별해서 아래의 폴더에 둡니다.

    C:\gorani

    특정폴더에 있는 사진의 번호를 다시 1번부터 100번까지 다시 이름을 짓는 파이썬 코드를 수행합니다.

    import os
    import shutil  # 파일을 다른 폴더로 이동하기 위해 사용
    
    # 원본 폴더 경로
    source_folder = 'C:\\\\gorani'
    
    # 새로 이동할 폴더 경로
    destination_folder = 'C:\\\\gorani2'
    
    # 이동할 폴더가 존재하지 않으면 생성
    if not os.path.exists(destination_folder):
        os.makedirs(destination_folder)
    
    # 파일 목록 가져오기
    file_list = os.listdir(source_folder)
    
    # 파일 목록 정렬 (숫자로 된 파일명일 경우를 대비)
    file_list.sort()
    
    # 번호를 매겨 파일명 변경 및 이동
    for idx, filename in enumerate(file_list, 1):
        # 파일 확장자 확인
        ext = os.path.splitext(filename)[1]  # ex) .jpg, .png
        
        # 새 파일명 생성 (1.jpg, 2.jpg, ..., 100.jpg)
        new_filename = f"{idx}{ext}"
        
        # 기존 파일 경로와 새 파일 경로 설정
        src = os.path.join(source_folder, filename)
        dst = os.path.join(destination_folder, new_filename)
        
        # 파일 이동 및 이름 변경
        shutil.move(src, dst)
    
    print("파일 이동 및 이름 변경 완료!")
    
  2. 대상2 웹스크롤링

    다음 너구리 사진을 다운받기 위해 c 드라이브 밑에 data_image3 폴더를 만듭니다. 그리고 너구리 사진을 웹스크롤링합니다.

    그 다음 nuguri 와 nuguri2 라는 폴더는 만듭니다.

    잘나온 사진 100장을 nuguri 폴더에 선별합니다.

    그리고 nuguri2 에 101~200번까지 번호를 붙여 옮깁니다.

    import os
    import shutil  # 파일을 다른 폴더로 이동하기 위해 사용
    
    # 원본 폴더 경로
    source_folder = 'C:\\\\nuguri'
    
    # 새로 이동할 폴더 경로
    destination_folder = 'C:\\\\nuguri2'
    
    # 이동할 폴더가 존재하지 않으면 생성
    if not os.path.exists(destination_folder):
        os.makedirs(destination_folder)
    
    # 파일 목록 가져오기
    file_list = os.listdir(source_folder)
    
    # 파일 목록 정렬 (숫자로 된 파일명일 경우를 대비)
    file_list.sort()
    
    # 번호를 매겨 파일명 변경 및 이동 (101부터 200까지 부여)
    for idx, filename in enumerate(file_list, 101):
        # 파일 확장자 확인
        ext = os.path.splitext(filename)[1]  # ex) .jpg, .png
        
        # 새 파일명 생성 (101.jpg, 102.jpg, ..., 200.jpg)
        new_filename = f"{idx}{ext}"
        
        # 기존 파일 경로와 새 파일 경로 설정
        src = os.path.join(source_folder, filename)
        dst = os.path.join(destination_folder, new_filename)
        
        # 파일 이동 및 이름 변경
        shutil.move(src, dst)
    
    print("파일 이동 및 이름 변경 완료!")
    
  3. 이미지 압축파일 생성

    잘선별한 사진들을 하나의 폴더에 1 ~ 200번까지 다 모아놓으시오 !

    1 ~ 100 고라니 사진, 101 ~ 200 너구리 사진

    c 드라이브 밑에 image_all2 라는 폴더에 넣겠습니다.

    구글 코렙에 쉽게 이미지를 올리기 위해서 200장의 사진 전부를 image_all2.zip 으로 압축합니다.

    image_all2.zip 파일을 /content/drive/MyDrive/pretty3 폴더에 올립니다.

  4. 오늘의 마지막 문제. 여러분들이 만든 사진 분류 신경망 활용 인터페이스를 수행해서 결과를 캡쳐해서 올리세요 ~

    https://cafe.daum.net/oracleoracle/SpOP/316

    # ==============================================
    #   이미지 분류 애플리케이션: 골든 햄스터 OR 토끼
    # ==============================================
    # 이 애플리케이션은 사용자가 업로드한 이미지를 분류하여,
    # 골든 햄스터인지 토끼인지를 예측하는 기능을 제공합니다.
    # tkinter를 사용한 GUI로 구현되었습니다.
    # ==============================================
    
    import tkinter as tk
    from tkinter import filedialog
    from PIL import ImageTk, Image
    import numpy as np
    import cv2
    from tensorflow.keras.models import load_model
    import tensorflow as tf
    
    # ==============================================
    #           메인 애플리케이션 클래스 정의
    # ==============================================
    # ImageClassifierApp 클래스는 tkinter GUI를 관리하고,
    # 이미지 업로드, 분류 및 결과를 팝업창으로 보여주는 기능을 포함합니다.
    # ==============================================
    class ImageClassifierApp:
        def __init__(self, root):
            # GUI 창 기본 설정
            self.root = root
            self.root.title('Guess the Animal !')  # 창 제목
            self.root.geometry('800x600')  # 창 크기 설정
            self.root.configure(background='#F0F4C3')  # 배경색을 파스텔톤으로 설정
    
            # 사전 학습된 모델을 로드합니다.
            self.model = load_model('c:\\\\data\\\\model_hamster_rabbit.keras')  # 이미지 분류 모델 경로
    
            # 라벨과 이미지 영역 설정
            self.label = tk.Label(root, background='#F0F4C3', font=('Helvetica', 15, 'bold'))
            self.sign_image = tk.Label(root)
    
            # 헤딩(큰 제목) 설정
            self.heading = tk.Label(root, text="Guess!\\nGolden Hamster?\\nRabbit?", pady=20, 
                                    font=('Helvetica', 24, 'bold italic'))
            self.heading.configure(background='#F0F4C3', foreground='#5C6BC0')  # 텍스트 색상 변경
            self.heading.pack()
    
            # 이미지 업로드 버튼 설정
            self.upload_btn = tk.Button(root, text="Upload an Image", command=self.upload_image, padx=10, pady=5)
            self.upload_btn.configure(background='#FFCCBC', foreground='white', 
                                      font=('Helvetica', 12, 'bold italic'))  # 버튼 스타일
            self.upload_btn.pack(side=tk.BOTTOM, pady=50)
    
            # 이미지 및 라벨 배치
            self.sign_image.pack(side=tk.BOTTOM, expand=True)
            self.label.pack(side=tk.BOTTOM, expand=True)
    
        # ==============================================
        #           이미지 분류 함수
        # ==============================================
        # classify_image 함수는 업로드된 이미지를 모델에 넣어 분류를 수행합니다.
        # ==============================================
        def classify_image(self, file_path):
            try:
                # 이미지 파일 경로에서 이미지를 불러옵니다.
                img = cv2.imread(file_path)
                
                # 이미지를 32x32 크기로 변환
                resized_img = cv2.resize(img, (32, 32), interpolation=cv2.INTER_CUBIC)
                
                # 이미지 데이터를 0~1 범위로 정규화
                x = np.reshape(resized_img, (1, 32, 32, 3)) / 255.0
    
                # 모델을 사용해 예측을 수행
                result = self.model.predict(x)
                predicted_class = np.argmax(result)  # 가장 높은 확률을 가진 클래스를 선택
    
                # 클래스 이름 설정 (0: 골든 햄스터, 1: 토끼)
                class_names = {0: 'Golden Hamster', 1: 'Rabbit'}
                sign = class_names[predicted_class]
                
                # 라벨에 예측 결과를 표시
                self.label.configure(foreground='#3949AB', text=sign)  # 결과를 파스텔 블루로 표시
                self.show_result_popup(sign)  # 결과 팝업창 호출
    
            except Exception as e:
                print(f"Error in classification: {e}")
    
        # ==============================================
        #           결과 팝업창 함수
        # ==============================================
        # show_result_popup 함수는 분류 결과를 팝업창으로 보여줍니다.
        # ==============================================
        def show_result_popup(self, sign):
            # 팝업창 생성 및 설정
            result_popup = tk.Toplevel(self.root)
            result_popup.title("Epic Result!")  # 팝업창 제목
            result_popup.geometry("750x200")  # 팝업창 크기 설정
            result_popup.configure(background='#FFE082')  # 배경을 파스텔톤 노란색으로 설정
    
            # 극적인 결과 메시지를 팝업창에 표시
            message = f"The creature before your eyes is none other than...\\n\\n***{sign}!!!***\\n\\nUnbelievable, isn't it?"
            tk.Label(result_popup, text=message, font=('Helvetica', 16, 'bold italic'), 
                     background='#FFE082', foreground='#5D4037').pack(pady=40)  # 텍스트 스타일 설정
    
        # ==============================================
        #           분류 버튼 생성 함수
        # ==============================================
        # show_classify_button 함수는 이미지를 업로드한 후,
        # 'Classify Image' 버튼을 화면에 표시하는 기능을 합니다.
        # ==============================================
        def show_classify_button(self, file_path):
            classify_btn = tk.Button(self.root, text="Classify Image", command=lambda: self.classify_image(file_path), padx=10, pady=5)
            classify_btn.configure(background='#FFAB91', foreground='white', font=('Helvetica', 12, 'bold italic'))  # 버튼 스타일
            classify_btn.place(relx=0.79, rely=0.46)  # 버튼의 위치를 화면에 배치
    
        # ==============================================
        #           이미지 업로드 함수
        # ==============================================
        # upload_image 함수는 사용자가 이미지를 업로드할 수 있게 해주며,
        # 업로드된 이미지를 화면에 미리보기로 보여줍니다.
        # ==============================================
        def upload_image(self):
            try:
                file_path = filedialog.askopenfilename()  # 파일 선택 다이얼로그
                if file_path:
                    uploaded_img = Image.open(file_path)
                    
                    # 이미지 미리보기 크기 조정
                    uploaded_img.thumbnail((self.root.winfo_width()/2.25, self.root.winfo_height()/2.25))
                    
                    im = ImageTk.PhotoImage(uploaded_img)
                    self.sign_image.configure(image=im)  # 이미지 위젯에 표시
                    self.sign_image.image = im
                    self.label.configure(text='')  # 라벨 초기화
                    
                    # 분류 버튼 생성
                    self.show_classify_button(file_path)
    
            except Exception as e:
                print(f"Error uploading image: {e}")
    
    # ==============================================
    #           메인 루프 실행
    # ==============================================
    # tkinter의 메인 루프를 실행하여 GUI가 동작하도록 합니다.
    # ==============================================
    if __name__ == "__main__":
        root = tk.Tk()
        app = ImageClassifierApp(root)
        root.mainloop()