SynthText 生成字符,全过程汇总

转载:https://blog.csdn.net/yshtjdx/article/details/112425866

转载:https://blog.csdn.net/baidu_14831657/article/details/77498467

记录

python3不兼容的可以自行修改

 

自然场景的文字识别的数据生成至关重要,可以大量降低人工标注的成本,这里详细介绍SynthText的安装和使用,并生成自己的bg数据集对应的图片以及优化引入生成垂直文本的功能。

SynthText官方示例生成效果

https://github.com/ankush-me/SynthText

直接下载工程,和工程开源的SynthText.h5等数据,直接python gen.py即可。

samples

我这里使用的是工程中的python3分支

Adding New Images

Segmentation and depth-maps are required to use new images as background. Sample scripts for obtaining these are available here.

  • predict_depth.m MATLAB script to regress a depth mask for a given RGB image; uses the network of Liu etal. However, more recent works (e.g., this) might give better results.
  • run_ucm.m and floodFill.py for getting segmentation masks using gPb-UCM.

For an explanation of the fields in dset.h5 (e.g.: seg,area,label), please check this comment.

要想使用自己的bg数据,需要先得到depth和seg, 然后合并成dset.h5文件,之后调用SynthText中的gen.py生成数据;

生成depth

https://bitbucket.org/fayao/dcnf-fcsp/src/master/

我这里使用的自己的window10的笔记本电脑中的matlab环境(Matlab2016b)

使用改代码时,需要在libs下MatConvNet和VLFeat,虽然原工程已经配置了这两个,但是matconvnet_20141015需要换成matconvnet-1.0-beta9版本(下载地址:https://www.vlfeat.org/matconvnet/download/),不然程序运行时会报错, VLFeat不用修改;同时修改./demo/demo_DCNF_FCSP_depths_prediction.m中的相关部分(P15-23行)如下:

function demo_DCNF_FCSP_depths_prediction(varargin)


run( '../libs/vlfeat-0.9.18/toolbox/vl_setup');

% dir_matConvNet='../libs/matconvnet_20141015/matlab/';
dir_matConvNet='../libs/matconvnet-1.0-beta9/matconvnet-1.0-beta9/matlab/';
addpath(genpath(dir_matConvNet));
run([dir_matConvNet 'vl_setupnn.m']);
  • function demo_DCNF_FCSP_depths_prediction(varargin)


    run( '../libs/vlfeat-0.9.18/toolbox/vl_setup');

    % dir_matConvNet='../libs/matconvnet_20141015/matlab/';
    dir_matConvNet='../libs/matconvnet-1.0-beta9/matconvnet-1.0-beta9/matlab/';
    addpath(genpath(dir_matConvNet));
    run([dir_matConvNet 'vl_setupnn.m']);
     

注意重新编译matconvert-1.0-beta9版式时,参考https://www.vlfeat.org/matconvnet/install/中的说明,我这里是直接编译的CPU版本;具体步骤如下,因为我的matlab一开始没有装C++的编译器,所以需要配置VS2015的C++编译器给matlab(https://blog.csdn.net/qq_17783559/article/details/82017379),然后mex -setup C++才能成功。

matcovert

编译成功后,使用dcnf-fcsp/src/master/demo/demo_DCNF_FCSP_depths_prediction.m或者SynthText/prep_scripts/predict_depth.m生成自己准备的bg图片的depth.mat文件,我是准备了12张example,每一个example对应一个文件夹,最终生成的效果是每一个文件夹下有一张rgb原始图片,生成一张gray灰度图片和一份depth.mat文件。

matconvert_1

将这12个文件夹放到服务器上,运行convert_depth_mat_to_h5.py程序,得到depth.h5文件。

##convert_depth_mat_to_h5.py
import os
import h5py
import glob

def convert_mat_to_h5(mat_path, h5_output_path):

    data_w=h5py.File(h5_output_path,'w')
    for sample in glob.glob(path):
        print('sample:',sample)
        imname = sample.split('/')[-2] + '.jpg'
        data=h5py.File(sample,'r')
        data_w.create_dataset(imname, data=data['data_obj'][:])
    data_w.close()

if __name__=='__main__':
    path = r'/data/nfs/yangsuhui/SynthText/prep_scripts/new_own_image_material/results_three/custom_outdoor_sample/*/*.mat'
    output_path = r'/data/nfs/yangsuhui/SynthText/prep_scripts/new_own_image_material/depth.h5'
    convert_mat_to_h5(path,output_path)

  • ##convert_depth_mat_to_h5.py
    import os
    import h5py
    import glob

    def convert_mat_to_h5(mat_path, h5_output_path):

        data_w=h5py.File(h5_output_path,'w')
        for sample in glob.glob(path):
            print('sample:',sample)
            imname = sample.split('/')[-2] + '.jpg'
            data=h5py.File(sample,'r')
            data_w.create_dataset(imname, data=data['data_obj'][:])
        data_w.close()

    if __name__=='__main__':
        path = r'/data/nfs/yangsuhui/SynthText/prep_scripts/new_own_image_material/results_three/custom_outdoor_sample/*/*.mat'
        output_path = r'/data/nfs/yangsuhui/SynthText/prep_scripts/new_own_image_material/depth.h5'
        convert_mat_to_h5(path,output_path)

生成seg

https://github.com/jponttuset/mcg

此处修改:我的安装环境是win10+vmware15+ubuntu20.04,中间虚拟机安装ubuntu会卡住

查过很多资料,最后发现是系统的安装iso,显卡驱动nv卡和ubuntu有些问题

解决办法,虚拟机安装系统一开始就按ESC,进入脚本安装界面,然后选择install(原始图像驱动)这个选项安装就可以。(该问题卡了我两天)

该程序只能运行在linux环境下,因此我在ubuntu16.04的环境下安装了matlab R2016b,然后使用SynthText/prep_scripts/run_ucm.m,如下图所示,修改代码中的img_dir和mcg_dir路径即可,得到指定路径下的

ucm.mat文件,然后运行SynthText/prep_scripts/floodFill.py,修改floodFill.py程序中的base_dir为第一步生成的ucm.mat文件路径,得到最终的seg_uint16.h5文件。

seg_matlab

合并depth和seg等文件成统一的dest.h5

运行程序add_more_data.py,借鉴use_preproc_bg.py写法),用于将1、2步生成的depth和seg和原图组合成同一个dset文件。

##add_more_data.py
import numpy as np
import h5py
import os, sys, traceback
import os.path as osp
import wget, tarfile
import cv2
from PIL import Image



def add_more_data_into_dset(DB_FNAME,more_img_file_path,more_depth_path,more_seg_path):
  db=h5py.File(DB_FNAME,'w')
  #depth_db=get_data(more_depth_path)
  depth_db=h5py.File(more_depth_path,'r')
  #seg_db=get_data(more_seg_path)
  seg_db=h5py.File(more_seg_path,'r')
  db.create_group('image')
  db.create_group('depth')
  db.create_group('seg')
  for imname in os.listdir(more_img_file_path):
    if imname.endswith('.jpg'):
      full_path=more_img_file_path+imname
      print(full_path,imname)

      # j=Image.open(full_path)
      # imgSize=j.size
      # rawData=j.tostring()
      # img=Image.fromstring('RGB',imgSize,rawData)
      img = cv2.imread(full_path)
      img = img[...,::-1]
      #img = img.astype('uint16')
      db['image'].create_dataset(imname,data=img)
      db['depth'].create_dataset(imname,data=depth_db[imname])
      db['seg'].create_dataset(imname,data=seg_db['mask'][imname])
      db['seg'][imname].attrs['area']=seg_db['mask'][imname].attrs['area']
      db['seg'][imname].attrs['label']=seg_db['mask'][imname].attrs['label']
  db.close()
  depth_db.close()
  seg_db.close()
# path to the data-file, containing image, depth and segmentation:
DB_FNAME = '/data/nfs/yangsuhui/SynthText/prep_scripts/new_own_image_material/dset_own_12.h5'

#add more data into the dset
more_depth_path='/data/nfs/yangsuhui/SynthText/prep_scripts/new_own_image_material/depth.h5'
more_seg_path='/data/nfs/yangsuhui/SynthText/prep_scripts/new_own_image_material/seg_uint16.h5'
more_img_file_path='/data/nfs/yangsuhui/SynthText/prep_scripts/new_own_image_material/bg_imgs/'

add_more_data_into_dset(DB_FNAME,more_img_file_path,more_depth_path,more_seg_path)

  • ##add_more_data.py
    import numpy as np
    import h5py
    import os, sys, traceback
    import os.path as osp
    import wget, tarfile
    import cv2
    from PIL import Image

    def add_more_data_into_dset(DB_FNAME,more_img_file_path,more_depth_path,more_seg_path):
      db=h5py.File(DB_FNAME,'w')
      #depth_db=get_data(more_depth_path)
      depth_db=h5py.File(more_depth_path,'r')
      #seg_db=get_data(more_seg_path)
      seg_db=h5py.File(more_seg_path,'r')
      db.create_group('image')
      db.create_group('depth')
      db.create_group('seg')
      for imname in os.listdir(more_img_file_path):
        if imname.endswith('.jpg'):
          full_path=more_img_file_path+imname
          print(full_path,imname)

          # j=Image.open(full_path)
          # imgSize=j.size
          # rawData=j.tostring()
          # img=Image.fromstring('RGB',imgSize,rawData)
          img = cv2.imread(full_path)
          img = img[...,::-1]
          #img = img.astype('uint16')
          db['image'].create_dataset(imname,data=img)
          db['depth'].create_dataset(imname,data=depth_db[imname])
          db['seg'].create_dataset(imname,data=seg_db['mask'][imname])
          db['seg'][imname].attrs['area']=seg_db['mask'][imname].attrs['area']
          db['seg'][imname].attrs['label']=seg_db['mask'][imname].attrs['label']
      db.close()
      depth_db.close()
      seg_db.close()
    # path to the data-file, containing image, depth and segmentation:
    DB_FNAME = '/data/nfs/yangsuhui/SynthText/prep_scripts/new_own_image_material/dset_own_12.h5'

    #add more data into the dset
    more_depth_path='/data/nfs/yangsuhui/SynthText/prep_scripts/new_own_image_material/depth.h5'
    more_seg_path='/data/nfs/yangsuhui/SynthText/prep_scripts/new_own_image_material/seg_uint16.h5'
    more_img_file_path='/data/nfs/yangsuhui/SynthText/prep_scripts/new_own_image_material/bg_imgs/'

    add_more_data_into_dset(DB_FNAME,more_img_file_path,more_depth_path,more_seg_path)

生成数据

根据自己数据生成的dset_own_12.h5文件,运行gen.py(修改DB_FNAME = osp.join(DATA_PATH,‘dset.h5’)为自己的dset文件),即可生成自己数据背景下的生成数据。

运行gen.py,终端显示(有些bg图片计算过程中会出现一些错误,比如下面的0 of 11,这表明有些图片做bg不太合适,最终生成的是10张图片(去掉背景错误生成不了的),10中背景,不同背景只生成一张,通过gen.py中的超参数设置(INSTANCE_PER_IMAGE)):

gen

运行visualize_results.py可以查看SynthText.h5文件生成的效果,并保存图片,运行效果如下,运行一张图片,并弹出图片窗口,终端是显示图片名称和生成的图片中的words和chars个数以及生成的文本text,最终的图片上可以控制显示charBB(字符级别的框)和wordBB(单词级别)。

vis

下图中除了第一张是用的官方的SynthText.h5生成的,其余的都是自己的bg图片生成的效果。

在这里插入图片描述

垂直文本的生成

参考https://github.com/ankush-me/SynthText/issues/114, 修改text_utils.py文件下的相应函数(render_multiline)即可,效果如下:
在这里插入图片描述

注意事项

1、该程序的visualize_results.py利用matplotlib可以将远程的SynthText.h5中的生成的内容显示出来,用pillow或者opencv很难将图像显示出来在MobaxTerm上;

2、步骤1和2中的depth.mat和ucm.mat文件转h5文件时,mat文件的读取有两种方式,尝试了scipy的io模块和h5py模块,其中如果保存的mat文件时用的matlab指定的-v7.3(如步骤2中run_ucm.py中最后一行save(‘ucm.mat’,‘ucms’,‘names’,’-v7.3’)😉,则scipy的io读取会报错,解决方法就是统一用h5py读取mat文件(参考1,2);有时候scipy的io模块导入不了,解决方法

error

3、将多个图片拼成一张长图,我是用的是pinthemall工具,当然还有许多其他好用的图像拼接工具, 其中Shapecollage可以将图片拼成不同形状,甚至绘制自定义形状,而Collagelt则只能固定长方形(https://zhuanlan.zhihu.com/p/25151315);

v2-19206586ec0f3436c75e458a7e9a7892_720w

4、从代码和最后生成的效果上看,SynthText主要是根据depth图和seg图,主要将根据语料和文字频率生成的文字放到图片中的光滑区域,与实际场景图片中的文字出现的位置更加切合;

5、SynthText生成的框有char和word级别,没有sentence级别,因此如果是需要直接检测场景图片中的句子级别的(检测+识别),该工程需要额外修改,或者应该使用其他的工程;

6、该工程生成数据的过程比较繁琐,而且速度比较慢;

7、修改后的代码,因为自己生成的depth.h5中是单通道的,而官方的示例是多通道的,因此根据需要选择是否注释gen.py中112行(#depth = depth[:,:,1] ##use own data to 注释这一行)。

==============================================================================================================================================

 

一,运行demo

1, 下载SynthText 源码,链接地址如下: https://github.com/ankush-me/SynthText.git

 

    解压后,文件目录如下:

 

2,运行:

 

python gen.py --viz

 

这个文件会下载大概56M的文件,包括:

dset.h5:这是一个示例h5文件,其中包含一组5个图像及其深度和分割信息。

data/fonts:三个样本字体(我们可以添加更多的字体到这个文件夹,然后用他们的路径更新`fonts / fontlist.txt')。

data/newsgroup: 文本源(来自新闻组数据集)。

data/models/colors_new.cp:  从IIIT-5K字数据集学习本的颜色模型(前景/背景文本颜色模型)。

data/models:  其他cPickle文件;

 

这个脚本输出结果为: results/SynthText.h5

 

二,生成文本检测数据集

 

1 , 预处理的背景图像

下载本文中使用的8000个背景图像,以及它们的分割和深度模板,下载链接地址如下:

`http://zeus.robots.ox.ac.uk/textspot/static/db/ <filename>`,其中``文件名``是:
 

- “imnames.cp”[180K]:已过滤文件的名称,即,这些文件不包含文本;

- `bg_img.tar.gz` [8.9G]:压缩的图像文件(超过8000,所以只能使用imnames.cp中的过滤的文件)

- “depth.h5”[15G]:深度图

- `seg.h5` [6.9G]:分割图

2 ,生成dset.h5文件

将下载的图片文件bg_img.tar.gz,解压到bg_img文件夹, 新建一个Python文件,命名为makeDset.py,将makeDset.py与bg_img图片文件夹,depth.h5,seg.h5 放在同一个文件夹下。

makeDset.py代码如下:

# -*- coding: UTF-8 -*-     
import numpy as np
import h5py
import os, sys, traceback
import os.path as osp
import matplotlib.image as mpimg
 
ImageListDir='imagesName.txt'
ImagesDir='bg_img/'
 
seg_db = h5py.File('seg.h5','r')
depth_db = h5py.File('depth.h5','r')
db = h5py.File('dset.h5','w')  
 
input = open(ImageListDir, 'r')  #将图片、seg文件、depth文件写入.h5w文件
imagesName = input.readlines()
 
image=db.create_group("image")
depth=db.create_group("depth")
seg=db.create_group("seg")
num=0
for name in seg_db['mask']:
    name=name.rstrip("\n")
    try:
        img = mpimg.imread(ImagesDir+name)
        d=depth_db[name][:]
        s=seg_db['mask'][name][:]
    except:
        continue
    image[name]=img
    s_max=np.amax(s)
    label=range(1,s_max+1)
    area=range(1,s_max+1)
    for i in label:
        area[i-1]=int(np.sum(s==i))
    depth[name]=d
    seg[name]=s
    seg[name].attrs['area']=area
    seg[name].attrs['label']=label
 
    num=num+1
    print num
    print name + 'is ok!\n'
 
db.close()
seg_db.close()
depth_db.close()

 


3,运行makeDset.py

 

python makeDset.py

 

在makeDset.py,同级目录下生成dset.h5文件。

4 ,生成SynthText.h5 

将生成的dset.h5文件放到SynthText /data文件夹下;运行gen.py文件:

 

python gen.py --viz

 

脚本输出结果为: results/SynthText.h5 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值