最近公司搞了一个项目,发动了几个员工每人用手机拍摄水果50张图片,其中安卓和苹果都有
图片到手后,标注完成之后发现训练过程中报错,说flter后坐标越界,就开始找问题,排除标注问题后
领导说是苹果和安卓手机存图方式不同的原因,检查过后发现的确苹果手机长宽和安卓正好相反
然后就开始一顿操作猛如虎啊,具体也就是opencv读进去再保存出来就发现苹果拍摄的图片长宽颠倒了
然后开始修改标注文件,坐标计算的我头晕,具体就是苹果的图片逆时针旋转了90度,好的代码也贴上来
但是!!!!!脚本跑完全部数据后发现正方形的图片数据有的旋转了180度有的没有旋转,我们一开始只关注长宽不一样的图片
#coding=utf-8 ''' @author: Shang Tongtong @license: (C) Copyright 2019-present, SeetaTech, Co.,Ltd. @contact: tongtong.shang@seetatech.com @file: split_apple_android_pic_and_xml.py @time: 19-11-13 16:24 @desc: 根据图片长宽把苹果手机和安卓手机拍摄的图片分开处理,苹果手机图片长宽和安卓正好相反,在linux系统使用opencv读取再保存,即可旋转过来 windows中还要逆时针旋转90度,然后再根据xml文件中的长宽来区分到底是苹果安卓从而改变xml文件中图片长宽以及框的坐标值 ''' import cv2 as cv import os import xml.etree.ElementTree as ET def walk_dir(suffix, *paths): dir_map = [] for path in paths: for (root, dirs, files) in os.walk(path): for item in files: if item.endswith(suffix): dir_map.append(item) return dir_map def change_xml_box(nxmlpath, xmlpath, sp): tree = ET.parse(xmlpath) root = tree.getroot() ### get xml wh and if change wh = [] width = root.iter('width') for w in width: wh.append(w.text) height = root.iter('height') for h in height: wh.append(h.text) if wh[0] >= wh[1]: width = root.iter('width') for w in width: w.text = str(sp[1]) height = root.iter('height') for h in height: h.text = str(sp[0]) for box in root.iter('bndbox'): ###read ord = [] for xmin in box.iter('xmin'): ord.append(xmin.text) #print(xmin.text) for ymin in box.iter('ymin'): ord.append(ymin.text) for xmax in box.iter('xmax'): ord.append(xmax.text) for ymax in box.iter('ymax'): ord.append(ymax.text) ####rewrite for xmin in box.iter('xmin'): xmin.text = str(sp[1]-int(ord[1])) # print(xmin.text) for ymin in box.iter('ymin'): ymin.text = ord[2] for xmax in box.iter('xmax'): xmax.text = str(sp[1]-int(ord[3])) for ymax in box.iter('ymax'): ymax.text = ord[0] tree.write(nxmlpath, encoding="utf-8", xml_declaration=True) else: tree.write(nxmlpath, encoding="utf-8", xml_declaration=True) def s_image(picture_name, input_dir, output_dir, raw_xml, xml): srcImage = cv.imread(input_dir + picture_name) print(srcImage.shape) cv.imwrite(output_dir + picture_name, srcImage) newxml_path = os.path.join(xml + picture_name.split('.')[0] + '.xml') raw_xml_path = os.path.join(raw_xml + picture_name.split('.')[0] + '.xml') sp = srcImage.shape print(sp) change_xml_box(newxml_path, raw_xml_path, sp) if __name__ == '__main__': IMAGE_DIR = r'/media/haohao/Data-2/data/fruit/test/raw_img/' raw_xml = r'/media/haohao/Data-2/data/fruit/test/raw_xml/' xml = r'/media/haohao/Data-2/data/fruit/test/xml/' OUTPUT_DIR = r'/media/haohao/Data-2/data/fruit/test/img/' IMAGE_path = walk_dir('jpg', IMAGE_DIR) for i in IMAGE_path: s_image(i, IMAGE_DIR, OUTPUT_DIR, raw_xml, xml)
那么,这其实是没人拍照的时候手机方向不同的原因啊
然后开始探究opencv读图究竟和labelimg到底有啥区别,感谢啊https://blog.csdn.net/xuan_xuan_/article/details/100295306
发现其实opencv读图会关注拍照方向即orientation这个参数,然后给正过来,而labelimg并不会,所以用opencv不必关注这个参数保存一下图片即可
具体代码:srcImage = cv2.imread(input_dir + picture_name, cv2.IMREAD_IGNORE_ORIENTATION|cv2.IMREAD_COLOR)
如果不写IMREAD_COLOR保存出来的图片是灰度的具体原因没去追究
反正跑完之后,训练就不会报错了