Bootstrap

基于Attention_CNN_GRU的野生动物监测图像分类

大一的时候突发奇想选择了这样的一个方向,并查阅了相关文献,努力去完成这样的一个系统化的东西。但确实这方面做的人很少,也没有找到有关的进行学习,做的也是很是缓慢,同时也是运用到了Paddle框架,Paddle的一小部分展示如下:

import paddle 
import sys
import os



import paddlehub as hub 
module = hub.Module(name='resnet50_vd_animals')


Downloading resnet50_vd_animals
[==================================================] 100.00%
Uncompress /home/aistudio/.paddlehub/tmp/tmp2qvasfuz/resnet50_vd_animals
[==================================================] 100.00%



Filelist = [] 
Dirlist = []
path ='dataset/img'
import os
def set_label(file_path):
    del_str='.ipynb_checkpoints'
    for home, dirs, files in os.walk(file_path):
        for d in dirs:
            if del_str in d:
                continue
            else:
                Dirlist.append(d) 
set_label(path)
print(Dirlist)

def get_filelist(dir):
 
    data_dict={}.fromkeys(['path','label'])
    del_str='.ipynb_checkpoints'
    for home, dirs, files in os.walk(path):
        for filename in files:
            if del_str in filename:
                continue
            else:
                data_dict={}.fromkeys(['path','label'])
                img_path=os.path.join(home, filename)
                data_dict['path']=img_path
                for i in range(len(Dirlist)):
                    if Dirlist[i] in img_path:
                        img_label=i
                data_dict['label']=img_label
                Filelist.append(data_dict)
    return Filelist, Dirlist   #返回文件名 路径

img_files,labels=get_filelist('dataset/img')

forecast_list=[]

def dict_save(trainfilename,validatafilename,data):
    for i in range(len(data)):

        if 0<=i%10 and i%10<=5:   
            with open(trainfilename,"a") as f:
                train = data[i]["path"]+" "+str(data[i]["label"])+"\n"
                f.write(train)

        if 6<=i%10 and i%10<=7:  
            with open(validatafilename,"a") as f1:
                validata = data[i]["path"]+" "+str(data[i]["label"])+"\n"
                f1.write(validata)

        if 8<=i%10:
            forecast_list.append(data[i]["path"])
    print("保存文件成功") 


def text_save(filename, data):
    str_list = [line+'\n' for line in data]

    with open(filename, 'w') as f:
        f.writelines(str_list)
    print("保存文件成功") 

validata_file='data/validata_list.txt'
label_file='data/label_list.txt'
train_file='data/train_list.txt'

dict_save(train_file,validata_file,img_files)
text_save(label_file,labels)

['野骆驼', '高鼻羚羊', '野牛', '麋鹿', '虎', '野马', '普氏原羚', '白唇鹿', '黑麂', ' 豚鹿', '丹顶鹤', '蒙古野驴', '中华秋沙鸭', '扭角羚', '鼷鹿', '西藏野驴', '熊猫', '台湾鬣羚', '河狸', '梅花鹿', '扬子鳄', '金钱豹', '藏羚', '云豹', '坡鹿', '紫貂', '野牦牛', '塔尔羊', '绿孔雀', '赤斑羚', '蜂猴', '藏羚羊']
保存文件成功
保存文件成功


from paddlehub.dataset.base_cv_dataset import BaseCVDataset

class HumanfaceDataset(BaseCVDataset): 
    def __init__(self):
        self.dataset_dir = '/home/aistudio'
        super(HumanfaceDataset,self).__init__(
            base_path=self.dataset_dir,
           train_list_file="data/train_list.txt", 
           label_list_file="data/label_list.txt",
            validate_list_file="data/validata_list.txt",
        )
dataset = HumanfaceDataset()

reader = hub.reader.ImageClassificationReader( #reader 负责对dataset进行数据预处理
    image_width=module.get_expected_image_width(),
    image_height=module.get_expected_image_height(),
    images_mean=module.get_pretrained_images_mean(),
    images_std=module.get_pretrained_images_std(),
    dataset = dataset
)

config = hub.RunConfig(   
    use_cuda=True,
    num_epoch=10,
    batch_size=62,
    log_interval=50,
    strategy=hub.DefaultFinetuneStrategy())

input_dict, output_dict, program = module.context(trainable=True)
img = input_dict["image"]

feature_map = output_dict["feature_map"]

feed_list = [input_dict["image"].name] 
task = hub.ImageClassifierTask(    
    data_reader=reader,
    feed_list=feed_list,
    feature=feature_map,
    num_classes=dataset.num_labels,
    config=config)

task.finetune_and_eval() 
import numpy as np
import re
import os



data = forecast_list

label_map = dataset.label_dict()
index = 0
num = 0
run_states = task.predict(data=data)

results = [run_state.run_results for run_state in run_states]
count=0
num1=0
for batch_result in results:
    batch_results = np.max(batch_result, axis=2)[0]
    batch_result = np.argmax(batch_result, axis=2)[0]
    
    for result in batch_result:
        
        num+=1
        index += 1
        try:
            if batch_results[index-1]:
                pass
        except:
            index=1
            
        result = label_map[result]
        if batch_results[index-1]>=0.6:
            num1+=1
            print("input %i is %s, and the predict result is %s" %(num, data[num - 1], result))
            res = re.compile('[\u4e00-\u9fff]+').findall(data[num - 1])
            if res[0] in result:
                count+=1
        else:
            print("input %i is %s, 该动物未被识别" %(num, data[num - 1]))
        
print("能够识别出来的精确率是:%.2f%%"%(count/num1*100))

 其中对于图像的低照度增强,这里借鉴一下崔崔的:

def Image_enhancing(image):
    img=cv2.cvtColor(image,cv2.COLOR_BGR2GARY)/255
    # img = 0.2989*image[:, :, 2]+0.5870*image[:, :, 1]+0.1140*image[:, :, 0]
    #二者效果一样,使用后者不需要再除以255
    img = replaceZeroes(img)
    img_n = (np.power(img, 0.24)+(1-img)*0.5+np.power(img, 2))/2
    sigma = 3
    window = 3*sigma*2+1

    guass1 = cv2.GaussianBlur(img, (window, window), sigma)
    r1 = guass1/img
    R1 = np.power(img_n, r1)
    sigma = 20
    window = 3*sigma*2+1

    guass2 = cv2.GaussianBlur(img, (window, window), sigma)
    r2 = guass2/img
    R2 = np.power(img_n, r2)
    sigma = 24
    window = 255

    guass3 = cv2.GaussianBlur(img, (window, window), sigma)
    r3 = guass3/img
    R3 = np.power(img_n, r3/255)
    R = (R1+R2+R3)/3
    Rr = R*(image[:, :, 2]/img_n)
    Rg = R*(image[:, :, 1]/img_n)
    Rb = R*(image[:, :, 0]/img_n)
    rgb = np.concatenate(
        (Rb[:, :, np.newaxis], Rg[:, :, np.newaxis], Rr[:, :, np.newaxis]), axis=2)
    return rgb+image
def replaceZeroes(img):
    min_nonzero = min(img[np.nonzero(img)])
    img[img == 0] = min_nonzero
    return img

以上的几个要点:

  1. 读取图像时需要归一化,归一化放在转为灰度图之后;

  2. 显示增强图像时需要除以255;

  3. cv2.imread()读取图片通道为BGR;

  4. 有文章说需要将增强图像超过1的部分设为1,详见

;