画像の顔認識と分類

6775 ワード

自分の写真の分類を扱うことで、顔認識で分類するという発想が芽生え、現在のネットアルバムではこの機能が提供されていますが、勉強したつもりでAIに近づき、今はAIが流行しているのではないでしょうか.もともとは自分で書く予定でしたが、ネット上のチュートリアルにも牛の毛が多く入っていて、結局半分まで書いたところ、オープンソースのface_recognitionは、認識精度が98%に達したという.この精度にかかわらず、持ってきて使えばいいです.具体的なインストール手順は、チュートリアルもたくさんあり、自分で探すことができます.サードパーティライブラリを採用しているので,コア機能は対応方法を呼び出せばよいが,コードの大部分は識別前と識別後の作業を処理する.その間、ある大神が書いた顔認識に関する文章を見て、ここに貼った.個人の参考に供する(https://www.cnblogs.com/neo-T/p/6432596.html).
本文中のface_recognition.face_locationsはmodel="cnn"のモードを採用しており、このモードはマシンメモリやCPUを非常に消費するので、認識前に画像を処理したり、サムネイルを一時ファイルの形式として処理したりしますが、それでも100枚の画像も12 Hを使っているので、マシン構成が足りない場合は慎みます.デフォルトのモデルも使用できます.
まずサンプルデータを出す必要があります.探している人の写真は、シングルの正面写真がいいです.私は10個のサンプルを置いたが,一部の側面と相対的にぼやけているものがあり,比較認識時にも認識できるものがあるようだ.また、しきい値もあります.自分に合ったしきい値を何度もデバッグして見つけます.
 
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019-07-10 18:10
# @Author  : yy
# @File    : CNNImage.py

import os
import cv2
import face_recognition
from PIL import Image
import  numpy as np
import exifread
import shutil
import time

class Imagetags():
    def __init__(self):
        self.SampPath =r'E:\Sample'
        self.Pic = r'E:\Pic'
        self.Photo = r'E:\Photo'
        self.TmpPath = r'E:\PicTmp'


    def ResizeImage(self,path):
        ImgTmp = cv2.imread(path)
        # Img = cv2.resize(img, (200, 100))
        Img = cv2.resize(ImgTmp, (0, 0),fx=0.5,fy=0.5,interpolation=cv2.INTER_CUBIC)
        return Img
    def PubToCnnFile(self,ImgPath):
        Img = Image.open(ImgPath)
        #          
        size = (640, 640)
        Img.thumbnail(size)
        TmpImgName = os.path.basename(ImgPath).split('.')[0] + '_tmp' + '.png'
        PicTmpPath = os.path.join(self.TmpPath, TmpImgName)
        #   PNG  
        Img.save(PicTmpPath, 'PNG')
        # Img.close()
        return PicTmpPath
        # os.remove(tmppath)


    def GetImageCodes(self,ImgPath):
        #  CNN              ,       ,      CPU   。
        PicTmpPath = self.PubToCnnFile(ImgPath)
        #    
        img = face_recognition.load_image_file(PicTmpPath)
        # model = "cnn"       CPU    ,PC     ,        
        # face_locations = face_recognition.face_locations(img)
        face_locations = face_recognition.face_locations(img,model = "cnn")
        #            
        Photo_Encodings = face_recognition.face_encodings(img, face_locations)
        return Photo_Encodings

    def GetSampleImgCodes(self):
        #  
        SampleCodeList = []
        for dirpath,dirnames,filenames in os.walk(self.SampPath):
            for item  in filenames:
                SampleImgPath = os.path.join(dirpath, item)
                print(SampleImgPath)
                Sample_Encodings = self.GetImageCodes(SampleImgPath)
                for codes in Sample_Encodings:
                    SampleCodeList.append(codes)
                    print(len(SampleCodeList))
        #           list
        return SampleCodeList
    def PubMoveFile(self,ImgPath,InPath,item):
        FileName = os.path.basename(ImgPath)
        #      
        if FileName.endswith(('MP4','mp4')):
            date = self.GetMp4EXIF(ImgPath)
        elif FileName.endswith(('jpg','JPG')):
            date = self.GetJpgEXIF(ImgPath)
        Datepath = os.path.join(InPath, date,item)
        if os.path.exists(Datepath):
            shutil.move(ImgPath, Datepath)
        else:
            os.makedirs(Datepath)
            shutil.move(ImgPath, Datepath)
        #         
        return Datepath
    def ComparePic(self,ImgPath,SampleCodeList):
        compareList = []
        Photo_Encodings = self.GetImageCodes(ImgPath)
        if Photo_Encodings:
            i=1
            for code in Photo_Encodings:
                i = i+1
                resList = []
                for sample_codes in SampleCodeList:
                    #tolerance=0.4    ,         ,    compare_faces
                    CompareRes = face_recognition.compare_faces([sample_codes],code, tolerance=0.4)
                    resList = resList+CompareRes
                if resList.count(True) < resList.count(False):
                    compareList.append(False)
                else:
                    compareList.append(True)
        return compareList



    def CompareImage(self):
        SampleCodeList = self.GetSampleImgCodes()
        print('     :',len(SampleCodeList))
        print('    ')
        starttime = time.time()
        #        
        x = 0
        y = 0
        for dirpath,dirnames,filenames in os.walk(self.Pic):
            for file  in filenames:
                ImgPath = os.path.join(dirpath, file)
                if 'mp4' in file or 'MP4' in file:
                    self.PubMoveFile(ImgPath, self.Photo,'MP4')
                else:
                    # imagepath = os.path.join(dirpath, file)
                    compareList = self.ComparePic(ImgPath,SampleCodeList)
                    if True in compareList:
                        #    
                        x = x+1
                        GoPath = self.PubMoveFile(ImgPath,self.Photo,'Zhou')
                        print('         :', GoPath)
                    else:
                        #     
                        y = y+1
                        GoPath = self.PubMoveFile(ImgPath,self.Photo,'Other')
                        #        ,len(compareList)               。
                        print('          :', GoPath,len(compareList))
                    # self.MoveFile(file,ImgPath,compareList)
        endtime = time.time()
        TTime = endtime-starttime
        print('  :',TTime)
        print('   :',x,'    :',y)

    def GetJpgEXIF(self,imagepath):
        Files = open(imagepath, 'rb')
        tags = exifread.process_file(Files)
        Files.close()
        ExDate = 'EXIF DateTimeOriginal'
        if "EXIF DateTimeOriginal" in tags.keys():
            datetmp = str(tags[ExDate]).split(' ')[0].split(':')
            date = '_'.join(datetmp[0:2])
        else:
            file = os.path.basename(imagepath)
            if ('HBGC' in file) or ('IMG' in file):
                datetmp = file.split('_')[1][0:6]
                year = datetmp[0:4]
                month = datetmp[4:6]
                date = year+'_'+month
        return date
    def GetMp4EXIF(self,file):
        datetmp = str(file).split('_')[1][0:6]
        year = datetmp[0:4]
        month = datetmp[4:6]
        date = year + '_' + month
        return date

    



run = Imagetags()
run.CompareImage()