Exemplo n.º 1
0
def test_init_itemcomp():
    i = item.Item()
    assert isinstance(i.item, ItemComponent)
Exemplo n.º 2
0
def test_init__is_Entity():
    i = item.Item()
    assert isinstance(i, entity.Entity)
Exemplo n.º 3
0
def test_init_renderorder():
    i = item.Item()
    assert i.render_order == RenderOrder.ITEM
Exemplo n.º 4
0
def test_init_blocks_movement():
    i = item.Item()
    assert i.blocks_movement is False
Exemplo n.º 5
0
def test_init_color():
    i = item.Item()
    assert i.color == (255, 255, 255)
Exemplo n.º 6
0
def test_init_default_components():
    i = item.Item()
    assert i.x == -1
    assert i.y == -1
Exemplo n.º 7
0
def new_data() -> None:
    """
    Function for generating images and XML markup and storing this data in the directories specified in the config file
    :return: None
    """
    # array with full parameters for each class
    item = []
    random.seed()

    # getting class names and their number from a file
    with open(config.file_with_classnames, 'r') as file:
        for line in file:
            str_ = line.split(' ')
            name = str_[0]
            count = str_[1][:-1]
            item.append(it.Item(name, count))

    # function for converting the source instances of each class to the initial dimensions
    change_size(item)

    # current class number
    index = 0

    # creating a variable responsible for the file number
    _count_ = 1
    print('\n*****Create image and xml for pix: *****')
    number_classes = len(item)

    # the list of accounting for the number of elements of each class
    list_count_of_each_class = [0] * number_classes
    progress_count = 0

    # counter of the total number of objects in the future dataset
    count_of_image = 0
    name_to_xml = str(_count_)

    # cycle through all class parameters
    for x in item:
        count_of_image += int(x.count)
    bar = progressbar.ProgressBar(maxval=count_of_image,
                                  widgets=config.widgets).start()

    # flag that is responsible for stopping the formation of the dataset
    flag = True

    # cycle for creating a dataset
    while flag:
        # a tuple that stores the size of an image
        size_ = (config.image_size['width'], config.image_size['height'])

        # creating an xml file
        root = Element("annotation")
        file = SubElement(root, "filename")
        file.text = str(name_to_xml + '.jpg')
        path = SubElement(root, "path")
        path.text = str(
            f'{config.dir_output_data}/{config.dir_result_img}/{name_to_xml}.jpg'
        )
        size_tree = SubElement(root, "size")
        width = SubElement(size_tree, "width")
        width.text = str(int(size_[0]))
        height = SubElement(size_tree, "height")
        height.text = str(int(size_[1]))
        depth = SubElement(size_tree, "depth")
        depth.text = "3"

        # creating auxiliary arrays
        object_, name, xmin_, xmax_, ymax_, ymin_, bndbox = [], [], [], [], [], [], []

        # creating a new image with the specified dimensions and a black background
        img = Image.new(
            "RGB", (config.image_size['width'], config.image_size['height']),
            '#191919')

        # flag that controls the fullness of the dataset
        flag_end = True

        # variable responsible for the number of files created
        end_file = 0

        # auxiliary variable for accessing arrays for xml markup
        number = 0

        # creating a matrix for the location of class objects
        matrix = create_matrix()

        # checking for boundary conditions
        while flag_end:
            end = 0
            if index >= number_classes:
                index = 0
            if list_count_of_each_class[index] >= int(item[index].count):
                while list_count_of_each_class[index] >= int(
                        item[index].count):
                    index += 1
                    end += 1
                    if index == number_classes:
                        index = 0
                    if end == number_classes:
                        flag = False
                        break
            if not flag:
                break

            coeff_orientation = None

            # orientation check to generate the orientation coefficient
            if item[index].orientation == 0:  # original
                coeff_orientation = 1
            # elif(item[index].orientation == 1): # horizontal
            #     coeff_orientation = random.randrange(70, 80, 1) / 100
            # elif(item[index].orientation == 2): # vertical
            #     coeff_orientation = 100 / random.randrange(70, 80, 1)

            # if (item[index].current_size[1] + item[index].config.step_change_size <= item[index].size_finish[1]):
            #     item[index].orientation = (item[index].orientation + 1 if (item[index].orientation < 2) else 0)

            # the number of occupied cells in the matrix by width
            count_of_x_boxes_item = int((
                item[index].current_size[1] // config.step['width'] +
                1) if item[index].current_size[1] % config.step['width'] > 0
                                        else int(item[index].current_size[1] //
                                                 config.step['width']))

            # the number of occupied cells in the matrix by height
            count_of_y_boxes_item = int((
                item[index].current_size[0] // config.step['height'] +
                1) if item[index].current_size[0] % config.step['height'] > 0
                                        else int(item[index].current_size[0] //
                                                 config.step['height']))

            # the path to the prepared image of the class object
            full_file_name = os.path.join(config.work_dir,
                                          config.dir_output_data,
                                          config.dir_prepare_boxes,
                                          f'{item[index].name}.png')

            # the path to the prepared image of the class object opening the image and converting to RGBA
            button = Image.open(full_file_name).convert("RGBA")

            # flag for determining whether an object of the class will be added to the image
            done_item_box = False

            # cycle through the matrix in height
            for i in range(4):
                global j

                # cycle through the matrix in width
                for j in range(4):

                    # flag for adding a class object to an image
                    is_fit = True

                    # checking that an object of the class with the new dimensions is placed on the image
                    if (count_of_x_boxes_item + j <
                            5) and (count_of_y_boxes_item + i < 5):

                        # cycle through the allowed cells in height
                        for y in range(i, i + count_of_y_boxes_item):

                            # cycle through the allowed cells in width
                            for x in range(j, j + count_of_x_boxes_item):

                                # checking that the cells of the matrix in which we want to place the object are free
                                if matrix[y, x] > 0:
                                    # we transfer the flag to the stage of the impossibility of adding it
                                    is_fit = False
                                    break
                            if not is_fit:
                                break

                        # checking whether an object of the class can be added to the image
                        if is_fit:

                            # cycle through the allowed cells in height
                            for y in range(i, i + count_of_y_boxes_item):

                                # cycle through the allowed cells in width
                                for x in range(j, j + count_of_x_boxes_item):
                                    # note in the matrix that these cells are filled in
                                    matrix[y, x] = 1

                            # setting the flag for adding a class object to the true state
                            done_item_box = True
                            break

                # checking whether an object of the class can be added to the image
                if done_item_box:

                    # resetting the variable number of filled files
                    end_file = 0

                    # the width of the area required for the class object
                    width = (j + count_of_x_boxes_item) * config.step['width']

                    # the height of the area required for the class object
                    height = (i +
                              count_of_y_boxes_item) * config.step['height']

                    # offset from the edge
                    random_indent = random.randrange(
                        5, 15, 5) if ((item[index].current_size[1] == 100) or
                                      (item[index].current_size[1] == 120)
                                      ) else random.randrange(20, 40, 5)

                    width_min, height_min, width_max, height_max = None, None, None, None
                    # checking that the class object should be shifted to the upper-left corner relative to the start
                    # cell
                    if item[index].current_position == 1:
                        width_min = width - count_of_x_boxes_item * config.step[
                            'width'] + random_indent
                        height_min = height - count_of_y_boxes_item * config.step[
                            'height'] + random_indent
                        width_max = width - count_of_x_boxes_item * config.step[
                            'width'] + item[index].current_size[
                                1] + random_indent
                        height_max = height - count_of_y_boxes_item * config.step[
                            'height'] + item[index].current_size[
                                0] + random_indent
                        item[index].current_position += 1

                    # checking that the class object should be shifted to the upper-right corner relative to the start
                    # cell
                    elif item[index].current_position == 2:
                        width_min = width - item[index].current_size[
                            1] - random_indent
                        height_min = height - count_of_y_boxes_item * config.step[
                            'height'] + random_indent
                        width_max = width - random_indent
                        height_max = height - count_of_y_boxes_item * config.step[
                            'height'] + item[index].current_size[
                                0] + random_indent
                        item[index].current_position += 1

                    # checking that the class object should be shifted to the lower-left corner relative to the start
                    # cell
                    elif item[index].current_position == 3:
                        width_min = width - count_of_x_boxes_item * config.step[
                            'width'] + random_indent
                        height_min = height - item[index].current_size[
                            0] - random_indent
                        width_max = width - count_of_x_boxes_item * config.step[
                            'width'] + item[index].current_size[
                                1] + random_indent
                        height_max = height - random_indent
                        item[index].current_position += 1

                    # checking that the class object should be shifted to the lower-right corner relative to the start
                    # cell
                    elif item[index].current_position == 4:
                        width_min = width - item[index].current_size[
                            1] - random_indent
                        height_min = height - item[index].current_size[
                            0] - random_indent
                        width_max = width - random_indent
                        height_max = height - random_indent
                        item[index].current_position += 1

                    # checking that the class object should be shifted to the center part relative to the start cell
                    elif item[index].current_position == 5:
                        width_min = width - count_of_x_boxes_item * config.step['width'] / 2 - \
                                    item[index].current_size[1] / 2
                        height_min = height - count_of_y_boxes_item * config.step['height'] / 2 - \
                                     item[index].current_size[0] / 2
                        width_max = width - count_of_x_boxes_item * config.step['width'] / 2 + \
                                    item[index].current_size[1] / 2
                        height_max = height - count_of_y_boxes_item * config.step['height'] / 2 + \
                                     item[index].current_size[0] / 2
                        item[index].current_position = 1

                    progress_count += 1
                    bar.update(progress_count)

                    # filter for resizing an image
                    resample = Image.ANTIALIAS
                    button.load()

                    # splitting an image into strips (R, G, B, A)
                    bands = button.split()

                    # getting new object sizes
                    dim = (int(width_max - width_min),
                           int(height_max - height_min))

                    # converting each color-light strip of the image to a new size
                    bands = [b.resize(dim, resample) for b in bands]

                    # combining all the stripes into a single image
                    button = Image.merge('RGBA', bands)

                    # inserting the resulting class object into the image
                    img.paste(button, (int(width_min), int(height_min)),
                              button)

                    # adding a class name to xml
                    object_.append(SubElement(root, "object_"))
                    name.append(SubElement(object_[number], "name"))
                    name[number].text = str(item[index].name)
                    bndbox.append(SubElement(object_[number], "bndbox"))
                    xmin_.append(SubElement(bndbox[number], "xmin"))
                    xmin_[number].text = str(int(width_min))
                    ymin_.append(SubElement(bndbox[number], "ymin"))
                    ymin_[number].text = str(int(height_min))
                    xmax_.append(SubElement(bndbox[number], "xmax"))
                    xmax_[number].text = str(int(width_max))
                    ymax_.append(SubElement(bndbox[number], "ymax"))
                    ymax_[number].text = str(int(height_max))

                    # increasing the number of added objects for the current class
                    list_count_of_each_class[index] += 1

                    # increasing the auxiliary variable by 1
                    number += 1

                    # getting a new object height
                    height_current = (item[index].current_size[1] + item[index].step_change_size) * \
                                     item[index].current_size[0] / item[index].current_size[1]

                    # getting a new object width
                    item[index].current_size[1] = (
                        item[index].current_size[1] +
                        item[index].step_change_size
                        if item[index].current_size[1] +
                        item[index].step_change_size <=
                        item[index].size_finish[1] else
                        item[index].size_start[1])

                    # checking that the current width is equal to the initial width
                    if item[index].current_size[1] == item[index].size_start[
                            1]:
                        height_current = item[index].size_start[0]

                    # getting the height
                    item[index].current_size[
                        0] = height_current * coeff_orientation
                    break

            # checking that the class object did not fit into the file
            if not done_item_box:
                end_file += 1

            # checking that the number of filled files == the number of classes
            if end_file == number_classes:
                flag_end = False

            # moving the class number variable to the next class
            index += 1

        # saving the image
        img.save(
            os.path.join(config.work_dir, config.dir_output_data,
                         config.dir_result_img, f'{str(_count_)}.jpg'))

        # path to the xml file
        name_ = os.path.join(config.work_dir, config.dir_output_data,
                             config.dir_result_xml, f'{str(_count_)}.xml')

        # calling the function that saves the xml file
        save_xml(name_, root)

        # increasing the file number by 1
        _count_ += 1
    bar.finish()