图片在section上下居中_TensorFlow图片集自动标注

做过TENSORFLOW图像识别的都知道要有训练素材。

一般是IMG+XML

网上的教程有:手把手教你图片打标(手把手教你图片打标 - 陈茂林的技术博客 - CSDN博客)

不过这个是手动标识。

我算是手速度快的了,标注200个图片也花了近2个小时。

实在是痛苦!!!

后来看XML文件,就是要把被训练的物体从背景图中的位置(具体是XMIN,YMIN,XMAX,YMAX)标识出来。(其他参数暂时忽略)

得到上面4个值才是最终目的。

有了目的,实现的手段就不止于手动了,完全可以通过软件完成!

环境:

UBUNTU 18.04

OPENCV :4.0.0

PYTHON:2.7.15

VSC:1.31.1

先准备要训练的物体图片:

6efd583e0f3c9eb0522b541d8203d007.png

注意下:这个图片是处理过的,没有任何背景图。

再准备被插入的图片集:

3bd5ee6271a742b476db787441861828.png

这个是哈佛图书馆的一个包,原来有8000多张,取了前面的200张,文件名字也按顺序标注好了。

下面是代码部分:

1:获取被插入的图片集

path='/media/james/work/neg/'
f=os.listdir(path)
pathDir = os.listdir(path)

2:把训练图片插入

2.1读入训练图片

img2 = cv2.imread('/media/james/work/python/mouse.jpg')

2.2插入之前旋转:

def rotate_about_center(src, angle, scale=1.):
w = src.shape[1]
h = src.shape[0]
rangle = np.deg2rad(angle) # angle in radians
# now calculate new image width and height
nw = (abs(np.sin(rangle)*h) + abs(np.cos(rangle)*w))*scale
nh = (abs(np.cos(rangle)*h) + abs(np.sin(rangle)*w))*scale
# ask OpenCV for the rotation matrix
rot_mat = cv2.getRotationMatrix2D((nw*0.5, nh*0.5), angle, scale)
# calculate the move from the old center to the new center combined
# with the rotation
rot_move = np.dot(rot_mat, np.array([(nw-w)*0.5, (nh-h)*0.5,0]))
# the move only affects the translation, so update the translation
# part of the transform
rot_mat[0,2] += rot_move[0]
rot_mat[1,2] += rot_move[1]
return cv2.warpAffine(src, rot_mat, (int(math.ceil(nw)), int(math.ceil(nh))), flags=cv2.INTER_LANCZOS4)

img2=rotate_about_center(img2,angle,1.0)

2.3设置插入坐标:

x_pos=rows2/3+random.randint(-10,10)
y_pos=cols2/3+random.randint(-10,10)

rows2/3 cols2/3是让图片尽量居中,后面是上下左右随机偏移

2.4完成插入

roi = img1[x_pos:rows+x_pos,y_pos:cols+y_pos]
# Now create a mask of logo and create its inverse mask also
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)
# Now black-out the area of logo in ROI
img1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
# Take only region of logo from logo image.
img2_fg = cv2.bitwise_and(img2, img2, mask=mask)
# Put logo in ROI and modify the main image
dst = cv2.add(img1_bg, img2_fg)
img1[x_pos:rows+x_pos, y_pos:cols+y_pos] = dst

2.5获取XMAX,YMAX

def get_new_xmax(src, angle, scale=1.):
w = src.shape[1]
h = src.shape[0]
rangle = np.deg2rad(angle) # angle in radians
# now calculate new image width and height
nw = (abs(np.sin(rangle)*h) + abs(np.cos(rangle)*w))*scale
nh = (abs(np.cos(rangle)*h) + abs(np.sin(rangle)*w))*scale
return int(nw)

def get_new_ymax(src, angle, scale=1.):
w = src.shape[1]
h = src.shape[0]
rangle = np.deg2rad(angle) # angle in radians
# now calculate new image width and height
nw = (abs(np.sin(rangle)*h) + abs(np.cos(rangle)*w))*scale
nh = (abs(np.cos(rangle)*h) + abs(np.sin(rangle)*w))*scale
return int(nh)

注意:这段代码好像有问题,与实际ROI还要再计算一下。

3得到XML

我没有创造新XML,在原来LabelImg生成的XML上修改完成。

3.1读取原来XML

updateTree = ET.parse("/home/james/dataset/raccoon_dataset-master/annotations/test.xml")

3.2更新:

#update xml
sub1 = root.find("filename")
sub1.text = '/media/james/work/mouse/'+'mouse-'+allDir
sub2 = root.find("path")
sub2.text = '/media/james/work/mouse/'+'mouse-'+allDir
sub3 = root.find("size")
sub4 = sub3.find("width")
sub4.text = str(cols2)
sub5 = sub3.find("height")
sub5.text = str(rows2)
sub6 = root.find("object")
sub7 = sub6.find("name")
sub7.text = 'mouse'
sub8 = sub6.find("bndbox")
sub9 = sub8.find("xmin")
sub9.text = str(y_pos)
sub10 = sub8.find("ymin")
sub10.text = str(x_pos)
sub11 = sub8.find("xmax")
sub11.text = str(y_pos+new_xmax)
sub12 = sub8.find("ymax")
sub12.text = str(x_pos+new_ymax)

注意里面int要转为str

3.3保存:

xml_save= '/media/james/work/mouse_xml/'+'mouse-'+allDir[:-4]+'.xml'
updateTree.write(xml_save)

这样XML与图片名字就一一对应了。

结果:

1图片:mouse-40.jpg

e304359bc4e5f3118b9b5e1b849fd2b5.png

2:xml

fea0b67b76d38e86e82d40eff22e3e2e.png

tensorflow训练后的识别效果:

68809c6781f29741c5dbfde99376427b.png

('the count of objects is: ', 2)

0.9999951

('object0: hm6901028314145', ',Center_X:', 1091, ',Center_Y:', 1102)

0.99997866

('object1: bs6901028192729', ',Center_X:', 592, ',Center_Y:', 1752)

权当抛砖引玉,希望有兴趣的人把代码再优化下,让大家摆脱简单枯燥繁重的标注。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值