Module cogsgpt.cogsmodel.cv.utils
Expand source code
from __future__ import annotations
from io import BytesIO
import os
from typing import List, Tuple
import requests
import tempfile
from PIL import Image, ImageDraw
from cogsgpt.schema import FileSource
from cogsgpt.utils import detect_file_source
def load_image(image_file: str) -> Image:
image_src = detect_file_source(image_file)
if image_src == FileSource.LOCAL:
image = Image.open(image_file)
elif image_src == FileSource.REMOTE:
response = requests.get(image_file)
image = Image.open(BytesIO(response.content))
else:
raise ValueError(f"Invalid image source: {image_file}")
if image.mode in ('1', 'L', 'P', 'LA', 'PA'):
# convert to RGB mode for low bit depth images
image = image.convert('RGB')
return image
def draw_rectangles(src_image_file: str, tgt_image_file: str | None = None,
rectangles: List[Tuple[int, int, int, int]] = [], texts: List[str] = [],
line_color: str = 'red', line_width: int = 2,
text_color: str = 'black', text_bg_color: str = 'white',
text_offset: Tuple[int, int] = (5, 5)) -> str:
if len(texts) > 0:
assert len(rectangles) == len(texts), "The size of rectangles and texts should be the same."
image = load_image(src_image_file)
draw = ImageDraw.Draw(image)
for bbox, text in zip(rectangles, texts):
draw.rectangle(bbox, outline=line_color, width=line_width)
text_x, text_y = bbox[0] + text_offset[0], bbox[1] + text_offset[1]
left, top, right, bottom = draw.textbbox((text_x, text_y), text)
draw.rectangle((left-5, top-5, right+5, bottom+5), fill=text_bg_color)
draw.text((text_x, text_y), text, fill=text_color)
if tgt_image_file is None:
src_image_suffix = os.path.splitext(src_image_file)[1]
with tempfile.NamedTemporaryFile(mode='w+b', suffix='.' + src_image_suffix, delete=False) as tgt_image_file:
image.save(tgt_image_file)
return tgt_image_file.name
def crop_rectangle(src_image_file: str, tgt_image_file: str | None = None,
rectangle: Tuple[int, int, int, int] = ()) -> str:
image = load_image(src_image_file)
cropped_image = image.crop(rectangle)
if tgt_image_file is None:
src_image_suffix = os.path.splitext(src_image_file)[1]
with tempfile.NamedTemporaryFile(mode='w+b', suffix='.' + src_image_suffix, delete=False) as tgt_image_file:
cropped_image.save(tgt_image_file)
return tgt_image_file.name
Functions
def crop_rectangle(src_image_file: str, tgt_image_file: str | None = None, rectangle: Tuple[int, int, int, int] = ()) ‑> str-
Expand source code
def crop_rectangle(src_image_file: str, tgt_image_file: str | None = None, rectangle: Tuple[int, int, int, int] = ()) -> str: image = load_image(src_image_file) cropped_image = image.crop(rectangle) if tgt_image_file is None: src_image_suffix = os.path.splitext(src_image_file)[1] with tempfile.NamedTemporaryFile(mode='w+b', suffix='.' + src_image_suffix, delete=False) as tgt_image_file: cropped_image.save(tgt_image_file) return tgt_image_file.name def draw_rectangles(src_image_file: str, tgt_image_file: str | None = None, rectangles: List[Tuple[int, int, int, int]] = [], texts: List[str] = [], line_color: str = 'red', line_width: int = 2, text_color: str = 'black', text_bg_color: str = 'white', text_offset: Tuple[int, int] = (5, 5)) ‑> str-
Expand source code
def draw_rectangles(src_image_file: str, tgt_image_file: str | None = None, rectangles: List[Tuple[int, int, int, int]] = [], texts: List[str] = [], line_color: str = 'red', line_width: int = 2, text_color: str = 'black', text_bg_color: str = 'white', text_offset: Tuple[int, int] = (5, 5)) -> str: if len(texts) > 0: assert len(rectangles) == len(texts), "The size of rectangles and texts should be the same." image = load_image(src_image_file) draw = ImageDraw.Draw(image) for bbox, text in zip(rectangles, texts): draw.rectangle(bbox, outline=line_color, width=line_width) text_x, text_y = bbox[0] + text_offset[0], bbox[1] + text_offset[1] left, top, right, bottom = draw.textbbox((text_x, text_y), text) draw.rectangle((left-5, top-5, right+5, bottom+5), fill=text_bg_color) draw.text((text_x, text_y), text, fill=text_color) if tgt_image_file is None: src_image_suffix = os.path.splitext(src_image_file)[1] with tempfile.NamedTemporaryFile(mode='w+b', suffix='.' + src_image_suffix, delete=False) as tgt_image_file: image.save(tgt_image_file) return tgt_image_file.name def load_image(image_file: str) ‑> Image-
Expand source code
def load_image(image_file: str) -> Image: image_src = detect_file_source(image_file) if image_src == FileSource.LOCAL: image = Image.open(image_file) elif image_src == FileSource.REMOTE: response = requests.get(image_file) image = Image.open(BytesIO(response.content)) else: raise ValueError(f"Invalid image source: {image_file}") if image.mode in ('1', 'L', 'P', 'LA', 'PA'): # convert to RGB mode for low bit depth images image = image.convert('RGB') return image