def make_circular(img: Image): """ Makes the given image circular :param img: Image opened with PIL.Image """ width, height = img.size result = Image.new(size=img.size, color=(0, 0, 0, 0), mode='RGBA') for y in range(height): # Get new width at this height relative_y = (y / height - 0.5) * 2 # Convert to value between -1 and +1 angle = math.asin(relative_y) relative_x = math.cos(angle) new_width = int(math.ceil(relative_x * width)) # Cut a strip at this height left, right = 0, width upper, lower = y, y + 1 box = (left, upper, right, lower) img_strip = img.crop(box) # Resize the strip img_resized = img_strip.resize(size=(new_width, 1)) # Paste the resized strip in place left = int(round(0.5 * (width - new_width))) upper = y box = (left, upper) result.paste(img_resized, box) return result
def identify_board(img: Image = None) -> Board: """OCR the (new) board represented in img. If img is None, a screenshot of the primary monitor - or, when available, the game window - is taken. img must represent a new game with the window in pixel-perfect scaling mode and contain only the contents of the game window """ if img is None: img = pyautogui.screenshot() # Find out how many times the game has been scaled up; note that the # fullscreen window gets a surrounding black border and so the game will # be scaled as many times as it can fit and then centred scale = min(img.width // GAME_RESOLUTION[0], img.height // GAME_RESOLUTION[1]) new_width, new_height = GAME_RESOLUTION[0] * scale, GAME_RESOLUTION[ 1] * scale # Get the bounds of the image centre left = (img.width - new_width) / 2 top = (img.height - new_height) / 2 right = (img.width + new_width) / 2 bottom = (img.height + new_height) / 2 # crop then resize the image img = img.crop((left, top, right, bottom)) img = img.resize(GAME_RESOLUTION).convert("1") return cast( Board, tuple(( [([ card for card, card_img in CARDS.items() if not ImageChops.difference( card_img, img.crop(( LEFT + COL_WIDTH * x, TOP + ROW_HEIGHT * y, LEFT + COL_WIDTH * x + CARD_WIDTH, TOP + ROW_HEIGHT * y + CARD_HEIGHT, )), ).getbbox() ] + ["?"])[0] for y in range(6)], False, ) for x in range(6)), )
def cut_pil_image_v_old(image: Image, border=20, spread=.05): w, h = image.size iw, ih = w - 2 * border, h - 2 * border dw, dh = int(iw * spread), int(ih * spread) return image.crop( (randint(border // 2, border + dw), randint(border // 2, border + dh), randint(w - border - dw, w - border // 2), randint(h - border - dh, h - border // 2)))
def generate_thumb(im: Image) -> Image: x, y = im.size while y > x: slice_height = min(y - x, 10) bottom = im.crop((0, y - slice_height, x, y)) top = im.crop((0, 0, x, slice_height)) if _image_entropy(bottom) < _image_entropy(top): im = im.crop((0, 0, x, y - slice_height)) else: im = im.crop((0, slice_height, x, y)) x, y = im.size gevent.sleep(0) im.thumbnail((70, 70), Image.ANTIALIAS) return im
def crop_center_image(img: PIL.Image, size: int) -> PIL.Image: """ crop center PIL-image """ w, h = img.size if size == w and size == h: return img else: return img.crop(((w - size) // 2, (h - size) // 2, (w + size) // 2, (h + size) // 2))
def cropimg(img: Image, bbox: Box, camera_intrinsic: np.ndarray) -> Image: bbox_img = view_points(bbox.corners(), view=camera_intrinsic, normalize=True) # in case the annotation runs off the edge of the page bbox_img[bbox_img < 0] = 0 bbox_img[0, bbox_img[0, :] > img.size[0]] = img.size[0]-1 bbox_img[1, bbox_img[1, :] > img.size[1]] = img.size[1]-1 # crop return img.crop((min(bbox_img[0]), min(bbox_img[1]), max(bbox_img[0]), max(bbox_img[1])))
def central_crop(img: Image) -> Image: w, h = img.size size = min(w, h) offset_h = int((h - size) / 2) offset_w = int((w - size) / 2) cropped = img.crop((offset_w, offset_h, offset_w + size, offset_h + size)) return cropped
def make_thumbnail(self, image: Image, ThumbnailSize=((100, 100))) -> Image: try: # Crop the image into a square if image.size[0] > image.size[1]: trim = (image.size[0] - image.size[1]) / 2 image = image.crop( (trim, 0, image.size[0] - trim, image.size[1])) if image.size[1] > image.size[0]: trim = (image.size[0] - image.size[1]) / 2 image = image.crop( (0, trim, image.size[1], image.size[0] - trim)) image.thumbnail(ThumbnailSize) return image except Exception as e: logging.error("Exception in Thumbnailer::make_thumbnail: %s" % str(e)) raise e
def rolling_an_image(self, image: Image, delta: int) -> Tuple[object, bool]: ''' rolll an image sideways ''' status = False try: xsize, ysize = image.size delta = delta % xsize if delta == 0: return (image, status) part1 = image.crop((0, 0, delta, ysize)) part2 = image.crop((delta, 0, xsize, ysize)) image.paste(part2, (0, 0, xsize-delta, ysize)) image.paste(part1, (xsize-delta, 0, xsize, ysize)) status = True except: status = False return (image, status)
def _crop_img(img: Image, person_range): """ 検出した人物の範囲(座標)に従ってトリミング :param Image img: :param tuple person_range: :return: """ # print(person_range) return img.crop(person_range)
def crop(image: Image, width: int, height: int, space: int) -> list: croppedImages = [] imgWidth, imageHeight = image.size for row in range(0, imageHeight, height + space): for column in range(0, imgWidth, width + space): crop = image.crop((column, row, column + width, row + height)) croppedImages.append(crop) return croppedImages
def extracts(cls, image: Image, return_bounding_boxes = False): faces_bounding_boxes, confidents = cls.model.detect(image) if faces_bounding_boxes is None or len(faces_bounding_boxes) == 0: return False faces = [] for face_bounding_box, confident in zip(faces_bounding_boxes, confidents): face = image.crop(face_bounding_box) faces.append(face) return faces if not return_bounding_boxes else faces, faces_bounding_boxes
def crop(image: Image, norm_pos, crop_size: int): if image is None: return None w, h = image.size pos = scale_to_image_coordinate(norm_pos, w, h, flip_y=False) rect = roi_rect(width=w, height=h, center_x=pos[0], center_y=pos[1], size=crop_size) if rect is None: return None return image.crop(rect)
def ocr( x_start: int, y_start: int, x_end: int, y_end: int, debug: bool = False, bmp: Image = None, cropb: bool = False, ocr_filter: bool = True, binf: int = 0, sliced: bool = False ) -> str: """Perform an OCR of the supplied area, returns a string of the result. Keyword arguments debug -- Saves an image of what is sent to the OCR (default False) bmp -- A bitmap from the get_bitmap() function, use this if you're performing multiple different OCR-readings in succession from the same page. This is to avoid to needlessly get the same bitmap multiple times. If a bitmap is not passed, the function will get the bitmap itself. (default None) cropb -- Whether the bmp provided should be cropped. filter -- Whether to filter the image for better OCR. binf -- Threshold value for binarizing filter. Zero means no filtering. sliced -- Whether the image has ben sliced so there's very little blank space. Gets better readings from small values for some reason. """ x_start += Window.x x_end += Window.x y_start += Window.y y_end += Window.y if bmp is None: bmp = Inputs.get_cropped_bitmap(x_start, y_start, x_end, y_end) elif cropb: # Bitmaps are created with a 8px border bmp = bmp.crop((x_start + 8, y_start + 8, x_end + 8, y_end + 8)) if binf > 0: # Binarizing Filter fn = lambda x: 255 if x > binf else 0 bmp = bmp.convert('L') # To Monochrome bmp = bmp.point(fn, mode='1') if debug: bmp.save("debug_ocr_whiten.png") if ocr_filter: # Resizing and sharpening *_, right, lower = bmp.getbbox() bmp = bmp.resize((right * 4, lower * 4), Image.BICUBIC) # Resize image bmp = bmp.filter(ImageFilter.SHARPEN) if debug: bmp.save("debug_ocr_filter.png") if sliced: s = pytesseract.image_to_string(bmp, config='--psm 6') else: s = pytesseract.image_to_string(bmp, config='--psm 4') return s
def crop_and_send(frame, det, destination="home/rossis/TEST_CROPS/", name="test.jpg"): det = xywh2xyxy(det) for el in det: el = el - 40 crop = Image.crop((det[0], det[1], det[2], det[3])) crop.save(destination + name)
def resize_image(im: Image, fg: Image, resize_mode: str, offset: dict) -> Image: """Resizes the image with the method specified in resize_mode Args: im (Image): image to resize fg (Image): images wich dimensions will be used to resize the former image resize_mode (str): how to resize the image offset (dict): offset used to crop the image Returns: Image: newly resized image """ orig_w, orig_h = im.size # size of the bg image temp_w, temp_h = fg.size # size of the template image if resize_mode == "crop": # crops the image from the center + the offset im = im.crop(box=((orig_w - temp_w) / 2 + offset['x'], (orig_h - temp_h) / 2 + offset['y'], (orig_w + temp_w) / 2 + offset['x'], (orig_h + temp_h) / 2 + offset['y'])) elif resize_mode == "scale": # scales the image so that it fits (ignores proportions) im = im.resize(fg.size) elif resize_mode == "scale&crop": # Make the image as big as the template proportionally for i in range(0, 2): ratio = temp_w / im.size[i] if ratio > 1: im = im.resize((int(orig_w * ratio), int(orig_h * ratio))) orig_w, orig_h = im.size # update the bg image size im = im.crop(box=((orig_w - temp_w) / 2 + offset['x'], (orig_h - temp_h) / 2 + offset['y'], (orig_w + temp_w) / 2 + offset['x'], (orig_h + temp_h) / 2 + offset['y'])) elif resize_mode == "random": # crops the image from the center + the random offset x_offset = random.randint(-abs(orig_w - temp_w) // 2, abs(orig_w - temp_w) // 2) y_offset = random.randint(-abs(orig_h - temp_h) // 2, abs(orig_h - temp_h) // 2) im = im.crop(box=((orig_w - temp_w) / 2 + x_offset, (orig_h - temp_h) / 2 + y_offset, (orig_w + temp_w) / 2 + x_offset, (orig_h + temp_h) / 2 + y_offset)) return im
def crop_rect(self, image: Image, box_position: Tuple[int, int, int, int]) -> Tuple[object, bool]: ''' crop ''' status = True try: image = image.crop(box_position) except: status = False return (image, status)
def scale(img: PIL.Image, size=200): """ Приводит img к размеру (size,size) """ center = (img.size[0] // 2, img.size[1] // 2) d = min(center) res = img.crop( (center[0] - d, center[1] - d, center[0] + d, center[1] + d)) return [res.resize((size, size))]
def GLCD_to_SSD1306(image: Image) -> Image: output = bytearray() for bn in range(8): #block number block: Image = image.crop((0, bn*8, 128, bn*8+8)) rblock: Image = block.rotate(-90, expand=True) output += rblock.tobytes() reassembled: Image = Image.frombytes('1', (64, 128), bytes(output)) return reassembled
def rating_type(image: Image, scores: typing.List[Score]) -> str: for score in scores: width_height = width_and_height(score.position_start, score.position_end) im_crop = image.crop((score.position_start.x, score.position_start.y, score.position_start.x + width_height[0], score.position_start.y + width_height[1])) return ""
def extract(cls, image: Image): faces_bounding_boxes, confidents = cls.model.detect(image) if len(faces_bounding_boxes) == 0: return False if len(faces_bounding_boxes) == 1: largest_face_bounding_box = faces_bounding_boxes[0] else: faces_areas = [GeometryUtils.calc_box_area(face_bounding_box) for face_bounding_box in faces_bounding_boxes] largest_face_index = numpy.argmax(faces_areas) largest_face_bounding_box = faces_bounding_boxes[largest_face_index] return image.crop(largest_face_bounding_box)
def replace_from_frame(image: Image, detection: dict): cx = detection.get(CROP_X) cy = detection.get(CROP_Y) w, h = detection.get(CROP_SIZE) hit_img = image.crop((cx, cy, cx + w, cy + h)) detection[ORIG_IMAGE] = detection[IMAGE] detection[IMAGE] = hit_img with BytesIO() as output: hit_img.save(output, format="png") # hit_img.save('/tmp/%d.png' % detection.get('id')) detection[FRAME_DECODED] = output.getvalue()
def predict_img(img: Image): img = img.crop((0, 0, 256, 256)) img = img.convert("L") img = img.resize((64, 64), Image.ANTIALIAS) data = np.asarray(img) data = np.reshape(data, (64, 64, 1)) data = data / 255.0 data = np.array([data]) res = model.predict(data) return list_all[np.argmax(res)]
def _resize_input(self, img: Image) -> Image: border = tuple( np.floor_divide(np.subtract(self._target_icon_size, img.size), 2)) if all(size > 0 for size in border): resized_icon = ImageOps.expand(img, border=border, fill="black") else: resized_icon = img.crop((-border[0], -border[1], -border[0] + self._target_icon_size[0], -border[1] + self._target_icon_size[1])) return resized_icon
def crop_image(image: Image): center_x = int(image.width / 2) center_y = int(image.height / 2) screen_width = screen_size[0] screen_height = screen_size[1] left_upper = (center_x - int(screen_width / 2), center_y - int(screen_height / 2)) right_lower = (center_x + int(screen_width / 2), center_y + int(screen_height / 2)) return image.crop(left_upper + right_lower)
def cut(self, box): """ cut out a box of the image and return it args: box (4-tuple of int): (left, top, right, bottom) (see PIL documentation) returns: a new cut image """ # copy image # deepcopy does not work somehow, so create a new image exactly like # this one cutimage = Image(self) # crop image cutimage.crop(box) return cutimage
def crop(image: Image, face) -> (Image, 'face'): ratio = 0.20 / 0.85 # delta_size / face_size width, height = image.size face_height = face.height() face_width = face.width() delta_height = ratio * face_height delta_width = ratio * width img_left = int(max(0, face.left() - delta_width)) img_top = int(max(0, face.top() - delta_height)) img_right = int(min(width, face.right() + delta_width)) img_bottom = int(min(height, face.bottom() + delta_height)) image = image.crop((img_left, img_top, img_right, img_bottom)) face = dlib.rectangle(face.left() - img_left, face.top() - img_top, face.right() - img_left, face.bottom() - img_top) center = face.center() width, height = image.size if width > height: left = int(center.x - height / 2) right = int(center.x + height / 2) if left < 0: left, right = 0, height elif right > width: left, right = width - height, width image = image.crop((left, 0, right, height)) face = dlib.rectangle(face.left() - left, face.top(), face.right() - left, face.bottom()) elif width < height: top = int(center.y - width / 2) bottom = int(center.y + width / 2) if top < 0: top, bottom = 0, width elif bottom > height: top, bottom = height - width, height image = image.crop((0, top, width, bottom)) face = dlib.rectangle(face.left(), face.top() - top, face.right(), face.bottom() - top) return image, face
def generate(master: Image, master_size: int, small_size: int) -> Image: dir_src = Config.get_default_dir() images_sources = FileCheck.get_dir_content(dir_src) images = LoadImages.load_images_with_resize(dir_src, images_sources, small_size, small_size) master_w, master_h = master.size if master_w > master_h: master_w = master_h elif master_h > master_w: master_h = master_w master_h -= master_h % master_size master_w = master_h master.resize((master_w, master_h)) part_size = master_w // master_size master_parts = {} for i in range(master_size): if i not in master_parts: master_parts[i] = {} for j in range(master_size): master_parts[i][j] = np.array( master.crop((part_size * i, part_size * j, part_size * (i + 1), part_size * (j + 1))).getdata()) images_reduce = {} for small_image in Model.resize_all(images.copy(), part_size, part_size): images_reduce[len(images_reduce)] = np.array(small_image.getdata()) links = {} for i, line in master_parts.items(): for j, sub_image in line.items(): best_value = 195075 * part_size * part_size + 1 best_id = None for k, small_image in images_reduce.items(): value = ((sub_image - small_image)**2).sum() if value < best_value: best_value = value best_id = k links[i * master_size + j] = best_id Model.make_final(links, images, master_size, small_size).rotate(-90).save(Config.get_save_path())
def Binarized(Image, Threshold): ImgNew = Image.crop() Pixels = ImgNew.load() (Width, Height) = ImgNew.size for i in xrange(Width): for j in xrange(Height): if Pixels[i, j] > Threshold: # 大于阈值的置为白色,否则黑色 Pixels[i, j] = 255 # 白色 else: Pixels[i, j] = 0 # 黑色 return ImgNew
def get_image_resized(self, image: Image) -> Image: """ Getting image resized :param image: :return: """ cropped_image = image.crop( (self.x_axis, self.y_axis, self.width + self.x_axis, self.height + self.y_axis)) return cropped_image.resize((256, 256), Image.ANTIALIAS)
def center_crop(img: Image): """ Crop image in center. """ width, height = img.size if width > height: # 横長 box = ((width - height) / 2, 0, (width + height) / 2, height) else: # 縦長 box = (0, (height - width) / 2, width, (height + width) / 2) cropped_img = img.crop(box) return cropped_img
def crop_image(image: Image, x1: int, y1: int, x2: int, y2: int) -> Image: """Crop an image. The arguments `x1`, `y1`, `x2`, `y2` are the coordinates of the cropped region in percent. """ width, height = image.size x1_abs = x1 * width / 100 x2_abs = x2 * width / 100 y1_abs = y1 * height / 100 y2_abs = y2 * height / 100 return image.crop((x1_abs, y1_abs, x2_abs, y2_abs))
def crop_face(image: Image, face_keypoints: Optional, hyp_ratio: float = 1 / 3) -> Image: """Crop input image to just the face""" if face_keypoints is None: print("No keypoints detected on image") return image left, upper, right, lower = get_crop_points(image, face_keypoints, hyp_ratio) return image.crop((left, upper, right, lower))
def cut_pic(Image,dst_w,dst_h): # dst_w = 800,dst_h = 600 try: ori_w, ori_h = Image.size if(ori_h>ori_w): y = (ori_h-dst_h)/2 box = (0, int(y), dst_w, dst_h+y) newImg = Image.crop(box) try: return newImg except IOError: return None except IOError:None
def center_crop(cls, img: Image): """ Crop image in center. """ width, height = img.size if width > height: # 横長 box = (int((width - height) / 2), 0, int((width + height) / 2), height) else: # 縦長 box = (0, int((height - width) / 2), width, int((height + width) / 2)) cropped_img = img.crop(box) return cropped_img
def crop_image(img: Image, xy: (float, float), scale_factor: float) -> Image: """Crop the image around the tuple xy Inputs: ------- img: Image opened with PIL.Image xy: tuple with relative (x,y) position of the center of the cropped image x and y shall be between 0 and 1 scale_factor: the ratio between the original image's size and the cropped image's size """ center = (img.size[0] * xy[0], img.size[1] * xy[1]) new_size = (img.size[0] / scale_factor, img.size[1] / scale_factor) left = max(0, int(center[0] - new_size[0] / 2)) right = min(img.size[0], int(center[0] + new_size[0] / 2)) upper = max(0, int(center[1] - new_size[1] / 2)) lower = min(img.size[1], int(center[1] + new_size[1] / 2)) cropped_img = img.crop((left, upper, right, lower)) return cropped_img
def process(input: Image, output: Image, pixel: int, scale: int): """ Do the needful. """ size = pixel * scale x = y = 0 source_x, source_y = input.size draw = ImageDraw.Draw(output) while True: # color = input.getpixel((x * pixel, y * pixel) art_pixel = input.crop((x * pixel, y * pixel, (x + 1) * pixel, (y + 1) * pixel)) colors = list(art_pixel.getdata()) total_pixels = len(colors) r = g = b = a = 0 for color in colors: r += color[0] g += color[1] b += color[2] a += color[3] r //= total_pixels g //= total_pixels b //= total_pixels a //= total_pixels drawpixel(draw, x, y, size, (r, g, b, a)) x += 1 if x * pixel >= source_x: x = 0 y += 1 if y * pixel >= source_y: break
def _extract_years(self, image: Image, x_ticks: list, bottom_line_y: int) -> list: years = [] for tick in x_ticks: # this 15s is bugprone estimations # todo fairly find gaps bw words box = (tick - 15, bottom_line_y + 3, tick + 20, image.size[1]) region = image.crop(box) text = region.crop(ImageOps.invert(region.convert('RGB')).getbbox()) # debug # region.save(str(tick)+'.bmp') word = '' rightmost_unread_pixel = text.size[0] while rightmost_unread_pixel > 0: x_left = rightmost_unread_pixel - self.tesser.max_width if x_left < 0: x_left = 0 x_right = rightmost_unread_pixel glyph = Image.new('RGBA', (x_right - x_left, 8), (255, 255, 255)) glyph.paste(text.crop((x_left, 0, x_right, 8))) letter, width = self.tesser.tess(glyph, left=False) word = letter + word rightmost_unread_pixel -= width years.append((self._word_to_year(word), tick)) years = sorted(years) # add first and last years min_year_0 = years[0] min_year_1 = years[1] first_year = (min_year_0[0] - 1, min_year_0[1] - (min_year_1[1] - min_year_0[1])) max_year_n1 = years[-2] max_year_n = years[-1] last_year = (max_year_n[0] + 1, max_year_n[1] + (max_year_n[1] - max_year_n1[1])) return [first_year] + years + [last_year]
def cut_box(lft,up,rght,lwr, Image): Image.load() box = (lft, up, rght ,lwr) i = Image.crop(box) return i
def find_slots(cls, loot_image: Image) -> List[Dict[str, Any]]: """Scans through an image, looking for inventory slots :param loot_image: An inventory screenshot :return: A list of dictionaries, containing the images and coordinates for every slot. """ image_copy = loot_image.copy() loot_bytes = loot_image.tobytes() slot_list = [] if loot_image.size[0] < 34 or loot_image.size[1] < 27: return slot_list x = -1 y = 0 skip = False for _ in loot_bytes: x += 1 if x + 34 > image_copy.size[0]: y += 1 x = 0 if y + 27 > image_copy.size[1]: break if skip: # Skip every other pixel to save time skip = False else: if x + 34 != image_copy.size[0]: # Can't skip the last part of an image skip = True if image_copy.getpixel((x, y)) == slot_border[0]: # If the current pixel looks like a slot s = 0 diff = 0 diffmax = 1 # 3/4's of the border size xs = 0 ys = 0 if x != 0 and image_copy.getpixel((x - 1, y)) == slot_border[0]: # Make sure we didnt skip the beggining of a slot # go back if we did x -= 1 # We also flag the next pixel to avoid looping here forever if this turns out not to be a slot image_copy.putpixel((x + 1, y), (255, 0, 255, 0)) while diff < diffmax: if xs == 0 or xs == 33 or ys == 0 or ys == 33: if not image_copy.getpixel((x + xs, y + ys)) == slot_border[s] \ and image_copy.getpixel((x + xs, y + ys)) not in [(24, 24, 24, 255), (55, 55, 55, 255), (57, 57, 57, 255), (75, 76, 76, 255), (255, 0, 255, 0)]: # ^ This is a workaround to ignore the bottom-left border of containers # as well as make the skipping work correctly break s += 1 xs += 1 if xs == 34: xs = 0 ys += 1 if ys == 28: slot_list.append({'image': loot_image.crop((x + 1, y + 1, x + 33, y + 33)), 'x': x, 'y': y}) image_copy.paste(Image.new("RGBA", (34, 34), (255, 255, 255, 255)), (x, y)) x += 33 break return slot_list