python脚本——图片重命名、图片合成视频、faster-rcnn画P-R曲线

调试faster rcnn算法实用的python脚本

目录

调试faster rcnn算法实用的python脚本

一、前言

二、常用python脚本

三、后记


一、前言

最近在做关于目标检测算法的研究,调试的第一个算法就是faster-rcnn,今天要说的时笔者在跑通这个算法,也就是训练、评估、数据制作等过程中用到的一些简单实用的python脚本,在这里分享出来,写的不好希望大家多多指正。

二、常用python脚本

1.python图片重命名

在调通了代码确保能够训练官方的Pascal_voc数据集之后,我们就自己标注数据集,希望训练自己的模型,采用的方法是实用labelimg工具一张一张的标,标注完之后图片名不统一,所以这个脚本就是统一命名全部图片,代码如下:

# -*- coding:utf8 -*-
import os
class BatchRename():
    '''
    批量重命名文件夹中的图片文件
​
    '''
    def __init__(self):
        self.path = 'F:\\Desktop\\data\\video_cut\\1'  #表示需要命名处理的文件夹
        # self.path = '这边写上你需要重命名的图片的路径'
    def rename(self):
        filelist = os.listdir(self.path) #获取文件路径
        total_num = len(filelist) #获取文件长度(个数)
        i = 1  #表示文件的命名是从1开始的
        for item in filelist:
            if item.endswith('.jpg'):  #初始的图片的格式为jpg格式的(或者源文件是png格式及其他格式,后面的转换格式就可以调整为自己需要的格式即可)
                src = os.path.join(os.path.abspath(self.path), item)
                #dst = os.path.join(os.path.abspath(self.path), ''+str(i) + '.jpg')#处理后的格式也为jpg格式的,当然这里可以改成png格式
                dst = os.path.join(os.path.abspath(self.path), '000' + format(str(i), '0>3s') + '.jpg')#这种情况下的命名格式为0000000.jpg形式,可以自主定义想要的格式
                try:
                    os.rename(src, dst)
                    print ('converting %s to %s ...' % (src, dst))
                    i = i + 1
                except:
                    continue
        print ('total %d to rename & converted %d jpgs' % (total_num, i))
​
if __name__ == '__main__':
    demo = BatchRename()
    demo.rename()

2.多张图片合成视频的python脚本

faster-rcnn算法可以测出单张的效果,在我修改了tf-faster-rcnn-master\tools下的demo.py之后,就能够测试多张,所以我想看到测试结果时,通常是一张张的图片放置在指定的路径下,然后,就能够跑很多demo,如下图所示:

每一张都是检测后的结果,这样看起来没有连续性,不够直观,所以此时利用这个脚本将所有的图片合成视频,就能够直观的看到效果,代码如下:

# -*- coding: UTF-8 -*-
import os
import cv2
import time
# 图片合成视频
def image2video(path,size):
    
    filelist = os.listdir(path) #获取该目录下的所有文件名
    '''
    fps:
    帧率:1秒钟有n张图片写进去[控制一张图片停留5秒钟,那就是帧率为1,重复播放这张图片5次] 
    如果文件夹下有50张 534*300的图片,这里设置1秒钟播放5张,那么这个视频的时长就是10秒
    '''
    fps = 3
    #size = (1920,1080) #图片的分辨率片
    # 导出的视频的存放目录
    file_path = "F:\\Desktop\\data\\test_video\\2\\" + str(int(time.time())) + ".avi"#合成视频导出路径
    fourcc = cv2.VideoWriter_fourcc('D', 'I', 'V', 'X')#不同视频编码对应不同视频格式(例:'I','4','2','0' 对应avi格式)
 
    video = cv2.VideoWriter( file_path, fourcc, fps, size )
 
    for item in filelist:
        if item.endswith('.jpg'):   #判断图片后缀是否是.jpg
            item = path + '/' + item 
            img = cv2.imread(item)  #使用opencv读取图像,直接返回numpy.ndarray 对象,通道顺序为BGR ,注意是BGR,通道值默认范围0-255。
            video.write(img)          #把图片写进视频
            print (item)
    video.release() #释放
​
 #调用函数,给定所有图片的路径
image2video(r'F:\\Desktop\\data\\test_result\\2\\',(1280,720))

3.遍历XML文件,进行数据分析

这个过程实际上就是对自己标注的数据集进行分析,因为我是把自己标注的数据集制作成Pascal_voc的样子,Pascal_voc共三个目录:

其中Annotations中对应的就是XML文件,每一个XML对应每一张图,也就是每一张原图生成一个XML,每个XML里保存的都是这个图片的重要信息,如:

<annotation>  
    <folder>VOC2012</folder>                             
    <filename>2007_000392.jpg</filename>                               //文件名  
    <source>                                                           //图像来源(不重要)  
        <database>The VOC2007 Database</database>  
        <annotation>PASCAL VOC2007</annotation>  
        <image>flickr</image>  
    </source>  
    <size>                                               //图像尺寸(长宽以及通道数)                        
        <width>500</width>  
        <height>332</height>  
        <depth>3</depth>  
    </size>  
    <segmented>1</segmented>                                   //是否用于分割(在图像物体识别中01无所谓)  
    <object>                                                           //检测到的物体  
        <name>horse</name>                                         //物体类别  
        <pose>Right</pose>                                         //拍摄角度  
        <truncated>0</truncated>                                   //是否被截断(0表示完整)  
        <difficult>0</difficult>                                   //目标是否难以识别(0表示容易识别)  
        <bndbox>                                                   //bounding-box(包含左下角和右上角xy坐标)  
            <xmin>100</xmin>  
            <ymin>96</ymin>  
            <xmax>355</xmax>  
            <ymax>324</ymax>  
        </bndbox>  
    </object>  
    <object>                                                           //检测到多个物体,内容同上  
        <name>person</name>  
        <pose>Unspecified</pose>  
        <truncated>0</truncated>  
        <difficult>0</difficult>  
        <bndbox>  
            <xmin>198</xmin>  
            <ymin>58</ymin>  
            <xmax>286</xmax>  
            <ymax>197</ymax>  
        </bndbox>  
    </object>  
</annotation>

所以我们对所有的XML进行遍历,就可以分析下总共有几个object,每一类的object有多少,代码如下:同样,一些路径需要根据你们自身情况改动

#coding=utf-8
import xml.dom.minidom
import os
import sys
rootdir='F:/VOC2007/Annotations/'#存有xml文件的文件夹的绝对路径
list=os.listdir(rootdir)#列出文件夹下所有的目录与文件
classes_list=[]
classes_count_imag=[1,1,1,1,1,1,1]#统计含有各个目标的图片数
classes_count_object=[1,1,1,1,1,1,1]#统计各个目标的总数
for i in range(0,len(list)):
    path=os.path.join(rootdir,list[i])
    if os.path.isfile(path):
        #用于区分imag和object
        flag=[0,0,0,0,0,0,0]
        #打开xml文档
        dom=xml.dom.minidom.parse(path)
        #得到文档元素对象
        root=dom.documentElement
        cc=dom.getElementsByTagName('name')
        for i in range(len(cc)):
            c1=cc[i]
            #如果是新的目标则将其加入classes_list数组中
            if classes_list.count(c1.firstChild.data)==0:
                classes_list.append(c1.firstChild.data)
            #统计imag和object的个数
            else:
                for j in range(0,len(classes_list)):
                    if(classes_list[j]==c1.firstChild.data):
                        if(flag[j]==0):
                            classes_count_imag[j]+=1
                            flag[j]=1
                        classes_count_object[j]+=1
print(classes_list)
print("Classes: "+str(len(classes_list)))
for i in range(len(classes_list)):
    print("Class:%20s   image:%10d张  object:%10d个"%(classes_list[i],classes_count_imag[i],classes_count_object[i]))

4.画p-r曲线

这个代码是评估用的,关于什么是p-r曲线,详情请看我之前的一篇博客

因为做目标检测,最后看这个模型的好坏,就是利用p-r曲线和mAP来评估,mAP和各类的AP在跑算法跑到最后的时候,会自动帮你算出来,但是p-r曲线要自己画,画p-r曲线,最重要的是要有你测试结束后生成的pkl文件,生成在这个路径下:

tf-fastercnn/output/vgg16/voc_2007_test/default/vgg16_faster_rcnn_iter_70000

这里的pkl文件就是用来给我们画p-r曲线的,代码如下:

#! -*- coding=utf-8 -*-
import matplotlib.pyplot as plt
import pickle
import os
​
list = ['pedestrian', 'person', 'motorbike', 'bike', 'hat', 'motorbike1', 'person_trunc']
​
for i in list:
    tmp = i + '_pr.pkl'
    fp = open(tmp,'rb')
    a = pickle.load(fp)
    plt.ylim([0.0, 1.1])
    plt.xlim([0.0, 1.1])
    tmp = 'Faster R-CNN Precision-Recall Curve (' + i + ')'
    plt.plot(a['rec'],a['prec'])
    plt.xlabel('Recall')
    plt.ylabel('Precision')
    plt.title(tmp)
    plt.show() 

当然,如果你不明白这个pkl文件长啥样,里面是啥内容,你可以把pkl转成txt文本进行阅读(因为不能直接打开pkl文件,所以需要转化),代码如下:

#-*-coding:utf-8-*-
import pickle
import numpy as np 
​
np.set_printoptions(threshold=np.NaN) 
fr = open('./motorbike1_pr.pkl','rb')    
inf = pickle.load(fr)       
print (inf)
fo = open("motorbike_pr.txt", "wb")
fo.write(str(inf))
fo.close()
fr.close()     

三、后记

以上是在我调faster-rcnn时用到的脚本,希望可以提供帮助,接下来笔者将继续阅读faster-rcnn的源码,争取发出关于源码的解读,大家互相学习啦。

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值