目录

1.首先
2. 应用概览
三、开发流程
4. 图像采集
5. 图像准备
6.图像填充
7.模型训练
8. 应用创建
9. 我试图判断
10.改进

1.首先

在这篇文章中,没有编程经验的我参加了Aidemy的“AI应用开发课程”,讲解了作为最终产品创建的“国籍确定应用”的制作流程。

2. 应用概览

当你上传一张人脸照片时,这个人的国籍是确定的(仅限日本、美国、意大利和印度 lol)

三、开发流程

数据收集→数据处理→模型学习→应用程序创建

4. 图像采集

使用 irawler 收集图像。

t_image s。 py
from icrawler.builtin import BingImageCrawler

SearchName = ["日本人 男性","アメリカ人 男性","イタリア人 男性","インド人 男性"]

for name in SearchName:
	#1---任意のクローラを指定
	crawler = BingImageCrawler(storage={"root_dir": name})
	#2---検索内容の指定
	crawler.crawl(keyword=name, max_num=100)

顔写真から国籍を判定するアプリ

5. 图像准备

从照片中识别并剪切面部部分。使用 OpenCV 的级联分类器

tri m_image s。 py
import cv2
import glob #ファイル読み込みで使用
import os #フォルダ作成で使用


cascade_path= os.path.join(
    cv2.data.haarcascades, "haarcascade_frontalface_alt.xml"
)
face_cascade = cv2.CascadeClassifier(cascade_path)

for fold_path in glob.glob('./Original/*'):
    imgs = glob.glob(fold_path + '/*.jpg')
    # 顔切り取り後の、画像保存先のフォルダ名
    save_path = fold_path.replace('Original','FaceEdited')
    
    # 保存先のフォルダがなかったら、フォルダ作成
    if not os.path.exists(save_path):
        os.mkdir(save_path)

    # 顔だけ切り取り→保存
    # 画像ごとに処理
    for i, img_path in enumerate(imgs,1):
    
        img = cv2.imread(img_path)


        img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        
        print('{}:read_done'.format(i))
        #カスケード分類器の特徴量を取得する
        cascade = cv2.CascadeClassifier(cascade_path)

        facerect = cascade.detectMultiScale(img_gray, scaleFactor=1.1, minNeighbors=2, minSize=(30, 30))

        #print(facerect)
        color = (255, 255, 255) #白
        print("{}_facerect:".format(i),facerect)
        # 検出した場合
        if len(facerect) > 0 :
            

            #検出した顔を囲む矩形の作成
            for rect in facerect:
                y=rect[0]
                x=rect[1]
                h=rect[2]
                print('rect:',rect)
                print('plot:',tuple(rect[0:2]),tuple(rect[0:2]+rect[2:4]))
                trim = img[y:y+h,x:x+h]
                print(trim.shape[0],trim.shape[1])
                print(trim.shape[1]!=0 )
                print(trim.shape[0]!= 0 and trim.shape[1]!= 0)
                if trim.shape[0]!= 0 and trim.shape[1]!= 0 :
                
                    
                    #認識結果の保存
                    file_name = "/{}.jpg".format(i)
                    print(file_name)
                    cv2.imwrite(save_path+file_name, trim)
                else:
                    print(trim.shape[0],trim.shape[1])
                   
                    
        else:
            
            print("{}:skip".format(i))
            

顔写真から国籍を判定するアプリ

不太顺利

6.图像填充

执行“水平反演”、“阈值”、“模糊”、“马赛克处理”、“缩小”处理并膨胀数据数量。

认识 g_image 。 py
import os
import glob
import numpy as np
import matplotlib.pyplot as plt
import cv2

# 左右反転の水増しのみ使用
def scratch_image(img, flip=True, thr=True, filt=True, resize=False, erode=False):
    # 水増しの手法を配列にまとめる
    methods = [flip, thr, filt, resize, erode]

    # flip は画像の左右反転
    # thr  は閾値処理
    # filt はぼかし
    # resizeはモザイク
    # erode は縮小
    #     をするorしないを指定している
    # 
    # imgの型はOpenCVのcv2.read()によって読み込まれた画像データの型
    # 
    # 水増しした画像データを配列にまとめて返す

    # 画像のサイズを習得、ぼかしに使うフィルターの作成
    img_size = img.shape
    filter1 = np.ones((3, 3))

    # オリジナルの画像データを配列に格納
    images = [img]

    # 手法に用いる関数
    scratch = np.array([
        #画像の左右反転のlambda関数を書いてください
        lambda x: cv2.flip(x, 1),
        #閾値処理のlambda関数を書いてください
        lambda x: cv2.threshold(x, 150, 255, cv2.THRESH_TOZERO)[1],  
        #ぼかしのlambda関数を書いてください
        lambda x: cv2.GaussianBlur(x, (5, 5), 0),
        #モザイク処理のlambda関数を書いてください
        lambda x: cv2.resize(cv2.resize(x,(img_size[1]//5, img_size[0]//5)), (img_size[1], img_size[0])),
        #縮小するlambda関数を書いてください
        lambda x: cv2.erode(x, filter1)  
    ])

    # 関数と画像を引数に、加工した画像を元と合わせて水増しする関数
    doubling_images = lambda f, imag: (imag + [f(i) for i in imag])

    # doubling_imagesを用いてmethodsがTrueの関数で水増ししてください

    for func in scratch[methods]:
        images = doubling_images(func,  images)

    return images


for fold_path in glob.glob('./FaceEdited/*'):
    imgs = glob.glob(fold_path + '/*.jpg')
    print(imgs)
    # 顔切り取り後の、画像保存先のフォルダ名
    save_path = fold_path.replace('FaceEdited','Aug')
    
    # 保存先のフォルダがなかったら、フォルダ作成
    if not os.path.exists(save_path):
        print(save_path)
        os.mkdir(save_path)

    # 画像ごとに処理
    for i, img_path in enumerate(imgs,1):

        # 画像ファイル名を取得
        base_name = os.path.basename(img_path)
        print(base_name)
        # 画像ファイル名nameと拡張子extを取得
        name,ext = os.path.splitext(base_name)
        print(name + ext)

        # 画像ファイルを読み込む
        img = cv2.imread(img_path, 1)
        scratch_images = scratch_image(img)



        for j, im in enumerate(scratch_images):
             #認識結果の保存
            file_name = "/{:0=2}_{:0=2}.jpg".format(i,j)
            print(file_name)
            cv2.imwrite(save_path+file_name, im)

顔写真から国籍を判定するアプリ

7.模型训练

现在数据已经准备好,是时候训练模型了。图像被调整为 64×64 并输入。该模型使用vgg16的迁移学习。

还有l。 py
import os
import glob
import cv2
import numpy as np
import matplotlib.pyplot as plt
from keras.utils.np_utils import to_categorical
from keras.layers import Dense, Dropout, Flatten, Input
from keras.applications.vgg16 import VGG16
from keras.models import Model, Sequential
from keras import optimizers


# 各国配列格納
natio_list = ["ind_male", "ita_male", "jap_male", "usa_male"]
print(natio_list)
print(len(natio_list))


# 各国の画像ファイルパスを配列で取得する関数
def get_path_natio(natio):
  path_natio = glob.glob('./Aug/' + natio + '/*')
  return path_natio

#リサイズ時のサイス指定
img_size = 64


# 各国の画像データndarray配列を取得する関数
def get_img_natio(natio):
  path_natio = get_path_natio(natio)

  img_natio = []
  for i in range(len(path_natio)):
    # 画像の読み取り、64にリサイズ
    img = cv2.imread(path_natio[i])
    img = cv2.resize(img, (img_size, img_size))
    # img_sakuraiに画像データのndarray配列を追加していく
    img_natio.append(img)
  return img_natio 



# 各国の画像データを合わせる
X = []
y = []
for i in range(len(natio_list)):
    print(natio_list[i] + ":" + str(len(get_img_natio(natio_list[i]))))
    X += get_img_natio(natio_list[i])
    y += [i]*len(get_img_natio(natio_list[i]))
X = np.array(X)
y = np.array(y)

print(X.shape)

# ランダムに並び替え
rand_index = np.random.permutation(np.arange(len(X)))

# 上記のランダムな順番に並び替え
X = X[rand_index]
y = y[rand_index]

# データの分割(トレインデータが8割)
X_train = X[:int(len(X)*0.8)]
y_train = y[:int(len(y)*0.8)]
X_test = X[int(len(X)*0.8):]
y_test = y[int(len(y)*0.8):]

# one-hotベクトルに変換
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

# モデル
input_tensor = Input(shape=(64, 64, 3))
vgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)

top_model = Sequential()
top_model.add(Flatten(input_shape=vgg16.output_shape[1:]))
top_model.add(Dense(256, activation='relu'))
top_model.add(Dropout(0.5))
top_model.add(Dense(len(natio_list), activation='softmax'))

model = Model(inputs=vgg16.input, outputs=top_model(vgg16.output))

# vgg16の重みの固定
for layer in model.layers[:15]:
    layer.trainable = False

# モデルの読み込み
model.compile(loss='categorical_crossentropy',
              optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
              metrics=['accuracy'])

model.summary()
history = model.fit(X_train, y_train, batch_size=64, epochs=50,  validation_data=(X_test, y_test))

# モデルの保存
model.save('model.h5')


# 精度の評価(適切なモデル名に変えて、コメントアウトを外してください)
scores = model.evaluate(X_test, y_test, verbose=1)
print('Test loss:', scores[0])
print('Test accuracy:', scores[1])

# acc, val_accのプロット
plt.plot(history.history['acc'], label='acc', ls='-')
plt.plot(history.history['val_acc'], label='val_acc', ls='-')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(loc='best')
plt.show()

测试损失:0.24770452082157135
测试精度:0.9108280539512634

8. 应用创建

最后,使用保存的学习模型,我们将它塑造成一个带有烧瓶的 Web 应用程序。
顔写真から国籍を判定するアプリ

9. 判断

评判神秘的印度乒乓球运动员
顔写真から国籍を判定するアプリ

正确答案!
顔写真から国籍を判定するアプリ

Jun Nagura,他最像日本的印度人。 .
顔写真から国籍を判定するアプリ

好的!正确答案
顔写真から国籍を判定するアプリ

10.改进

面部切割过程中精度低。我想提高级联分类器的准确性。


原创声明:本文系作者授权爱码网发表,未经许可,不得转载;

原文地址:https://www.likecs.com/show-308628611.html

相关文章: