opencv 读图与labelimg读图方式区别

最近公司搞了一个项目,发动了几个员工每人用手机拍摄水果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保存出来的图片是灰度的具体原因没去追究

反正跑完之后,训练就不会报错了

上一篇:labelimg标注数据处理以及画散点图(python)


下一篇:Ubuntu系统python3安装LabelImg