python 多線程切圖

任務需求: 根據檢測框的座標將 大圖中的目標摳出來,存進指定目錄

目錄:  

  • 先看個例子

  • 再自己實現

    • 常規版本
    • 多線程版本

 

例子不表,詳情見

常規版本:


# -*- coding: utf-8 -*-

import os
import cv2
import time
import xml.etree.ElementTree as ET
import threading

def crop2train(im, crop_area, output_filename):
    x1, y1, x2, y2 = crop_area
    crop_im = im[y1:y2, x1:x2, :]
    cv2.imwrite(output_filename, crop_im)

def parse_rec(filename):
    tree = ET.parse(filename)
    objects = []
    for obj in tree.findall('object'):
        obj_struct = {}
        obj_struct['name'] = obj.find('name').text
        bbox = obj.find('bndbox')
        obj_struct['bbox'] = [int(float(bbox.find('xmin').text)),
                 int(float(bbox.find('ymin').text)),
                 int(float(bbox.find('xmax').text)),
                 int(float(bbox.find('ymax').text))]
        objects.append(obj_struct)
    return objects

def crop_img_from_xml(xmlPath, imgPath):
    _bbox = parse_rec(xmlPath)
    im = cv2.imread(imgPath)
    for bbox in _bbox:
        x1, y1, x2, y2 = bbox['bbox']
        output_filename = '{}_{}_{}_{}_{}.png'.format(os.path.join(output_dir, imgPath.strip().split('/')[-1].replace('.xml', '')), x1, y1, x2, y2)
        crop2train(im, bbox['bbox'], output_filename)

def main():
    s_ = time.time()

    global output_dir
    root_dir = '/data/del'

    xml_dir = os.path.join(root_dir, 'Annotations')
    img_dir = os.path.join(root_dir, 'JPEGImages')
    output_dir = os.path.join(root_dir, 'cropimg')
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    xml_list = os.listdir(xml_dir)

    for k, v in enumerate(xml_list):
        xmlPath = os.path.join(xml_dir, v)
        imgPath = os.path.join(img_dir, v.strip().replace('xml', 'jpg'))

        crop_img_from_xml(xmlPath, imgPath)

    print("all Done at: {}".format(time.time()-s_))

運行了兩次,時間如下:

all Done at: 12.306139469146729
all Done at: 12.506436347961426

 

多線程版本

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import cv2
import time
import xml.etree.ElementTree as ET
import threading

def crop2train(im, crop_area, output_filename):
    x1, y1, x2, y2 = crop_area
    crop_im = im[y1:y2, x1:x2, :]
    cv2.imwrite(output_filename, crop_im)

def parse_rec(filename):
    tree = ET.parse(filename)
    objects = []
    for obj in tree.findall('object'):
        obj_struct = {}
        obj_struct['name'] = obj.find('name').text
        bbox = obj.find('bndbox')
        obj_struct['bbox'] = [int(float(bbox.find('xmin').text)),
                 int(float(bbox.find('ymin').text)),
                 int(float(bbox.find('xmax').text)),
                 int(float(bbox.find('ymax').text))]
        objects.append(obj_struct)
    return objects

def crop_img_from_xml(xmlPath, imgPath):
    _bbox = parse_rec(xmlPath)
    im = cv2.imread(imgPath)
    for bbox in _bbox:
        x1, y1, x2, y2 = bbox['bbox']
        output_filename = '{}_{}_{}_{}_{}.png'.format(os.path.join(output_dir, imgPath.strip().split('/')[-1].replace('.xml', '')), x1, y1, x2, y2)
        crop2train(im, bbox['bbox'], output_filename)

def main():
    s_ = time.time()

    global output_dir
    root_dir = '/data/del'

    xml_dir = os.path.join(root_dir, 'Annotations')
    img_dir = os.path.join(root_dir, 'JPEGImages')
    output_dir = os.path.join(root_dir, 'cropimg')
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    xml_list = os.listdir(xml_dir)

    threads = []
    nloops = range(len(xml_list))

    for k, v in enumerate(xml_list):
        xmlPath = os.path.join(xml_dir, v)
        imgPath = os.path.join(img_dir, v.strip().replace('xml', 'jpg'))

        t = threading.Thread(target=crop_img_from_xml, args=(xmlPath, imgPath))
        threads.append(t)
        # crop_img_from_xml(xmlPath, imgPath)

    for i in nloops:
        threads[i].start()
    for i in nloops:  # 等待
        threads[i].join()  # 線程完成

    print("all Done at: {}".format(time.time()-s_))


if __name__ == "__main__":
    main()

 

運行了兩次,時間如下:
all Done at: 4.787922143936157
all Done at: 4.274227142333984

 

總的來說,時間提升3倍數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章