Beispiel #1
0
    def __init__(self,
                 manga109_root_dir,
                 year=2020,
                 version="",
                 book_limit=None,
                 page_limit=None,
                 add_manga109_info=False,
                 add_coco_info=True):
        """
        Parameters
        ----------
        add_manga109_info : bool
            include additional information out of original COCO format.
        add_coco_info : bool
            include information in original COCO format,
            but out of Manga109 Dataset.
            if set to False, COCO compatibility breaks.
        """
        self.book_limit = book_limit
        self.page_limit = page_limit
        self.add_manga109_info = add_manga109_info
        self.add_coco_info = add_coco_info

        self.parser = manga109api.Parser(root_dir=manga109_root_dir)
        self.init_coco_format_info(year=year, version=version)
        self.reset_converter()
def get_faces_for_yolo():
    manga109_root_dir = "Data"
    p = manga109api.Parser(root_dir=manga109_root_dir)
    j = 0
    for book_title in p.books:
        annotation = p.get_annotation(book=book_title)

        for i in range(0, len(annotation['page'])):

            img = Image.open(p.img_path(book=book_title, index=i))

            for annotation_type in ["face"]:

                j += 1
                rois = annotation["page"][i][annotation_type]

                f = open(f"Yolo_dataset/{j}.txt", "w+")

                for roi in rois:
                    w = (roi["@xmax"] - roi["@xmin"])
                    h = (roi["@ymax"] - roi["@ymin"])
                    x = roi['@xmin'] + ((roi["@xmax"] - roi["@xmin"]) / 2)
                    y = roi["@ymin"] + ((roi["@ymax"] - roi["@ymin"]) / 2)

                    x = round(x / img.size[0], 6)
                    y = round(y / img.size[1], 6)
                    w = round(w / img.size[0], 6)
                    h = round(h / img.size[1], 6)

                    f.write(f"1 {x} {y} {w} {h}\n")
                f.close()
                img.save(f"Yolo_dataset/{j}.jpg")
Beispiel #3
0
def test_img_path():
    manga109_root_dir = "tests/data_dummy/"
    p = manga109api.Parser(root_dir=manga109_root_dir)

    img1 = Path(p.img_path(book="TitleA", index=0)).absolute()
    img2 = Path("tests/data_dummy/images/TitleA/000.jpg").absolute()
    assert (img1 == img2)
Beispiel #4
0
def test_data_type():
    manga109_root_dir = "tests/data_dummy/"
    p = manga109api.Parser(root_dir=manga109_root_dir)

    for book in p.books:
        annotation = p.get_annotation(book=book)

        # title
        assert isinstance(annotation["title"], str)

        # character
        assert isinstance(annotation["character"], list)
        for character in annotation["character"]:
            assert isinstance(character["@id"], str)
            assert isinstance(character["@name"], str)

        # page
        assert isinstance(annotation["page"], list)
        for page in annotation["page"]:
            assert isinstance(page["@index"], int)
            assert isinstance(page["@width"], int)
            assert isinstance(page["@height"], int)

            for obj_type in {"body", "face", "frame", "text"}:
                assert isinstance(page[obj_type], list)
                for obj in page[obj_type]:
                    assert isinstance(obj["@id"], str)
                    assert isinstance(obj["@xmin"], int)
                    assert isinstance(obj["@xmax"], int)
                    assert isinstance(obj["@ymin"], int)
                    assert isinstance(obj["@ymax"], int)

                    if obj_type == "text":
                        assert isinstance(obj["#text"], str)
Beispiel #5
0
def test_data_type_separated():
    manga109_root_dir = "tests/data_dummy/"
    p = manga109api.Parser(root_dir=manga109_root_dir)

    for book in p.books:
        annotation = p.get_annotation(book=book, separate_by_tag=True)

        # title
        assert isinstance(annotation["title"], str)

        # character
        assert isinstance(annotation["character"], list)
        for character in annotation["character"]:
            assert isinstance(character["@id"], str)
            assert isinstance(character["@name"], str)

        # page
        assert isinstance(annotation["page"], list)
        for page in annotation["page"]:
            assert isinstance(page["@index"], int)
            assert isinstance(page["@width"], int)
            assert isinstance(page["@height"], int)

            for obj_type in page.keys():
                if obj_type in {"body", "face", "frame", "text"}:
                    assert isinstance(page[obj_type], list)
                    for obj in page[obj_type]:
                        assert isinstance(obj["@id"], str)
                        assert isinstance(obj["@xmin"], int)
                        assert isinstance(obj["@xmax"], int)
                        assert isinstance(obj["@ymin"], int)
                        assert isinstance(obj["@ymax"], int)
                        assert obj["type"] == obj_type

                        if obj_type == "text":
                            assert isinstance(obj["#text"], str)

                # custom tag test
                elif obj_type not in {"@index", "@width", "@height"}:
                    for obj in page[obj_type]:
                        assert isinstance(obj["@id"], str)
                        assert isinstance(obj["@attr_num"], int)
                        assert isinstance(obj["@attr_str"], str)
                        assert isinstance(obj["@attr_mix"], str)
                        assert obj["type"] == obj_type

                        for key in (obj.keys() - {
                                "@id", "@attr_num", "@attr_str", "@attr_mix",
                                "type"
                        }):
                            assert isinstance(obj[key], (int, str))

                        if "#text" in obj.keys():
                            assert isinstance(obj["#text"], str)
Beispiel #6
0
    def load(cls, path, **kwargs):
        os.makedirs('cache/manga', exist_ok=True)

        try:
            with open('cache/manga/data.json', 'r') as f:
                data = json.load(f)
        except:
            data = manga109api.Parser(root_dir=str(path))
            data = {'books': data.books, 'annotations': data.annotations}

            with open('cache/manga/data.json', 'w') as f:
                json.dump(data, f)

        try:
            with open('cache/manga/pages.json', 'r') as f:
                pages = json.load(f)
        except:
            pages = []

            for book in data['books']:
                for page in data['annotations'][book]['book']['pages']['page']:
                    pagedata = {
                        'text': [],
                        'path':
                        str(path / 'images' / book /
                            (str(page['@index']).zfill(3) + ".jpg"))
                    }
                    if 'text' in page:
                        for txt in page['text'] if isinstance(
                                page['text'], list) else [page['text']]:
                            pagedata['text'].append({
                                'xmin': txt['@xmin'],
                                'xmax': txt['@xmax'],
                                'ymin': txt['@ymin'],
                                'ymax': txt['@ymax'],
                                'text': txt['#text']
                            })
                    pages.append(pagedata)

            with open('cache/manga/pages.json', 'w') as f:
                json.dump(pages, f)

        return Manga109ImageList(
            list(filter(lambda x: len(x['text']) > 0, pages)), **kwargs)
Beispiel #7
0
    def __init__(
        self,
        manga109_root: str,
        titles,
        data_root: str = "dataset",
        exclude_others: bool = True,
        threshold: int = 0,
        transform=None,
    ) -> None:
        self.root = manga109_root
        self.data_root = data_root
        self.titles = titles
        self.transform = transform

        chara_others = set()
        with open(os.path.join(self.data_root, "others_ids.txt")) as f:
            for line in f:
                chara_others.add(line.rstrip())
        # obtain list of character ids and file paths
        chara_ids = list()
        self.paths = list()
        self.manga109_parser = manga109api.Parser(self.root)
        for title in self.titles:
            # We used the old version.
            annot = self.manga109_parser.get_annotation(
                title, annotation_type="annotations.v2018.05.31")
            for chara in annot["character"]:
                if exclude_others and chara["@id"] in chara_others:
                    continue

                chara_path = os.path.join(self.data_root, "images",
                                          chara["@id"])
                if not os.path.exists(chara_path):
                    continue
                paths = os.listdir(chara_path)
                if len(paths) < threshold:
                    continue
                self.paths += paths
                chara_ids += [chara["@id"]] * len(paths)

        self.classes = sorted(set(chara_ids))
        self.labels = [self.classes.index(id) for id in chara_ids]
        assert len(self.labels) == len(self.paths)
Beispiel #8
0
def main():
    arg_parser = argparse.ArgumentParser()
    arg_parser.add_argument("manga109dir")
    arg_parser.add_argument("--out", default="dataset/images", type=Path)
    args = arg_parser.parse_args()

    parser = manga109api.Parser(root_dir=args.manga109dir)
    books = list()
    for split in {"train", "val", "test"}:
        with open("dataset/{}_titles.txt".format(split)) as f:
            for line in f:
                books.append(line.rstrip())

    for book in tqdm.tqdm(books):
        annotation = parser.get_annotation(
            book=book, annotation_type="annotations.v2018.05.31")
        for page in annotation["page"]:
            name = "{:03d}.jpg".format(page["@index"])
            path = parser.root_dir / "images" / annotation["title"] / name
            # H, W, C
            page_img = cv2.imread(path.as_posix())
            for face in page["face"]:
                (args.out / face["@character"]).mkdir(exist_ok=True,
                                                      parents=True)

                # small face images are excluded.
                if (face["@xmax"] - face["@xmin"]) <= 30:
                    continue
                if (face["@ymax"] - face["@ymin"]) <= 30:
                    continue
                attrs = ("@xmin", "@ymin", "@xmax", "@ymax")
                bbox = [face[attr] for attr in attrs]
                bbox = expand_bbox(bbox, page["@width"], page["@height"])
                img = page_img[bbox[1]:bbox[3], bbox[0]:bbox[2], :]

                # NOTE: ".png" should be used
                save_path = args.out / face["@character"] / (face["@id"] +
                                                             ".jpg")
                cv2.imwrite(save_path.as_posix(), img)
Beispiel #9
0
import manga109api
from pprint import pprint
import cv2
import time
import os
from dotenv import load_dotenv
import numpy as np

load_dotenv()
TEST_RATIO = 0.1

manga109_root_dir = os.getenv('MANGA109_ROOT_DIR')
p = manga109api.Parser(root_dir=manga109_root_dir)

book_cnt = 0
os.system('rm -r face body')
os.mkdir('face/')
os.mkdir('body/')
face_train = open("face_training_set.txt", "w")
face_test = open("face_test_set.txt", "w")

for book in p.books:
    book_cnt += 1
    face_cnt = 0
    body_cnt = 0
    os.mkdir('face/' + str(book_cnt))
    os.mkdir('body/' + str(book_cnt))
    for page in p.annotations[book]["book"]["pages"]["page"]:
        img = cv2.imread(p.img_path(book=book, index=page["@index"]))

        if "face" in page.keys() and type(page["face"]) is list:
Beispiel #10
0
if __name__ == "__main__":
    ap = args_parser()
    manga109_root_dir = "manga109extracted"
    if not os.path.exists(manga109_root_dir):
        os.makedirs(manga109_root_dir)
    book = ap.book
    page_count = ap.pages
    file_count = [
        glob.glob(os.path.join(manga109_root_dir, '**', '*.*'), recursive=True)
    ]
    count = len(file_count[0])

    for page_index in range(page_count):
        tracker = 0
        p = manga109api.Parser(root_dir="Manga109s_data")
        annotation = p.get_annotation(book=book)
        img = Image.open(p.img_path(book=book, index=page_index))
        for annotation_type in [ap.annotation]:
            rois = annotation["page"][page_index][annotation_type]
            for roi in rois:
                cropped = img.crop(
                    (roi["@xmin"], roi["@ymin"], roi["@xmax"], roi["@ymax"]))
                image_x_dim, image_y_dim = cropped.size
                if ap.preprocess:
                    cropped = cropped.resize((ap.size, ap.size),
                                             Image.ANTIALIAS)
                if image_x_dim >= (ap.size / 2) and image_y_dim >= (ap.size /
                                                                    2):
                    cropped.save("manga109extracted/%s_%d.jpg" %
                                 (ap.book, count))
import argparse

import manga109api

arg_parser = argparse.ArgumentParser()
arg_parser.add_argument("root", help="/path/to/Manga109_20xx_xx_xx")
args = arg_parser.parse_args()

others_names = ["Others", "Other", "the other", "Other", "other", "Ohter"]
# for Buraritessen
others_names += ["Other(スリ)", "Other(赤穂浪士)", "Other(役人)", "Other(大吉屋の手下)"]

others_ids = list()
parser = manga109api.Parser(args.root)
for book in parser.books:
    annot = parser.get_annotation(book,
                                  annotation_type="annotations.v2018.05.31")
    for chara in annot["character"]:
        if chara["@name"] in others_names:
            others_ids.append(chara["@id"])

with open("dataset/others_ids.txt", "w") as f:
    for id in others_ids:
        f.write(id + "\n")
def get_annotation_dict(
        annotation_type='face',
        threshold_num=70,
        dict_len=200,
        manga109_dir='/Users/patrick/Documents/datasets/Manga109_2017_09_28',
        return_list=False):
    """
        :param annotation_type: face/body
        :param threshold_num: minimum number of this annotation type appears in a book
        :param dict_len: the length of return dict
        :param manga109_dir: the dir of manga109 dataset
        :param return_list: whether the type of return value is a list

        :return:  the annotation ordered dict in this format
        {
            'id_of_the_element': {
                '@count': int,
                '@book': book_name,
                'elements': [
                    {
                        '@page': int,
                        '@xmax': int,
                        '@xmin': int,
                        '@ymax': int,
                        '@ymin': int
                    },
                    ...
                ]
            }, 
            ...
        }
    """

    p = manga109api.Parser(root_dir=manga109_dir)

    books = p.books
    all_characters = {}

    for book_name in books:
        book = p.annotations[book_name]['book']

        characters = book['characters']['character']
        #     print(characters)
        characters_count = {}
        for char in characters:
            characters_count[char['@id']] = {
                '@count': 0,
                '@book': book_name,
                'elements': []
            }

        pages = book['pages']['page']

        for i in range(len(pages)):
            page = pages[i]
            if annotation_type not in page:
                continue
            # 不止有一个 face
            if type(page[annotation_type]) is type([]):
                for face in page[annotation_type]:
                    temp_dict = dict()
                    temp_dict['@page'] = i
                    temp_dict['@xmax'] = face['@xmax']
                    temp_dict['@xmin'] = face['@xmin']
                    temp_dict['@ymax'] = face['@ymax']
                    temp_dict['@ymin'] = face['@ymin']
                    characters_count[face['@character']]['elements'].append(
                        temp_dict)
                    characters_count[face['@character']]['@count'] += 1
            else:
                temp_dict = dict()
                temp_dict['@page'] = i
                temp_dict['@xmax'] = page[annotation_type]['@xmax']
                temp_dict['@xmin'] = page[annotation_type]['@xmin']
                temp_dict['@ymax'] = page[annotation_type]['@ymax']
                temp_dict['@ymin'] = page[annotation_type]['@ymin']
                characters_count[page[annotation_type]
                                 ['@character']]['elements'].append(temp_dict)
                characters_count[page[annotation_type]
                                 ['@character']]['@count'] += 1

        for key, val in characters_count.items():
            if val['@count'] >= threshold_num:
                all_characters[key] = val

    ordered_characters = OrderedDict()

    for key, val in all_characters.items():
        ordered_characters[key] = val

    ordered_characters = sorted(list(ordered_characters.items()),
                                key=lambda x: x[1]['@count'],
                                reverse=True)

    if return_list:
        return ordered_characters[:dict_len]

    return OrderedDict(ordered_characters[:dict_len])
def get_frame_dict(
        manga109_dir='/Users/patrick/Documents/datasets/Manga109_2017_09_28'):
    p = manga109api.Parser(root_dir=manga109_dir)

    books = p.books
    all_frames = {}
    frame_without_face = 0
    frame_without_body = 0

    for book_name in books:
        book = p.annotations[book_name]['book']

        pages = book['pages']['page']

        for i in range(len(pages)):
            page = pages[i]
            frame_list = []
            face_list = []
            body_list = []

            if 'frame' not in page:
                continue
            # 统一为 list,方便后面的处理
            if type(page['frame']) is type([]):
                frame_list.extend(page['frame'])
            else:
                frame_list.append(page['frame'])

            if 'face' in page:
                if type(page['face']) is type([]):
                    face_list.extend(page['face'])
                else:
                    face_list.append(page['face'])
            if 'body' in page:
                if type(page['body']) is type([]):
                    body_list.extend(page['body'])
                else:
                    body_list.append(page['body'])

            for frame in frame_list:
                # 初始化每个 frame
                frame_dict = dict()
                frame_dict['@book'] = book_name
                frame_dict['@page'] = i
                frame_dict['@xmax'] = frame['@xmax']
                frame_dict['@xmin'] = frame['@xmin']
                frame_dict['@ymax'] = frame['@ymax']
                frame_dict['@ymin'] = frame['@ymin']
                frame_dict['@body_count'] = 0
                frame_dict['@face_count'] = 0
                frame_dict['body'] = []
                frame_dict['face'] = []

                # 添加到返回的结果中
                all_frames[frame['@id']] = frame_dict

                # 把 face 和 body 添加到对应的 frame 之中
            for frame in frame_list:
                # 将 face 添加到对应的 frame 中
                for face in face_list:
                    if is_element_in_frame(frame, face):
                        all_frames[frame['@id']]['@face_count'] += 1
                        all_frames[frame['@id']]['face'].append(face)

                # 将 body 添加到对应的 frame 中
                for body in body_list:
                    if is_element_in_frame(frame, body):
                        all_frames[frame['@id']]['@body_count'] += 1
                        all_frames[frame['@id']]['body'].append(face)

            for frame in frame_list:
                if all_frames[frame['@id']]['@face_count'] == 0:
                    frame_without_face += 1
                if all_frames[frame['@id']]['@body_count'] == 0:
                    frame_without_body += 1

    print('all frames count:', len(all_frames))
    print('frames without face count:', frame_without_face)
    print('frames without body count:', frame_without_body)
    return all_frames
def crop_save(folder):

    try:
        os.makedirs(folder + 'train/B/')
        os.makedirs(folder + 'test/B/')
        os.makedirs(folder + 'train/A/')
        os.makedirs(folder + 'test/A/')
    except:
        pass

    counter = 0
    print('start prasing...')
    p = manga109api.Parser(root_dir=manga109_root_dir)
    print('end')
    for m in range(0, len(p.books)):
        print(p.books[m])
        for index in range(
                1,
                len(p.annotations[p.books[m]]['book']['pages']['page']) - 1):
            #print(p.books[m], index)
            try:
                imgright = Image.open(
                    p.img_path(book=p.books[m], index=2 * index))
                imgleft = Image.open(
                    p.img_path(book=p.books[m], index=2 * index + 1))
            except:
                continue

            width = imgleft.size[0]
            total_width = imgleft.size[0] + imgright.size[0]
            max_height = imgleft.size[1]
            new_im = Image.new('RGB', (total_width, max_height))
            new_im.paste(imgleft, (0, 0))
            new_im.paste(imgright, (width, 0))
            annotation_type = "frame"
            try:
                rois = p.annotations[p.books[m]]["book"]["pages"]["page"][
                    index][annotation_type]
            except:
                continue
            #print(rois)
            if type(rois) is not list:
                rois = [rois]
            for roi in rois:
                #print(roi)
                xmin = roi["@xmin"]
                ymin = roi["@ymin"]
                xmax = roi["@xmax"]
                ymax = roi["@ymax"]
                width = (xmax - xmin)
                height = (ymax - ymin)
                ratio = width / height
                #print(width, height, ratio)
                if width < 768 and width > 256 and height > 256 and height < 768 and (
                        0.8 < ratio and ratio < 1.25):
                    #draw_rectangle(new_im,xmin,ymin,xmax,ymax, annotation_type)
                    #new_im.show()
                    counter += 1
                    box = (xmin + 10, ymin + 10, xmax - 20, ymax - 20)
                    cropped_image = new_im.crop(box)
                    #cropped_image.show()
                    if width < height:
                        cropped_image = cropped_image.resize(
                            (256, int(256 * height / width)))
                    else:
                        cropped_image = cropped_image.resize(
                            (int(256 * width / height), 256))

                    if counter % 10 == 0:
                        outf = folder + 'test/B/'
                    else:
                        outf = folder + 'train/B/'
                    result = np.array(cropped_image)
                    cv2.imwrite(outf + "{:05d}.jpg".format(counter), result)