Пример #1
0
def mask_page(title: str, page_no: int) -> Optional[np.ndarray]:
    data = annotations(title, page_no)
    img = cv2.imread(
        op.join(root, "manga109", "images", title, f"{page_no:03d}.jpg"))
    mask = np.full((img.shape[0], img.shape[1]), 255, dtype=np.uint8)
    if "text" not in data:
        return
    text_boxes = data["text"]
    if isinstance(text_boxes, list):
        for box in text_boxes:
            x1 = box["@xmin"]
            y1 = box["@ymin"]
            x2 = box["@xmax"]
            y2 = box["@ymax"]
            points = np.array([[x1, y1], [x1, y2], [x2, y2], [x2, y1]],
                              dtype=np.int32)
            cv2.fillPoly(mask, [points], (0, 0, 0))
    else:
        x1 = text_boxes["@xmin"]
        y1 = text_boxes["@ymin"]
        x2 = text_boxes["@xmax"]
        y2 = text_boxes["@ymax"]
        points = np.array([[x1, y1], [x1, y2], [x2, y2], [x2, y1]],
                          dtype=np.int32)
        cv2.fillPoly(mask, [points], (0, 0, 0))
    fg = cv2.bitwise_or(img, img, mask=mask)

    background = np.full(img.shape, 255, dtype=np.uint8)
    mask = cv2.bitwise_not(mask)
    bk = cv2.bitwise_or(background, background, mask=mask)
    final = cv2.bitwise_or(fg, bk)
    return final
Пример #2
0
def page_annotations_visual(title: str, page_no: int) -> Optional[np.ndarray]:
    data = annotations(title, page_no)
    img = cv2.imread(
        op.join(root, "manga109", "images", title, f"{page_no:03d}.jpg"))

    if "text" not in data and "frame" not in data:
        return
    frames = data["frame"]
    text_boxes = data["text"]
    if not isinstance(text_boxes, list):
        text_boxes = [text_boxes]

    for box in text_boxes:
        x1 = int(box["@xmin"])
        y1 = int(box["@ymin"])
        x2 = int(box["@xmax"])
        y2 = int(box["@ymax"])
        cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2)

    if not isinstance(frames, list):
        frames = [frames]
    for box in frames:
        x1 = int(box["@xmin"])
        y1 = int(box["@ymin"])
        x2 = int(box["@xmax"])
        y2 = int(box["@ymax"])
        cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
    mid = img.shape[1] // 2
    cv2.rectangle(img, (mid - 100, 0), (mid + 100, img.shape[0]), (0, 0, 225))
    return img
Пример #3
0
def text_in_frames(title, page_no) -> Dict[str, List[Dict[str, Any]]]:
    data = annotations(title, page_no)
    texts = data["text"]
    if not isinstance(texts, list):
        texts = [texts]
    if "frame" not in data:
        return {"-1": [text for text in texts]}
    frames = data["frame"]
    if not isinstance(frames, list):
        frames = [frames]
    for i in range(len(frames)):
        frames[i]["boxtopleft"] = (int(frames[i]["@xmin"]),
                                   int(frames[i]["@ymin"]))
        frames[i]["boxbotright"] = (int(frames[i]["@xmax"]),
                                    int(frames[i]["@ymax"]))
    frames_to_text = {frame["@id"]: [] for frame in frames}
    for text in texts:
        text_topleft = (int(text["@xmin"]), int(text["@ymin"]))
        text_botright = (int(text["@xmax"]), int(text["@ymax"]))
        areas = {frame["@id"]: 0 for frame in frames}
        for frame in frames:
            frame_topleft = frame["boxtopleft"]
            frame_botright = frame["boxbotright"]
            SI = max(0, min(text_botright[0], frame_botright[0]) - max(text_topleft[0], frame_topleft[0])) * \
                 max(0, min(text_botright[1], frame_botright[1]) - max(text_topleft[1], frame_topleft[1]))
            areas[frame["@id"]] = SI
        best_frame = max(areas.items(), key=operator.itemgetter(1))[0]
        if areas[best_frame] == 0:
            continue
        frames_to_text[best_frame].append(text)
    return frames_to_text
Пример #4
0
def frame_order(title, page_no) -> List[str]:
    data = annotations(title, page_no)
    text = text_in_frames(title, page_no)
    if "frame" not in data:
        return ["-1"]
    frames = data["frame"]
    if not isinstance(frames, list):
        frames = [frames]
    if title in yonkoma:
        return _frame_order_yonkoma(frames)
    frames = [f for f in frames if len(text[f["@id"]]) > 0]

    if len(frames) == 0:
        return ["-1"]

    if frame_crosses_middle(title, page_no):
        return _frame_order(frames)
    midpoint = find_midpoint(title, page_no)
    right_page_frames = []
    left_page_frames = []
    for frame in frames:
        topright_x = int(frame["@xmax"])
        # Have a small buffer to fix pixel errors
        if topright_x > midpoint + 50:
            right_page_frames.append(frame)
        else:
            left_page_frames.append(frame)
    return _frame_order(right_page_frames) + _frame_order(left_page_frames)
Пример #5
0
def frame_crosses_middle(title, page_no) -> Optional[bool]:
    data = annotations(title)
    img = cv2.imread(
        op.join(root, "manga109", "images", title, f"{page_no:03d}.jpg"))
    mid = img.shape[1] / 2
    if "frame" not in data["book"]["pages"]["page"][page_no]:
        return
    frames = data["book"]["pages"]["page"][page_no]["frame"]
    if not isinstance(frames, list):
        frames = [frames]
    for box in frames:
        x1 = int(box["@xmin"])
        x2 = int(box["@xmax"])
        if x1 < mid - 75 < mid + 75 < x2:
            return True
    return False
Пример #6
0
def get_pages(with_text: bool = False, exclude: Optional[List[str]] = None, include: Optional[List[str]] = None) -> \
        List[Tuple[str, int]]:
    assert exclude is None or include is None
    if exclude is None:
        exclude = []
    result = []
    books = get_books() if include is None else include
    for book in books:
        if book in exclude:
            continue
        data = annotations(book)
        num_pages = len(data["book"]["pages"]["page"])
        for i in range(num_pages):
            if with_text:
                if "text" not in data["book"]["pages"]["page"][i]:
                    continue
                if (book, i) in degeneracies:
                    continue
            result.append((book, i))
    return result