| | import cv2 |
| | import numpy as np |
| |
|
| | |
| | |
| | |
| | def draw_bbox(image,box,color=(255,0,0),thickness=1): |
| | if thickness==0: |
| | return |
| | |
| | left = int(box[0]) |
| | top = int(box[1]) |
| | right = int(box[0]+box[2]) |
| | bottom = int(box[1]+box[3]) |
| | box_points =[(left,top),(right,top),(right,bottom),(left,bottom)] |
| | |
| | cv2.polylines(image, [np.array(box_points)], isClosed=True, color=color, thickness=thickness) |
| |
|
| |
|
| | def to_int_points(points): |
| | int_points=[] |
| | for point in points: |
| | int_points.append([int(point[0]),int(point[1])]) |
| | return int_points |
| |
|
| | def draw_text(img, text, point, font_scale=0.5, color=(200, 200, 200), thickness=1): |
| | font = cv2.FONT_HERSHEY_SIMPLEX |
| | cv2.putText(img, str(text), point, font, font_scale, color, thickness, cv2.LINE_AA) |
| |
|
| | plot_text_color = (200, 200, 200) |
| | plot_text_font_scale = 0.5 |
| | plot_index = 1 |
| | plot_text = False |
| |
|
| | def set_plot_text(is_plot,text_font_scale,text_color): |
| | global plot_index,plot_text,plot_text_font_scale,plot_text_color |
| | plot_text = is_plot |
| | plot_index = 1 |
| | plot_text_font_scale = text_font_scale |
| | plot_text_color = text_color |
| |
|
| | def plot_points(image,points,isClosed=False,circle_size=3,circle_color=(255,0,0),line_size=1,line_color=(0,0,255)): |
| | |
| | global plot_index,plot_text |
| | int_points = to_int_points(points) |
| | if line_size>0: |
| | cv2.polylines(image, [np.array(int_points)], isClosed=isClosed, color=line_color, thickness=line_size) |
| | if circle_size>0: |
| | for point in int_points: |
| | cv2.circle(image,point,circle_size,circle_color,-1) |
| | if plot_text: |
| | draw_text(image,plot_index,point,plot_text_font_scale,plot_text_color) |
| | plot_index+=1 |
| | |
| |
|
| | def fill_points(image,points,thickness=1,line_color=(255,255,255),fill_color = (255,255,255)): |
| | np_points = np.array(points,dtype=np.int32) |
| | cv2.fillPoly(image, [np_points], fill_color) |
| | cv2.polylines(image, [np_points], isClosed=True, color=line_color, thickness=thickness) |
| |
|
| | def get_image_size(cv2_image): |
| | return cv2_image.shape[:2] |
| |
|
| | def get_channel(np_array): |
| | return np_array.shape[2] if np_array.ndim == 3 else 1 |
| |
|
| | def get_numpy_text(np_array,key=""): |
| | channel = get_channel(np_array) |
| | return f"{key} shape = {np_array.shape} channel = {channel} ndim = {np_array.ndim} size = {np_array.size}" |
| |
|
| |
|
| | def gray3d_to_2d(grayscale: np.ndarray) -> np.ndarray: |
| | channel = get_channel(grayscale) |
| | if channel!=1: |
| | raise ValueError(f"color maybe rgb or rgba {get_numpy_text(grayscale)}") |
| | """ |
| | 3 次元グレースケール画像 (チャンネル数 1) を 2 次元に変換する。 |
| | |
| | Args: |
| | grayscale (np.ndarray): 3 次元グレースケール画像 (チャンネル数 1)。 |
| | |
| | Returns: |
| | np.ndarray: 2 次元グレースケール画像。 |
| | """ |
| |
|
| | if grayscale.ndim == 2: |
| | return grayscale |
| | return np.squeeze(grayscale) |
| |
|
| | def blend_rgb_images(image1: np.ndarray, image2: np.ndarray, mask: np.ndarray) -> np.ndarray: |
| | """ |
| | 2 つの RGB 画像をマスク画像を使用してブレンドする。 |
| | |
| | Args: |
| | image1 (np.ndarray): 最初の画像 (RGB)。 |
| | image2 (np.ndarray): 2 番目の画像 (RGB)。 |
| | mask (np.ndarray): マスク画像 (グレースケール)。 |
| | |
| | Returns: |
| | np.ndarray: ブレンドされた画像 (RGB)。 |
| | |
| | Raises: |
| | ValueError: 入力画像の形状が一致しない場合。 |
| | """ |
| |
|
| | if image1.shape != image2.shape or image1.shape[:2] != mask.shape: |
| | raise ValueError("入力画像の形状が一致しません。") |
| |
|
| | |
| | image1 = image1.astype(float) |
| | image2 = image2.astype(float) |
| |
|
| | |
| | alpha = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR).astype(float) / 255.0 |
| |
|
| | |
| | blended = (1 - alpha) * image1 + alpha * image2 |
| |
|
| | return blended.astype(np.uint8) |
| |
|
| | def create_color_image(img,color=(255,255,255)): |
| | mask = np.zeros_like(img) |
| | |
| | h, w = img.shape[:2] |
| | cv2.rectangle(mask, (0, 0), (w, h), color, -1) |
| | return mask |
| |
|
| | def pil_to_bgr_image(image): |
| | np_image = np.array(image, dtype=np.uint8) |
| | if np_image.shape[2] == 4: |
| | bgr_img = cv2.cvtColor(np_image, cv2.COLOR_RGBA2BGRA) |
| | else: |
| | bgr_img = cv2.cvtColor(np_image, cv2.COLOR_RGB2BGR) |
| | return bgr_img |
| |
|
| | def bgr_to_rgb(np_image): |
| | if np_image.shape[2] == 4: |
| | bgr_img = cv2.cvtColor(np_image, cv2.COLOR_RBGRA2RGBA) |
| | else: |
| | bgr_img = cv2.cvtColor(np_image, cv2.COLOR_BGR2RGB) |
| | return bgr_img |
| |
|
| | def copy_image(img1: np.ndarray, img2: np.ndarray, x: int, y: int) -> None: |
| | |
| | if img1.ndim != 3 or img2.ndim != 3: |
| | raise ValueError("Both img1 and img2 must be 3-dimensional arrays.") |
| | elif img1.shape[2] != img2.shape[2]: |
| | raise ValueError(f"img1 and img2 must have the same number of channels. img1 has {img1.shape[2]} channels, but img2 has {img2.shape[1]} channels.") |
| |
|
| | |
| | if not isinstance(img1, np.ndarray) or not isinstance(img2, np.ndarray): |
| | raise TypeError("img1 and img2 must be NumPy arrays.") |
| |
|
| | if x>=0: |
| | offset_x=0 |
| | w = min(img1.shape[1]-x,img2.shape[1]) |
| | else: |
| | w = min(img1.shape[1],img2.shape[1]+x) |
| | offset_x=int(-x) |
| | x = 0 |
| |
|
| | if y>=0: |
| | h = min(img1.shape[0]-y,img2.shape[0]) |
| | offset_y=0 |
| | else: |
| | h = min(img1.shape[0]-y,img2.shape[0]+y) |
| | offset_y=int(-y) |
| | y = 0 |
| | x=int(x) |
| | y=int(y) |
| | h=int(h) |
| | w=int(w) |
| | |
| | |
| | print(f"img1 {img1.shape} img2{img2.shape} x={x} y={y} w={w} h={h}") |
| | |
| | img1[y:y+h, x:x+w] = img2[offset_y:h+offset_y, offset_x:w+offset_x] |
| |
|
| | def crop(image,bbox): |
| | x,y,width,height = bbox |
| | return image[y:y+height, x:x+width] |
| | |
| | def paste(image,replace_image,x,y): |
| | height,width = replace_image.shape[:2] |
| | image[y:y+height, x:x+width] = replace_image |
| |
|