CV

COCO 标注格式

参考链接

coco的目标检测任务的标注文件仅为一个json文件(含有所有图片的标注),形式如下:

{
	"info": ... // 整个数据集的一些信息, 用处不大
	"licenses": ... // 数据所用到的开源协议列表, 不同图片的开源协议可能不一样
	"categories": ... // 数据里所有的物体种类
	"images": ... // 每张图片的基本信息
	"annotations": ... // 标注
}

info

"info": {
    "description": "COCO 2017 Dataset",
    "url": "http://cocodataset.org",
    "version": "1.0",
    "year": 2017,
    "contributor": "COCO Consortium",
    "date_created": "2017/09/01"
},

license

categories

images

annotations

annotations 是一个列表,每个列表代表一个标注(即一个物体)。各字段的含义为

  • segmentation:表示实例分割标签,标注形式后面再详述。

  • area:物体的面积

  • iscrowd:若取值为 1 表示该条标注为一群物体,标注形式为 RLE 格式,会采用这种标注形式的例子为:叠在一起的书本,人群;若取值为 0 ,则表示该条标注代表一个轮廓清晰的物体,标注形式为多边形格式。

  • image_id:图片ID,与 images 中的 id 字段相对应

  • bbox:目标检测标签,四个数字依次代表:左上角的 xx 坐标,坐上角的 yy 坐标,目标框的宽,目标框的高。其中 xx 轴代表图片的上边缘,yy 轴代表图片的左边缘,原点位于左上角,四个数字均为绝对坐标(像素个数),但可能会有小数出现。

  • category_id:物体类别,与 categories 中的 id 字段对应

  • id:标注唯一性标识,无具体含义

注意:

  • 标注信息均为像素位置的绝对值,注意像素位置,面积等标注信息可以是小数。

  • annotations 列表是无序的,即同一张图片里的实例标注信息在 annotations 列表中不一定是连续的

实例分割标签分为两种:

  • iscrowd=0:表示该实例为单个物体,segmentation 字段为一个列表,列表中的每个元素代表着一个多边形。例如:

    代表该物体由一个凹五边形与一个三角形构成:

  • iscrowd=1:表示该实例为一群物体,segmentation 字段形式如下,counts 为 RLE 格式的mask。

    size 字段表示 [height, width],表示图片大小(该标注对应图片大小),而 counts 字段表示逐像素的 mask,mask 的形状为 [height, width](在这个例子中为 [240, 320]),mask 为 1 表示该像素值属于物体,mask 为 0 表示该像素不属于物体。counts 的具体含义为:将 mask 拉直后(按列的方式拉直,即先取第一列,紧接着取第二列,以此类推),依次出现了 0 个 0,179 个 1,27 个 0,392 个 1 等等。

    备注:counts 的第一个元素一定是数有多少个 0,counts 的长度可以是奇数也可以是偶数,因此 counts 的最后一个元素可能是数有多少个 0,也可能是数有多少个 1。一个简易的转换代码如下:

一个简易的标注可视化代码参见 show_mask.py。(仅供理解,不要重复造轮子😊

pycocotools

安装

linux参考官方源码的说明即可。

windows 下需要安装第三方改写的包,如下:

简介

数据增强

Mixup

将两张图片逐像素相加,标签按比例分配

Cutout

剪裁图像的一部分,标签不变

CutMix

剪裁的部分用另一张图的一部分替换,标签按比例分配

常用库

图像格式

图像保存尽量使用 .png 格式,jpg 格式是有损压缩的

OpenCV

跳转

PIL

PIL 默认的图像格式为 RGB,图像形状为 (H, W, 3)

CV2 默认的图像格式为 BGR,图像形状为 (H, W, 3)

mxnet 默认的图像读取格式为 RGB,图像形状为 (H, W, 3)

pytorch 默认的图像格式(网络输入)为 RGB,形状为 (B, 3, H, W)

tensoflow 默认的图像格式(网络输入)为 RGB,形状为 (B, H, W, 3)

利用 PIL 在图上写文字

由于 cv2 不支持中文文字,可以利用 PIL 实现

备注:PIL.ImageDraw.Draw.text 函数的文字位置参数指的是文字的左上角坐标,而 cv2.putText 函数中的文字位置参数默认为文字的左下角坐标。

PIL 中的子模块名都使用大写开头,且核心内容为同名的类。例如:PIL.ImageDraw 模块下的 ImageDraw 类。注意 ImageDraw 模块下的 Draw 是一个方法,返回值是一个 ImageDraw 对象。

base64

base64格式一般用于网络传输

读取磁盘图片,不进行任何解码操作。(适用于任何文件,相当于拷贝文件)

网络传输情形

lmdb

lmdb 是一个 key-value 数据库,使用 Python 安装后即可使用。可用于存储多张图片数据。保存的方式为

将图片从磁盘写入 lmdb 数据库的例子

将图片从上述 lmdb 数据库读出并转换为 cv2 的格式:

mxnet: recordio

细节与原理

mxnet 中推荐使用如下数据格式进行文件 IO,典型应用场景是原始数据为十万张图片以及相应的标签,mxnet 提供了相应的工具将所有的图片与标签压缩到一个后缀名为 .rec 的文件中,例如:

.rec 文件的实际存储为二进制形式,(猜测)实际存储格式为:

其中字节数目占用 8 个字节的空间,而每条数据的实际内容所占的字节数不定长。

mx.recordio.MXRecordIO

这个类只需要一个 .rec 文件作为输入,只处理最基本的读写操作,如下:

注意:由于每行数据所占的字节数是不一样的,所以 MXRecordIO 类只支持顺序读取,而不能进行随机读取(例如直接读取第 102 条数据)。

mx.recordio.MXIndexedRecordIO

这个类的主要作用是支持随机读写,因此还需要一个映射表用于指示每条数据的起始位置。需要两个文件作为输入,例如:

其中 data.idx 为一个文本文件,其内容大致为(分割符为制表符):

每行数据的第一个数字表示下标(即之后所述的 read_idx(idx) 中的 idx),第二个数字表示该下标对应的数据的起始位置。

小细节:.rec 文件中的字节对齐

注意实际存储时,每行的实际数据的字节数会对齐到 8 的倍数,因此实际存储时的存储如下

MXIndexedRecordIO 的实际使用例子如下:

mx.recordio.pack/unpack/pack_img/unpack_img

mxnet 中针对图像数据的 .rec 文件格式做了一些约定,当 .rec 文件的存储满足这些约定时,可以调用四个函数进行数据处理。以下 header 表示一个 IRHeader 对象,s 表示字节(即调用MXRecordIOread 方法得到的东西),而 img 表示的是一个形状为 (H, W, 3) BGR 格式的三维数组。

IRHeader 实际上就是一个 namedtuple,定义如下:

  • flag 是一个整数,可以自由根据需要设置

  • label 是一个浮点数或浮点数组,代表标签

  • id 是每条记录的唯一 id

  • id2 一般设置为 0 即可

工具

待补充

mxnet/tools/im2rec.py 用于生成 .rec 格式的数据

例子

一个一般用法的例子

一个实际例子:

生成recordio形式的数据,参考insightface

读取上述recordio形式的数据,参考insightface

mxnet

mxnet 与 pytorch 一样,对于卷积算法,默认情况下会开启自动搜索最快算法的功能。如果需要关闭此功能,需要进行如下操作(参考 github-issue):

  • 首先将模型保存文件 *.json 中的如下键值对修改:

    备注:mxnet 模型保存形式为两个文件:*.json*.params

  • 运行时需修改环境变量

    方案一:

    方案二:在 python 代码中添加

人脸识别任务

数据集及评价标准

LFW 数据集

​ LFW数据集共有13233张人脸图像,每张图像均给出对应的人名,共有5749人,且绝大部分人仅有一张图片。每张图片的尺寸为250X250,绝大部分为彩色图像,但也存在少许黑白人脸图片。 ​ LFW数据集主要测试人脸识别的准确率,该数据库从中随机选择了6000对人脸组成了人脸辨识图片对,其中3000对属于同一个人2张人脸照片,3000对属于不同的人每人1张人脸照片。测试过程LFW给出一对照片,询问测试中的系统两张照片是不是同一个人,系统给出“是”或“否”的答案。通过6000对人脸测试结果的系统答案与真实答案的比值可以得到人脸识别准确率 ———————————————— 版权声明:本文为CSDN博主「姚路遥遥」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/Roaddd/article/details/114221618

Megaface 数据集

测试方法

Cumulative Match Characteristics (CMC) curve:将待

人脸关键点

参考链接:CSDN

68 个关键点如上图所示,转换为 5 个关键点的方式为

insightface

recognition/_tools_/mask_renderer.py:自动生成口罩遮挡的人脸

训练/验证数据集:

例如:faces_umd.zip

测试数据集

例如:IJBC

ijbc_face_tid_mid.txt 文件内容解释:第一项为图片名,第二项表示该图片是哪个人,第三个数字是视频 ID。注意:同一个人可能有多个ID,例如

ijbc_name_5pts_score.txt 文件内容解释:第一项为文件名,后面连续 10 个浮点数两个一组分别为 5 个关键点的 (x,y)(x,y) 绝对像素位置坐标,最后一个数字是一个接近 1 的分数(该图片是人脸的置信度)

ijbc_template_pair_label.txt 文件内容解释:前两个为人物 ID,如前面所述,两个 ID 可能对应的是同一个人,由第三个数字指示。

不同的人物 ID 数有 23124 个,但不同的 ID 有可能对应到同一个人。并且人物 ID 与视频 ID 都不是从 1 开始连续编号。

IJBC 测试数据集

每个 ID 对应多张图片,每个人物对应多个 ID。测试时判断两个 ID 是否是同一个人。测试标签例子如下:

范式如下:训练一个网络,输入是人脸图片,输出是一个 512 维的特征。测试时,将所有属于同一个 person_id 的图片的输出特征取平均。对于每一条测试数据,求两个 person_id 对应特征的余弦距离,设定一个阈值来判断这两个 person_id 是否为同一个人。

度量指标

1: 1 验证:

  • ROC & TAR@FAR

TAR=TPTP+FN=TPPFAR=FPFP+TN=FPNTAR=\frac{TP}{TP+FN}=\frac{TP}{P}\\ FAR=\frac{FP}{FP+TN}=\frac{FP}{N}

一般而言,负样本对的数目会比较大,因此 FAR 会很小,性能指标会使用 TAR@FAR 的形式表示:通过调整阈值,使得 FAR 值达到指定的要求,统计此时的 TAR,例如:0.95@1060.95@10^{-6},表示调整相似度阈值使得 FAR 为 10610^{-6} 时,TAR的值为 0.95。备注:随着阈值的提升,TAR 与 FAR 同时下降。

另一种度量指标是对不同的相似度阈值描点:(FAR, TAR),得到 ROC 曲线,计算 ROC 曲线下的面积。

LFW 准确率评估指标:将测试数据分为 K 组,每次选择其中一个组调整阈值使得准确率最高,在剩余的 K-1 个组上计算准确率。对每个组重复上述操作,得到均值与方差,例如:0.95±0.010.95\pm0.01

1: n 识别:

Megaface 比赛评测方法:

使用 K 张图片做为底库(gallery set),测试样本为 N 个人物,每个人 M 张图片,这里 N=80,M=50,K=106N=80, M=50, K=10^6,这 N×MN\times M 张图片称为 probe set。gallery set 中没有这 N 个人物的图片,每次测试都将一个人的一张照片放入到 gallery set 中,用剩余的 M-1 张图片与 $K+1$ 张图片计算相似度并排序,判断与这张图片的相似度大小是否排在 Rank-K 以内。

实验记录:

Probe set (facescrub)图片数量:不到 4000 张

MegaFace Gallery set 未去噪前图片数量:1027058

开源工具

labelImg

标注目标检测框

labelme

标注实例分割,语义分割,目标检测等任务

安装

实例分割

  • data_annotated 为存储图片的文件夹

  • --labels label.txt 表示标签文件

  • --nodata 表示生成的标注文件中不存储图片

  • --validatelabel exact 表示不允许标注不在 labels.txt 中的标签

  • --config '{shift_auto_shape_color: -2}' 的含义未知

  • 操作界面里每个多边形需要给出标签,另外还可以选择给一个 group_id,适用于用多个多边形框住一个物体的情况

  • 输出的标注形式是每张图片一个 Json 文件,格式为 labelme 包的格式

将标注格式转换为 coco 格式

  • data_annotated 文件夹中存放着上一步得到的一堆 Json 文件(labelme 包的格式)

  • data_dataset_coco 为转换后的文件目录,转换后会得到

TextRecognitionDataGenerator

生成文本图片数据

版本号

使用方法

  • --output_dir

  • --input_dir

  • -l en:设置语言,必须有 fonts/lantin 文件夹,-l cn 必须有 fonts/cn 文件夹,文件底下都是 .ttf 文件。脚本运行的逻辑每张图片随机从这些字体中选择

  • -c 1000:生成 1000 张小条图

  • -rs-let-num-sym:适用于生成随机文本进行生成的情况,用法略去

  • -w-r:不明含义,看字面意思是生成小条图中有多少个字符,但似乎总是会生成整个文本

  • -f 32:将小条图的高度设置为 32 像素

  • -t 4:运行 run.py 脚本的线程数

  • -e jpg:生成图片的后缀名

  • -k 20:生成的文字逆时针 20 度,-rk 表示随机旋转 [-20, 20] 度角

  • -wk:不明含义

  • -bl 3:表示增加高斯模糊,高斯模糊的卷积核大小为 3,-rbl 表示随机适用 [0, 3] 的高斯模糊核

  • -b-b 3 表示背景图片从 pictures 文件夹里随机选择

  • -hw:生成手写字符,需要 tensorflow 的训练模型,未测试

  • -na 0:输出图片的命名方式为 [TEXT]_[ID].[EXT]

  • -d 2:采用的 distorsion (图像扭曲)方式为 Cosine wave

  • -do-d 0 表示只对垂直方向做扭曲,1 表示只对水平方向做扭曲,2 表示对两个方向都做扭曲

  • -wd-wd -1 根据字符串长度自动确定小条图的长度(像素个数),-wd 300表示手动设定小条图的长度

  • -al 1:设置对齐方式为中心对齐

  • -or 1:设置文字方向为垂直,即每个字的方向都是正向的,但书写方向为从上自下

  • -tc #FF0000:文字的颜色为红色

  • -sw 1.5:字符间隔,测试发现似乎无效

源码分析

目录结构如下

主要代码集中在 trdg 文件夹下,其入口为 trdg/run.pymain 函数,其实际逻辑主要是利用 argparse 模块从命令行获取控制输出的参数,利用多进程调用 trdg/data_genearator.py 中的类方法 FakeTextDataGenerator.generate_from_tuple 生成图片:

而这个函数内部将依次调用:

  • trdg/computer_text_generator.py:generatetrdg/computer_text_generator.py:generate:分别适用于生成打印体与手写体。对于前者,实际上主要就是调用了 PIL.Image.text 方法生成文字图片以及文字区域的mask

  • trdg/distorsion_generator.py:**sincosrandom 中的一个。用于对前一步生成的图片进行扭曲

  • trdg/background_generator.py:**gaussian_noiseplain_whitequasicrystalimage 中的一个,用于生成背景图片,注意:image 函数是利用用户指定的图片作为背景

  • 利用 PIL.Image.paste 方法将背景图片与扭曲过的图片融合,得到融合后的图片

  • 利用 PIL 的一些方法加上一些模糊

字体:(trdg 目前不支持ttc格式,只支持ttf格式)

ttc格式可以被 PIL.ImageFont.truetype 处理,可以通过 index 参数获得

C:\Windows\Fonts 里的arial字体,复制出来会存在

text_color的取值为 #181818,#282828#181818 这种形式,生成字体时随机从两个颜色(RGB分别随机)中取值

trdg可以返回字符的mask,mask是一个与最终生成的图片同样大小的灰度图,用0表示背景,用大于0的数表示字符,但每个字符与mask的取值未必一一对应(尚不清楚为何如此),另外如果生成图片时已经进行了高斯模糊,那么mask也会受到影响

Last updated

Was this helpful?