{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"#csv2xml\nimport numpy as np # linear algebra\nimport pandas as pd\n\npath = '/kaggle/working/annotation'\nos.makedirs(path) \nimport csv\nimport os, ast\nfrom xml.dom import minidom\n\n# 文件路径\nxml_dir = '/kaggle/working/annotation'\ncsv_filename = os.path.join('/kaggle/input/global-wheat-detection/', 'train.csv')\n# 逐行读取csv文件\ndef create_xml(filename, bboxs):\n    width = 1024\n    height = 1024\n    depth = 3\n    # 1.创建DOM树对象\n    dom = minidom.Document()\n    # 2.创建根节点。每次都要用DOM对象来创建任何节点。\n    root_node = dom.createElement('annotation')\n    # 3.用DOM对象添加根节点\n    dom.appendChild(root_node)\n\n    filename_node = dom.createElement('filename')\n    root_node.appendChild(filename_node)\n    # 也用DOM创建文本节点，把文本节点（文字内容）看成子节点\n    name_text = dom.createTextNode(filename)\n    # 用添加了文本的节点对象（看成文本节点的父节点）添加文本节点\n    filename_node.appendChild(name_text)\n\n    # size\n    size_node = dom.createElement('size')\n    root_node.appendChild(size_node)\n    width_node = dom.createElement('width')\n    height_node = dom.createElement('height')\n    depth_node = dom.createElement('depth')\n    # width\n    size_node.appendChild(width_node)\n    width_text = dom.createTextNode(str(width))\n    width_node.appendChild(width_text)\n    # height\n    size_node.appendChild(height_node)\n    height_text = dom.createTextNode(str(height))\n    height_node.appendChild(height_text)\n    # depth\n    size_node.appendChild(depth_node)\n    depth_text = dom.createTextNode(str(depth))\n    depth_node.appendChild(depth_text)\n\n    for bbox in bboxs:\n        # 创建obejct\n        object_node = dom.createElement('object')\n        root_node.appendChild(object_node)\n        # 创建类别name\n        name_node = dom.createElement('name')\n        name_text = dom.createTextNode('Wheat')\n        name_node.appendChild(name_text)\n        object_node.appendChild(name_node)\n        # 创建bndbox\n        # bbox [xmin, ymin, width, height]\n        bbox = ast.literal_eval(bbox)\n        xmin, ymin = bbox[0], bbox[1]\n        xmax, ymax = xmin + bbox[2], ymin + bbox[3]\n\n        bndbox = dom.createElement('bndbox')\n        object_node.appendChild(bndbox)\n        # xmin\n        xmin_node = dom.createElement('xmin')\n        xmin_text = dom.createTextNode(str(xmin))\n        xmin_node.appendChild(xmin_text)\n        bndbox.appendChild(xmin_node)\n        # ymin\n        ymin_node = dom.createElement('ymin')\n        ymin_text = dom.createTextNode(str(ymin))\n        ymin_node.appendChild(ymin_text)\n        bndbox.appendChild(ymin_node)\n        # xmax\n        xmax_node = dom.createElement('xmax')\n        xmax_text = dom.createTextNode(str(xmax))\n        xmax_node.appendChild(xmax_text)\n        bndbox.appendChild(xmax_node)\n        # ymax\n        ymax_node = dom.createElement('ymax')\n        ymax_text = dom.createTextNode(str(ymax))\n        ymax_node.appendChild(ymax_text)\n        bndbox.appendChild(ymax_node)\n\n    # 每一个结点对象（包括dom对象本身）都有输出XML内容的方法，如：toxml()--字符串, toprettyxml()--美化树形格式。\n    try:\n        with open(os.path.join(xml_dir, filename) + '.xml', 'w', encoding='UTF-8') as fh:\n            # 4.writexml()第一个参数是目标文件对象，第二个参数是根节点的缩进格式，第三个参数是其他子节点的缩进格式，\n            # 第四个参数制定了换行格式，第五个参数制定了xml内容的编码。\n            dom.writexml(fh, indent='', addindent='\\t', newl='\\n', encoding='UTF-8')\n#             print('写入xml OK!')\n    except Exception as err:\n        print('错误信息：{0}'.format(err))\ndef main():\n    with open(csv_filename, 'r', encoding=\"utf-8\") as csvfile:\n        reader = csv.DictReader(csvfile)\n        # 自动获取第一张照片的文件名，并设置为last_image\n        i = 0\n        for row in reader:\n            if i == 1:\n                last_image = row['image_id']\n                break\n            i += 1\n        # print(last_image)\n        img_num = 1\n        bboxs = []\n        for row in reader:\n            if row['image_id'] == last_image:\n                # 叠加bbox [xmin, ymin, width, height]\n                bboxs.append(row['bbox'])\n            elif row['image_id'] != last_image:\n                bboxs.append(row['bbox'])\n                # 创建xml文件\n                create_xml(last_image, bboxs)\n                last_image = row['image_id']\n                img_num += 1\n                # 重置bbox\n                bboxs.clear()\n\n        print(img_num)\nmain()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# 将xml文件数据进行读取\nimport os, glob\n\nos.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'\nimport numpy as np\nimport tensorflow as tf\nfrom tensorflow import keras\n\ntf.random.set_seed(2234)\nnp.random.seed(2234)\n\n# print(tf.__version__)\n# print(tf.test.is_gpu_available())\n\nobj_names = ('Wheat')\nimg_dir = '/kaggle/input/global-wheat-detection/train'\nann_dir = '/kaggle/working/annotation'\n\nimport xml.etree.ElementTree as ET\n\n# 1.1\ndef parse_annotation(img_dir, ann_dir, labels):\n    # img_dir: image path\n    # ann_dir: annotation xml file path\n    # labels: ('wheat')\n    # 从 annotation info from xml file\n    imgs_info = []\n    max_boxes = 0\n    for ann in os.listdir(ann_dir):\n        tree = ET.parse(os.path.join(ann_dir, ann))\n        img_info = dict()\n        img_info['object'] = []\n        boxes_counter = 0\n        for elem in tree.iter():\n\n            if 'filename' in elem.tag:\n                img_info['filename'] = os.path.join(img_dir, elem.text)\n            if 'width' in elem.tag:\n                img_info['width'] = int(elem.text)\n                assert img_info['width'] == 1024\n            if 'height' in elem.tag:\n                img_info['height'] = int(elem.text)\n                assert img_info['height'] == 1024\n\n            if 'object' in elem.tag or 'part' in elem.tag:\n                # x1-y1-x2-y2-label 左上角，右下脚坐标\n                object_info = [0., 0., 0., 0., 0.]\n                boxes_counter += 1\n                for attr in list(elem):\n                    if 'name' in attr.tag:\n                        label = labels.index(attr.text) + 1\n                        object_info[4] = label\n                    if 'bndbox' in attr.tag:\n                        for pos in list(attr):\n                            if 'xmin' in pos.tag:\n                                object_info[0] = float(pos.text)\n                            if 'ymin' in pos.tag:\n                                object_info[1] = float(pos.text)\n                            if 'xmax' in pos.tag:\n                                object_info[2] = float(pos.text)\n                            if 'ymax' in pos.tag:\n                                object_info[3] = float(pos.text)\n                img_info['object'].append(object_info)\n        imgs_info.append(img_info)  # filename,w/h/box_info\n        # (N,5) = (max_objects_num,5)\n        if boxes_counter > max_boxes:\n            max_boxes = boxes_counter\n        # the maximum boxes number is max_boxes\n    # [3372,116,5]\n    boxes = np.zeros([len(imgs_info), max_boxes, 5])\n    print(boxes.shape)\n    imgs = []  # filename list\n    for i, img_info in enumerate(imgs_info):\n        # [N,5]\n        img_boxes = np.array(img_info['object'])\n        # overwrite the N boxes info\n        boxes[i, :img_boxes.shape[0]] = img_boxes\n        imgs.append(img_info['filename']+'.jpg')\n    #         print(img_info['filename'], boxes[i:1])\n    # imgs :list of image path [b]\n    # boxes:[b,116,5]\n    return imgs, boxes\n\n\ndef preprocess(img, img_boxes):\n    # img:string\n    # img_boxes:[116,5]\n    x = tf.io.read_file(img)\n    x = tf.image.decode_png(x, channels=3)\n    x = tf.image.convert_image_dtype(x, tf.float32)\n    return x, img_boxes\n\n\n# 1.2\ndef get_dataset(img_dir, ann_dir, batchsz):\n    # return tf dataset\n    # [b],boxes[b,116,5]\n    imgs, boxes = parse_annotation(img_dir, ann_dir, obj_names)\n    db = tf.data.Dataset.from_tensor_slices((imgs, boxes))\n    db = db.shuffle(100).map(preprocess).batch(batchsz).repeat()\n    print('db_images', len(imgs))\n    return db\n\n\ntrain_db = get_dataset(img_dir, ann_dir, batchsz=64)\nprint(train_db)\n\n# 1.3 visual the db\nfrom matplotlib import pyplot as plt\nfrom matplotlib import patches\n\ndef db_visualize(db):\n    # [b,1024,1024,3]\n    # imgs_boxes [b,116,5]\n    imgs, imgs_boxes = next(iter(db))\n    #在这里设置你想查看的图像\n    img, img_boxes = imgs[10], imgs_boxes[10]\n    f, ax1 = plt.subplots(1)\n    # display the image,[1024,2014,3]\n    ax1.imshow(img)\n    for x1, y1, x2, y2, l in img_boxes:\n        x1, y1, x2, y2 = float(x1), float(y1), float(x2), float(y2)\n        w = x2 - x1\n        h = y2 - y1\n        if l == 1:\n            color = (0, 1, 0)\n        else:\n            break\n        rect = patches.Rectangle((x1, y1), w, h, linewidth=2, edgecolor=color, facecolor='none')\n        ax1.add_patch(rect)\n\n\ndb_visualize(train_db)\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}