解析Open Image 数据小记

       最近需要去检索一些车辆的图片,据说Open Image的图片量比较大,所以准备去这个数据集上下载点,想着这是google弄得数据,本以为这比较方便,没想到中途遇到了些问题,哎想法是美好的,过程是坎坷的。

      首先吐槽一下,现在数据格式真是五花八门,就说几种常见的数据集吧

1、VOC标记信息采用的是xml格式,类别名直接命名;

2、COCO标记信息采用json格式,类别名直接命名;

3、ImageNet标记信息采用的是xml格式,类别名采用词条索引命名;

4、OpenImage标记信息采用的是csv格式,类别名采用词条索引命名;

这些数据格式相互转化倒也容易,但还是多少有些烦的,大家都统一采用一个标准就更好了。百家争鸣是很好的,但在这种很基础的地方大家统一采用一个标准个人觉得这是一个很好的做法,希望以后会有这样的组织出来规范一下。

      Open Image至2019年5月已经更新到V5了,总图片量约900万张,总计约560G。关于详细信息可以去这里:http://storage.googleapis.com/openimages/web/factsfigures.html

如果不想看英文,这篇文章:https://www.cnblogs.com/tay007/p/11282117.html对Open Image数据分布及结果做了介绍

Open Image上虽然比较人性化的划分了train val test,但只提供了全部下载,对于这么大的数据集,而且还要连接到google上去,下载成了第一大难题,好在大千世界中无私奉献的人总是有的,有个热心的人提供了一个分类下载的工具,利用这个工具你只需要下载你需要的类别就可以了,这种人真是值得敬仰。其工具及使用说明在:https://github.com/EscVM/OIDv4_ToolKit

这个工具很不错,不过只适合V4的数据集下载,由于数据结构不一样,V5的不行,截止目前作者还没写V5的下载工具。使用这个工具下载文件保存在当前文件夹下的OID文件夹,OID下分了两个文件夹:一个csv_folder;一个Dataset。这个工具使用中遇到了点疑惑,你下载600类别中的Apple类,他会在Dataset/train/Apple/Label把对应的标记框存放在txt文件中,但我下载Land vehicle是,Label文件夹就是个摆设,啥都没有,二是把数据全部存放在csv_folder/train-annotations-bbox.csv中,这个文件有时多大1G左右。没法子,只能自己解析这些文件了。在解析这些csv文件中遇到了些问题,具体下面说。

最开始我写了这么个脚本,脚本放置在OID目录下:

import csv,cv2,os

CSVMainDir='.\\csv_folder'
ClsDescptBoxPath=os.path.join(CSVMainDir,'class-descriptions-boxable.csv')
ClsDescpts=csv.reader(open(ClsDescptBoxPath,'r'))
RealClsNames={}
for ClsDescpt in ClsDescpts:
    LabelName,ClsName=ClsDescpt[0],ClsDescpt[1]
    RealClsNames[LabelName]=ClsName


def GetImAnnotBox():
    ImMainDir='.\\Dataset'
    DataType = 'validation'
    ImCls = 'Apple'
    ImDir = os.path.join(ImMainDir, DataType, ImCls)
    AnnotName='{}-annotations-bbox.csv'.format(DataType)
    AnnotPath=os.path.join(CSVMainDir,AnnotName)
    AnnotInfos=csv.reader(open(AnnotPath,'r'))
    ImNames=os.listdir(ImDir)
    for ImName in ImNames[:]:
        print('do {}\n'.format(ImName))
        ImPath=os.path.join(ImDir,ImName)
        if os.path.isfile(ImPath):
            ImPath = os.path.join(ImDir, ImName)
            Im = cv2.imread(ImPath)
            ImH, ImW, _ = Im.shape
            SearchWord = ImName[:-4]
            ObjBoxs = {}
            for AnnotInfo in AnnotInfos:
                ImNameStr = AnnotInfo[0]
                if ImNameStr == SearchWord:#这一句对很多图片名匹配不到,百思不得其解
                    LabelName=AnnotInfo[2]
                    xxyy=[float(AnnotInfo[4]), float(AnnotInfo[5]), float(AnnotInfo[6]), float(AnnotInfo[7])]
                    BBox=[int(xxyy[0]*ImW),int(xxyy[2]*ImH),int(xxyy[1]*ImW),int(xxyy[3]*ImH)]
                    RealClsName=RealClsNames[LabelName]
                    if RealClsName in ObjBoxs.keys():
                        ObjBoxs[RealClsName].append(BBox)
                    else:
                        ObjBoxs[RealClsName]=[BBox]
            if ObjBoxs:
                for Cls in ObjBoxs.keys():
                    Boxs=ObjBoxs[Cls]
                    for Box in Boxs:
                        x1,y1,x2,y2=Box
                        cv2.rectangle(Im,(x1,y1),(x2,y2),(255,0,0),2,2)
                        cv2.putText(Im,Cls,(int((x1+x2)/2),y1),1,2,(0,255,0),2,1)
                cv2.namedWindow('Im',cv2.WINDOW_NORMAL)
                cv2.imshow('Im',Im)
                cv2.waitKey(1000)
            else:
                print('No annotbox\n')
                cv2.destroyWindow('Im')


if __name__=='__main__':
    GetImAnnotBox()

如上述if ImNameStr == SearchWord:#这一句对很多图片名匹配不到,百思不得其解,我单独打印ImNameStr没问题呀。是在是调试不好了,最后我把csv每一行存放在一个list变量中,改成下面这样测试可以了:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 2019/09/21 by DQ
import csv,cv2,os

def GetRealClsNames(ClsDescptBoxPath):
    ClsDescpts=csv.reader(open(ClsDescptBoxPath,'r'))
    RealClsNames={}
    for ClsDescpt in ClsDescpts:
        LabelName,ClsName=ClsDescpt[0],ClsDescpt[1]
        RealClsNames[LabelName]=ClsName
    return RealClsNames

def GetAnnotInfos(AnnotPath):#把csv每一行存放在一个list变量中
    AnnotInfos=[]
    with open(AnnotPath, 'r') as FId:
        for AnnotInfo in csv.reader(FId):
            AnnotInfos.append(AnnotInfo)
    return AnnotInfos


def GetImAnnotBox(CSVMainDir,ImMainDir,DataType,ImCls):
    ExpectClss=('Land vehicle','Van','Car')#我想显示的类别,类别比较多,都画出来,眼花了
    ClsDescptBoxPath = os.path.join(CSVMainDir, 'class-descriptions-boxable.csv')
    RealClsNames = GetRealClsNames(ClsDescptBoxPath)
    AnnotName='{}-annotations-bbox.csv'.format(DataType)
    AnnotPath=os.path.join(CSVMainDir,AnnotName)
    AnnotInfos=GetAnnotInfos(AnnotPath)
    ImDir = os.path.join(ImMainDir, DataType, ImCls)
    ImNames=os.listdir(ImDir)
    for ImName in ImNames[:]:
        ImPath=os.path.join(ImDir,ImName)
        if os.path.isfile(ImPath):
            ImPath = os.path.join(ImDir, ImName)
            Im = cv2.imread(ImPath)
            ImH, ImW, _ = Im.shape
            ObjBoxs = {}
            for AnnotInfo in AnnotInfos:
                if AnnotInfo[0]==ImName[:-4]:
                    xxyy=[float(AnnotInfo[4]), float(AnnotInfo[5]), float(AnnotInfo[6]), float(AnnotInfo[7])]
                    BBox=[int(xxyy[0]*ImW),int(xxyy[2]*ImH),int(xxyy[1]*ImW),int(xxyy[3]*ImH)]
                    LabelName = AnnotInfo[2]
                    RealClsName=RealClsNames[LabelName]
                    if RealClsName in ExpectClss:
                        if RealClsName in ObjBoxs.keys():
                            ObjBoxs[RealClsName].append(BBox)
                        else:
                            ObjBoxs[RealClsName]=[BBox]
            if ObjBoxs:
                for Cls in ObjBoxs.keys():
                    Boxs=ObjBoxs[Cls]
                    for Box in Boxs:
                        x1,y1,x2,y2=Box
                        cv2.rectangle(Im,(x1,y1),(x2,y2),(255,0,0),2,2)
                        cv2.putText(Im,Cls,(int((x1+x2)/2),y1),1,2,(0,0,255),2,1)
                #cv2.namedWindow('Im',cv2.WINDOW_NORMAL)
                #cv2.imshow('Im',Im)
                #cv2.waitKey(1000)
                SaveImPath=os.path.join('.\\Temp',ImName)
                cv2.imwrite(SaveImPath,Im)
                print('{} has annotbox\n'.format(ImName))
            else:
                print('{} no annotbox\n'.format(ImName))
                #cv2.destroyWindow('Im')

if __name__=='__main__':
    CSVMainDir='.\\OID\\csv_folder'
    ImMainDir='.\\OID\\Dataset'
    DataType ='validation'# 'train'
    ImCls = 'Land vehicle'
    GetImAnnotBox(CSVMainDir,ImMainDir,DataType,ImCls)

下面是一些截图显示:

google虽然没有明确说明但从上述示例来看,600个标记框类中的Land vehicle是个泛类或大类,Car其实也属于这个类,只要是没有明确的或车辆混杂在一起的陆地车辆类似乎都被标记这个泛化类了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值