---
# System prepended metadata

title: 自製判斷好看醜陋演算法 並利用pygame做出視窗
tags: [tensorflow.keras]

---

# 自製判斷好看醜陋演算法 並利用pygame做出視窗
###### tags: `tensorflow.keras`
```python=
from webdriver_manager.chrome import ChromeDriverManager
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
from bs4 import BeautifulSoup
import pandas
import os
import face_recognition
import cv2
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import requests
```
```python=
def search_picture(keyword):
    options = Options()
    options.add_argument("--disable-notifications")#進用通知
    driver = webdriver.Chrome(ChromeDriverManager().install())#打開chrome瀏覽器

    driver.get("https://www.google.com.tw/?hl=zh_TW")
    q = driver.find_element(By.NAME,'q')
    q.send_keys(keyword)
    q.send_keys(Keys.ENTER)
    
    soup = BeautifulSoup(driver.page_source)
    a = soup.find_all("div",  "hdtb-mitem")
    c = a[1].find('a').get('href')
    c = c.replace("_"," ")
    driver.get("https://www.google.com"+c)
    
    
    for x in range(1,20):#將網頁往下滑20次 載入更多數據
        height = driver.execute_script("return document.documentElement.scrollHeight")
        driver.execute_script("window.scrollTo(0, " + str(height) + ");")
        time.sleep(0.1)
    soup = BeautifulSoup(driver.page_source)
    results = soup.find_all('img')
    src = [result.get("src") for result in results]
    return src

def download_picture(destination,good_or_bad_picture):
    os.chdir(destination)
    for i,url in enumerate(srcc):
        if 'https:' in url: 
            response = requests.get(url)
            print(i)
            with open( good_or_bad_picture+ str(i) + ".jpg", "wb") as file:  # 開啟資料夾及命名圖片檔
                file.write(response.content)
def have_head_in_file(destination):
    for i in os.listdir(destination):
        path = destination+i
        img = cv2.imread(path)

        face_loc = face_recognition.face_locations(img)
        if face_loc == []:
            os.remove(path)
def clear_the_file(destination):
    for i in os.listdir(destination):
        os.remove(destination+i)
```
```python=
clear_the_file("C:/Users/bt/train/beautifulpeople/")
clear_the_file("C:/Users/bt/train/uglypeople/")
```
## 抓取好看的訓練集
```python=
a = search_picture("漂亮的人")
b = search_picture("明星")
c = search_picture("模特兒")
d = search_picture("handsome")
e = search_picture("beauty")
```
```python=
search = [a,b,c,d,e]
```
```python=
srcc = []
for i in range(len(search)):
    for j in range(len(search[i])):
        if search[i][j] != None and 'https:' in search[i][j] :
            srcc.append(search[i][j])
```
```python=
download_picture("C:/Users/bt/train/beautifulpeople/",'good')
```
```python=
have_head_in_file('C:/Users/bt/train/beautifulpeople/')
```
## 抓取醜陋的訓練集
```python=
clear_the_file("C:/Users/bt/train/uglypeople/")
a = search_picture("醜人")
b = search_picture("醜男")
c = search_picture("醜女")
d = search_picture("ugly")
e = search_picture("ugly people")
f = search_picture("hideous")
```
```python=
search = [a,b,c,d,e,f]
```
```python=
srcc = []
for i in range(len(search)):
    for j in range(len(search[i])):
        if search[i][j] != None and 'https:' in search[i][j] :
            srcc.append(search[i][j])
```
```python=
download_picture("C:/Users/bt/train/uglypeople/",'bad')
```
```python=
have_head_in_file('C:/Users/bt/train/uglypeople/')
```
## 分訓練集集測試集
```python=
import numpy as np
import os
import cv2
import tqdm
```
```python=
os.chdir('C:/Users/bt')
class_names = ['beautifulpeople','uglypeople']
class_names_label = {class_name:i for i, class_name in enumerate(class_names)}
nb_classes = len(class_names)
IMAGE_SIZE = (64,64)
```
```python=
def load_data():
    datasets = ['train','test']#資料夾
    output = []
    
    
    for dataset in datasets:
        
        images = []
        labels = []
        
        print("Loading {}".format(dataset))
        
        
        for folder in os.listdir(dataset):
            label = class_names_label[folder]
            
            
            for file in os.listdir(os.path.join(dataset, folder)):
                
               
                img_path = os.path.join(os.path.join(dataset, folder), file)
                
                
                image = cv2.imread(img_path)
                
                image = cv2.resize(image, IMAGE_SIZE) 
                
               
                images.append(image)
                labels.append(label)
                
        images = np.array(images, dtype = 'float32')
        labels = np.array(labels, dtype = 'int32')   
        
        output.append((images, labels))

    return output
```
```python=
(train_images, train_labels),(test_images , test_labels) = load_data()
```
```python=
train_images = train_images/255
```
## 建模
```python=
from keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from keras.layers import Dropout, Flatten
from keras.layers.core import Dense

input_shape = (64, 64, 3) #圖片格式
model = Sequential([
    Conv2D(64, (3, 3), input_shape=input_shape, padding='same',#64神經元數目 3,3掃描器大小 padding:掃出來要跟原本一樣
           activation='relu', strides=2),#激活函數, strides:每隔多少步掃描一次
    MaxPooling2D(pool_size=(2, 2), strides=2),#池化曾:做特徵壓縮 (壓縮大小2*2,每隔多少步壓縮一次)
    Dropout(0.2),#防止過度配適 把20%丟掉
    
    #兩次卷基層 池畫曾
    Conv2D(128, (3, 3), input_shape=input_shape, padding='same',
           activation='relu', strides=2),
    MaxPooling2D(pool_size=(2, 2), strides=2),
    Dropout(0.2),
    Flatten(),#把圖片攤平
    Dropout(0.5),
    
    Dense(2, activation='softmax') #輸出層，只有2個,分類用softmax
])
model.compile(optimizer = 'adam', #最佳化演算法 adam:動態 SGD(lr=0.1)
              loss = 'sparse_categorical_crossentropy',#損失函數 :混淆矩陣
              metrics=['accuracy'])#想看甚麼輸出 : 準確度
```
```python=
history = model.fit(train_images,train_labels,validation_split=0.2,batch_size=100,epochs=100,verbose=2)
```
```python=
from matplotlib import pyplot as plt
plt.title("train_accuracy")
plt.ylabel ('accuracy')
plt.xlabel('epoch')
plt.plot(history.history["accuracy"])
```
![](https://i.imgur.com/M0LC1jo.png)

## 判斷
```python=
predictions = model.predict(test_images)
pred_labels = np.argmax(predictions, axis = 1)
```
```python=
from sklearn.metrics import confusion_matrix

CM =  confusion_matrix( test_labels,pred_labels)#混淆矩陣 因為適分類的預測

def accuracy(confusion_matrix):
    diagonal_sum = confusion_matrix.trace()#預測正確的
    sum_of_all_elements = confusion_matrix.sum()#總預測數
    return diagonal_sum/sum_of_all_elements
print(accuracy(CM))#預測效果
```
```
0.8865979381443299
```
```python=
from matplotlib import pyplot as plt
import seaborn as sn
ax =plt.axes()
sn.heatmap(CM,annot = True,#裡面數字是否呈現
         annot_kws={"size":20},#裡面的數字
        xticklabels = class_names,
        yticklabels = class_names, ax =ax,
         )
ax.set_title("confusion_matrix")
plt.show()
```
![](https://i.imgur.com/phtkQ8j.png)
將模型存下來方便其他地使用
```python=
model.save('model_ok.h5')
```
![](https://i.imgur.com/lkfLtCi.png)
# 製作視窗判斷好看否
利用pygame將視窗做出
```python=
import pygame
import random
import os
import re
from keras.models import load_model
import os
import cv2
import numpy as np
import time


model = load_model('model_ok.h5')
pygame.init()#遊戲初始化

WIDTH = 550
HIGHT = 600

screen = pygame.display.set_mode((WIDTH,HIGHT))#視窗大小 寬度500高度600
pygame.display.set_caption("MaJuGoDioaLaAhMaow")#更改視窗名字

clock = pygame.time.Clock()#可管理時間 

input_adress = "beautyorugly"

things_in_file = os.listdir(input_adress)
background_img = pygame.image.load(os.path.join("beautyorugly",'白文章.jpg')).convert() #os.path 是檔案位置  一堆圖為資料夾名稱, 套套2.png為照片名稱 convert為將圖轉為pygame比較好讀的格式
background_img = pygame.transform.scale(background_img , (550, 600)) 

bg_color = (255,102,178)
font_name = pygame.font.match_font('DFKai-SB')


    
def draw_text(surf, text, size ,x,y,z,a,b):#畫東西的函示 (哪個平面, 內容,大小,x,y)
    font = pygame.font.Font(font_name, size)
    text_surface = font.render(text, True, (z,a,b))
    text_rect = text_surface.get_rect()
    text_rect.centerx = x
    text_rect.top = y
    surf.blit(text_surface, text_rect)
def draw_init():
    screen.blit(background_img ,(0,0))
    draw_text(screen, "MaJuGoDioaLaAhMaow",55,WIDTH/2,HIGHT/3,255,0,0)
    draw_text(screen ,"一次最多只能判斷25張圖片",25,WIDTH/2,HIGHT/2,255,204,255)
    draw_text(screen, "連按2次空白鍵開始執行...",25,WIDTH/2,HIGHT/2+60,255,204,255)
    pygame.display.update()
    watting = True
    while watting:
        clock.tick(FPS)#1秒鐘之內最多只能執行 FPS 次
        for event in pygame.event.get():#全部事件列出來
            if event.type == pygame.QUIT:#如果按x讓視窗關閉
                pygame.quit()
                return True
            elif event.type == pygame.KEYUP:#按下鍵盤建 (KEYUP 是按下再拿起案件才開始)
                watting = False
                return False

def scan_files_picture():
    c = []
    
    for i in range(len(things_in_file)-1):
        img_path = os.path.join("beautyorugly",things_in_file[i])       
        image = cv2.imread(img_path)            
        image = cv2.resize(image,(64,64) )
        a = np.array(image,dtype = 'float32')
        c.append(a)
    c = np.array(c)
    return c
def predictions_labels():
    predictions = model.predict(scan_files_picture())
    pred_labels = np.argmax(predictions, axis = 1)   
    return pred_labels
    
FPS = 60

show_init = True
running = True
while running:
    if show_init:
        
        draw_init()
        show_init = False
    
    clock.tick(FPS)#1秒鐘之內最多只能執行 FPS 次
    for event in pygame.event.get():#全部事件列出來
        if event.type == pygame.QUIT:#如果按x讓視窗關閉
            running = False
        elif event.type == pygame.KEYUP:      
            if event.key == pygame.K_SPACE:
                screen.fill(bg_color)
                pygame.display.update()
                draw_text(screen,"你要判斷的圖片有:",55,WIDTH/2,10,0,0,0)
                if len(things_in_file) < 10:
                    if len(things_in_file) % 2== 0:
                        for i in range(int(len(things_in_file))-1):
                       
                            draw_text(screen,things_in_file[i],40,WIDTH/2, 40*i+40+HIGHT/len(things_in_file),0,0,0)
                        pygame.display.update()
                    if len(things_in_file) % 2!= 0:
                        for i in range(int(len(things_in_file))-1):
                       
                            draw_text(screen,things_in_file[i],40,WIDTH/2, 40*i+40+HIGHT/len(things_in_file),0,0,0)
                        pygame.display.update()
                    draw_text(screen,"連按2次 '1' 繼續判斷",40,WIDTH/2, 40*(i+1)+40+HIGHT/len(things_in_file),255,204,250)
                    pygame.display.update()
                if len(things_in_file) >= 10:
                    if len(things_in_file)%2 == 0 :
                        for i in range(int(len(things_in_file)/2)):
                            draw_text(screen,things_in_file[i],30,90, 40*i+40+HIGHT/len(things_in_file),0,0,0)
                        for j in range(int(len(things_in_file)/2)-1):
                            draw_text(screen,things_in_file[i+j+1],30,WIDTH/2+90, 40*(j)+40+HIGHT/len(things_in_file),0,0,0)
                    if len(things_in_file)%2 != 0 :
                        for i in range(int(len(things_in_file)/2)):
                            draw_text(screen,things_in_file[i],30,90, 40*i+40+HIGHT/len(things_in_file),0,0,0)
                        for j in range(int(len(things_in_file)/2)):
                            draw_text(screen,things_in_file[i+j+1],30,WIDTH/2+90, 40*(j)+40+HIGHT/len(things_in_file),0,0,0)
                        draw_text(screen,things_in_file[i+j+1],30,WIDTH/2+90, 40*(j+1)+40+HIGHT/len(things_in_file),0,0,0)
                    pygame.display.update()
                    draw_text(screen,"連按2次 '1' 繼續判斷",30,WIDTH/2, 40*(j+2)+40+HIGHT/len(things_in_file),255,204,250)
                    pygame.display.update()
            if event.key == pygame.K_1:
                pre_labels = predictions_labels()
                for i in range(int(len(things_in_file))-1):
                    back_img = pygame.image.load(os.path.join("beautyorugly",things_in_file[i])).convert() #os.path 是檔案位置  一堆圖為資料夾名稱, 套套2.png為照片名稱 convert為將圖轉為pygame比較好讀的格式
                    back_img = pygame.transform.scale(back_img , (550, 600)) 
                    screen.blit(back_img,(0,0))
                    pygame.display.update()
                    time.sleep(0.5)
                    if pre_labels [i] ==0:
                        draw_text(screen,"這張圖...",50,WIDTH/2, HIGHT/2,255,128,0)
                        pygame.display.update()
                        time.sleep(1.5)
                        draw_text(screen,"很好看喔",50,WIDTH/2, HIGHT/2+50,255,128,0)
                        pygame.display.update()
                    if pre_labels [i] ==1:
                        draw_text(screen,"這張圖...",50,WIDTH/2,HIGHT/2,255,128,0)
                        pygame.display.update()
                        time.sleep(1.5)
                        draw_text(screen,"好醜喔",50,WIDTH/2,HIGHT/2+50,255,128,0)
                        pygame.display.update()
                    time.sleep(1.5)
                draw_init()
                    
                        
                    
                
            
            
    
            
            
            
            
            
pygame.QUIT
```
利用auto-py-to-exe將檔案打包後，將model_ok.h5以及資料夾"beautyorugly"(可以將想要判斷的圖片放進此資料夾)放入與exe同一個資料夾
![](https://i.imgur.com/zGwlgnl.png)
![](https://i.imgur.com/ySoxOJm.png)
![](https://i.imgur.com/EnmslgW.png)
自動往下繼續判斷
![](https://i.imgur.com/9oSFHWM.png)
跑完後跳回
![](https://i.imgur.com/zGwlgnl.png)
