import cv2 import numpy as np from os import path, listdir __all__ = [ "sorted_boxes", "get_rotate_crop_image", "get_min_area_rect_crop", "get_image_file_list", "check_and_read" ] def sorted_boxes(dt_boxes): num_boxes = dt_boxes.shape[0] _sorted_boxes = sorted(dt_boxes, key=lambda x: (x[0][1], x[0][0])) _boxes = list(_sorted_boxes) for i in range(num_boxes - 1): for j in range(i, -1, -1): if abs(_boxes[j + 1][0][1] - _boxes[j][0][1]) < 10 and (_boxes[j + 1][0][0] < _boxes[j][0][0]): tmp = _boxes[j] _boxes[j] = _boxes[j + 1] # noqa _boxes[j + 1] = tmp else: break return _boxes def get_rotate_crop_image(img, points): """ img_height, img_width = img.shape[0:2] left = int(np.min(points[:, 0])) right = int(np.max(points[:, 0])) top = int(np.min(points[:, 1])) bottom = int(np.max(points[:, 1])) img_crop = img[top:bottom, left:right, :].copy() points[:, 0] = points[:, 0] - left points[:, 1] = points[:, 1] - top """ assert len(points) == 4, "shape of points must be 4*2" img_crop_width = int(max(np.linalg.norm(points[0] - points[1]), np.linalg.norm(points[2] - points[3]))) img_crop_height = int(max(np.linalg.norm(points[0] - points[3]), np.linalg.norm(points[1] - points[2]))) pts_std = np.float32([[0, 0], [img_crop_width, 0], [img_crop_width, img_crop_height], [0, img_crop_height]]) M = cv2.getPerspectiveTransform(points, pts_std) # noqa dst_img = cv2.warpPerspective( # noqa img, M, (img_crop_width, img_crop_height), borderMode=cv2.BORDER_REPLICATE, flags=cv2.INTER_CUBIC # noqa ) dst_img_height, dst_img_width = dst_img.shape[0:2] if dst_img_height * 1.0 / dst_img_width >= 1.5: dst_img = np.rot90(dst_img) return dst_img def get_min_area_rect_crop(img, points): bounding_box = cv2.minAreaRect(np.array(points).astype(np.int32)) # noqa points = sorted(list(cv2.boxPoints(bounding_box)), key=lambda x: x[0]) # noqa if points[1][1] > points[0][1]: index_a = 0 index_d = 1 else: index_a = 1 index_d = 0 if points[3][1] > points[2][1]: index_b = 2 index_c = 3 else: index_b = 3 index_c = 2 box = [points[index_a], points[index_b], points[index_c], points[index_d]] crop_img = get_rotate_crop_image(img, np.array(box)) return crop_img def _check_image_file(file_path): img_end = ("jpg", "bmp", "png", "jpeg", "rgb", "tif", "tiff", "gif") return any([file_path.lower().endswith(e) for e in img_end]) def get_image_file_list(img_file): images = [] if img_file is None or not path.exists(img_file): raise Exception(f"not found any img file in {img_file}") if path.isfile(img_file) and _check_image_file(img_file): images.append(img_file) elif path.isdir(img_file): for single_file in listdir(img_file): file_path = path.join(img_file, single_file) if path.isfile(file_path) and _check_image_file(file_path): images.append(file_path) if len(images) == 0: raise Exception(f"not found any img file in {img_file}") images = sorted(images) return images def check_and_read(img_path): if path.basename(img_path)[-3:].lower() == "gif": gif = cv2.VideoCapture(img_path) # noqa ret, frame = gif.read() if not ret: print(f"Cannot read {img_path}. This gif image maybe corrupted.") return None, False if len(frame.shape) == 2 or frame.shape[-1] == 1: frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2RGB) # noqa img = frame[:, :, ::-1] return img, True return None, False