解读keras版Faster R-CNN(二)

这次带来的是Faster R-CNN中的子程序get_data()的代码解析

import cv2
import numpy as np

代码首先导入的是两个库。其中cv2主要是图像方面的库,numpy是科学计算方面的库。

def get_data(input_path):
    found_bg = False
    all_imgs = {}

    classes_count = {}

    class_mapping = {}

    visualise = True

代码经过了一些的初始化。重新提一下这些变量最后的作用:
all_imgs是一个list,但是他的每个元素都是字典,也就是存放的是每一张图片里面的信息,
比如某张图像的总共有多少个目标,有多少个类等
从便签文件路径中得到所有的图像,类别的数量还有类别
class_count 是各类总共的数量,是一个字典,key是类名,value是该类的数量,
class_mapping 是每个类对应的标签

with open(input_path, 'r') as f:

    print('Parsing annotation files')

    for line in f:
        line_split = line.strip().split(',')
        (filename, x1, y1, x2, y2, class_name) = line_split

由于代码太长,我们剪切出一段来慢慢解析。
本段代码一开始是以读取的方式打开了这个输入的路径( with open(input_path, ‘r’) as f:)

将这个路径中的信息逐个读取出来赋值给line(for line in f:)

line.strip().split(',')

其中line.strip()是用来删除字符串头尾指定的字符。

strip()的用法:

Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。

注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。

.split(‘,’)是用括号中的符号对前面的字符进行划分,比如:AB→A,B

(filename, x1, y1, x2, y2, class_name) = line_split
将划分的信息分别输送给前面设定好的变量名。

        if class_name not in classes_count:
            classes_count[class_name] = 1
        else:
            classes_count[class_name] += 1

现在这个classes_count计算了所有类别所有的数目了。

对图像中的类进行各类总共的数量的计算,如果这个class_name不在之前预存好集内,我们就给这个数据集类加一个key并且赋值为1。

        if class_name not in class_mapping:
            if class_name == 'bg' and not found_bg:
                print('Found class name with special name bg. Will be treated as a'
                      ' background region (this is usually for hard negative mining).')
                found_bg = True
            class_mapping[class_name] = len(class_mapping)

这里判断class_name 是否在 class_mapping,这里如果发现背景这个标签就把 found_bg设为True。并把这个类设定了位置。这里设置的是长度(len(class_mapping))我们通过设置长度确定各类的标签。用十进制表示,比如这个class_mapping有10个东西,那么我们设置这个位置的class_mapping里面这个标签的位置为第10个。
好了现在class_mapping记载了所有的类别了

if filename not in all_imgs:
    all_imgs[filename] = {}

    img = cv2.imread(filename)
    (rows, cols) = img.shape[:2]
    all_imgs[filename]['filepath'] = filename
    all_imgs[filename]['width'] = cols
    all_imgs[filename]['height'] = rows
    all_imgs[filename]['bboxes'] = []
    if np.random.randint(0, 6) > 0:
        all_imgs[filename]['imageset'] = 'trainval'
    else:
        all_imgs[filename]['imageset'] = 'test'

现在是对这个名为all_imgs的字典进行赋值,先是对字典内嵌套一个字典(all_imgs[filename] = {}),然后是读取图片(img = cv2.imread(filename))还有图像的尺寸((rows, cols) = img.shape[:2])。下面这段代码保存了图片的路径和长宽

        all_imgs[filename]['filepath'] = filename
        all_imgs[filename]['width'] = cols
        all_imgs[filename]['height'] = rows
        all_imgs[filename]['bboxes'] = []

这代码里对bboxes进行了赋空值。然后是对图像划分训练集还是测试集

if np.random.randint(0, 6) > 0:
    all_imgs[filename]['imageset'] = 'trainval'
else:
    all_imgs[filename]['imageset'] = 'test'

最后对刚刚赋空值的bboxes赋值

all_imgs[filename]['bboxes'].append(
            {'class': class_name, 'x1': int(float(x1)), 'x2': int(float(x2)), 'y1': int(float(y1)),
             'y2': int(float(y2))})

最后对这个all_imgs里的数据保存到一个数据all_data里。

all_data = []
for key in all_imgs:
    all_data.append(all_imgs[key])

真的最后了,把”背景“这类移动到最后一个去

if found_bg:
    if class_mapping['bg'] != len(class_mapping) - 1:
        key_to_switch = [key for key in class_mapping.keys() if class_mapping[key] == len(class_mapping) - 1][0]
        val_to_switch = class_mapping['bg']
        class_mapping['bg'] = len(class_mapping) - 1
        class_mapping[key_to_switch] = val_to_switch

返回需要的值:

return all_data, classes_count, class_mapping
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值