Python文件夹下的图片按比例移动到多个文件夹,多图像重命名,中断异常处理,多线程处理

这个月在实习,一些杂活挺多的,由此也锻炼了一下自己,平时在实验室忽略的一些杂活也总算上手做了一遍(苍天饶过谁,23333333)

任务是在CentOS下,将1000多万张图片提取深度特征,并入到数据库里,使用到了CnnExtract(ResNet)模块、Clickhouse等

电脑配置:

CPU:E5-2690 v4

RAM:512 DDR4

固态硬盘:8 TB PCI-E

GPU: dual Nvidia-2080Ti

即使是这个配置,还是需要3天的时间才能入完,期间出现过各种问题:

1、中断异常处理:首先入库的脚本运行后,会异常终止,查看log文件发现1000多万张图片有一些是损坏的,于是在for循环中添加了异常处理,把个别坏图片忽略掉继续执行:

import requests
import json
import glob  
import random
import os, sys
import datetime
import threading


if __name__=="__main__": 
    


    print 'start extract feat' 
	
    featapi = Api(('127.0.0.1',9981),3500)        # cnn port
	
    print 'start ise'        
	
    api=Api( ('127.0.0.1', 2007),3500 )                # clickhouse & TCP
    
    def action(api, featapi, folder_path, dbname, i):
        startfold = i*1+1
        endfold = i*1+2
        for fold in range(startfold, endfold):          
            folder = '{}/{}'.format(folder_path,fold)       # folder = /home/pic_data/car/car_1
            webfolder = '{}/{}'.format(webpath,fold)
            img_lists = os.listdir(folder)                              #/car/car_1
            for file in img_lists:
                try:
                    file_path = '{}/{}'.format(folder,file)                                  # name1.jpg
                    name = 'http://10.18.221.150' + webfolder + '/' + file
                    spt = 20191114172611
                    loadimg = loadfile(file_path)
                    feat = featapi.rt_cnn_img_extract(loadimg)
                    api.rt_push_img_rec_v2(dbname, 1, feat, 'SmallImgUrl,SnapTime', "%s,%d"%(name, spt))
                except Exception as e:
                    print str(e)
                    print file_path
                    pass
                continue
    for i in range(0, 8):
        t=threading.Thread(target=action,args=(api, featapi, folder_path, dbname, i))
        t.start()

其中添加了try···except 可以输出错误信息,可以从中发现哪些图片是有问题的,可以输出打印它们后期将它们删除,pass 则可以忽略这些问题,continue 则能在循环里继续提取图片深度特征以及入库。

2、多线程:在任务中,定义了action函数,下面使用for循环定义了8个线程将变量包裹,加快图像处理速度,因为单线程太浪费资源了,算了一下要10多天天才能将图片入库完毕,这下多线程 2天多一些就可以完成 。

3、多线程设置完成后,并没有那么简单,因为是原生centOS,对汉字很不友好,汉字入库会出现乱码,因为入库的Url字段是和后续的FTP有关的,可以通过网页访问,但是乱码了就无法访问了,因此又对所有图片进行了rename:

import os
import re
import sys

path = "/home/pic_data/car/car1"
fileList = os.listdir(path)  
print("before:" + str(fileList))  
os.chdir(path)  
num = 1  
for fileName in fileList:  
    pat = ".+\.(jpg|jpeg|JPG)"  
    pattern = re.findall(pat, fileName)  
    print('pattern[0]:', pattern)
    print('num:', num, 'filename:', fileName)
    os.rename(fileName, ('name' + str(num) +'_'+ '.' + pattern[0]))  
    num = num + 1  
print("---------------------------------------------------")
sys.stdin.flush()  
print("after:" + str(os.listdir(path)))  

rename这里很简单,car目录下有24个文件夹,用for循环将所有图片进行 ‘name’+str(num)+图片格式 的重命名,一共完成这个类别的1300多万张重命名。

4、文件夹下的图片按比例移动到多个文件夹:你以为这样就结束了吗?不是的。。。在千万级别的图像入库中,会出现运行一段时间速度降低的情况,这个可能涉及到底层,catch以及数据库原理等等一系列问题,在不了解的无法排查的情况下,只能使用分阶段处理的方法,将24个图像文件下面细分多个文件夹,并继续使用多线程处理。下面是某文件夹下图片按比例移动到多个文件夹下的脚本:

import os
import random
import shutil
from shutil import move
datadir_normal = "/home/pic_data/cars/car8/8/"
print datadir_normal
all_data = os.listdir(datadir_normal)    #Ttupian
num_all_data = len(all_data)
print( "num_all_data: " + str(num_all_data) )
index_list = list(range(num_all_data))
#print(index_list)
random.shuffle(index_list)
num = 0


ADir = "/home/pic_data/cars/car17/1/"#(A)


BDir = '/home/pic_data/cars/car17/2/'#(B)


CDir = '/home/pic_data/cars/car17/3/'#(C)


DDir = '/home/pic_data/cars/car17/4/'#(D)


EDir = '/home/pic_data/cars/car17/5/'#(E)


FDir = '/home/pic_data/cars/car17/6/'#(F)


GDir = '/home/pic_data/cars/car17/7/'#(G)


HDir = '/home/pic_data/cars/car17/8/'#(H)


for i in index_list:
    fileName = os.path.join(datadir_normal, all_data[i])
    if num < num_all_data*0.125:
        # print(str(fileName))
        move(fileName, ADir)
    elif num>num_all_data*0.125 and num < num_all_data*0.25:
        print(str(fileName))
        move(fileName, BDir)
    elif num>num_all_data*0.25 and num < num_all_data*0.375:
        move(fileName, CDir)
    elif num>num_all_data*0.375 and num < num_all_data*0.5:
        move(fileName, DDir)
    elif num>num_all_data*0.5 and num < num_all_data*0.625:
        move(fileName, EDir)
    elif num>num_all_data*0.625 and num < num_all_data*0.75:
        move(fileName, FDir)
    elif num>num_all_data*0.75 and num < num_all_data*0.875:
        move(fileName, GDir)
    else:
        move(fileName, HDir)
    num += 1

其中num_all_data*0.125就是按1/8的比例进行移动的,且是随机、平均移动

以上对以后深度学习制作训练集测试集、网络搭建以及中断异常处理等等都很有作用,干了杂活也学到了东西,锻炼了一下自己。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值