Akjava's picture
add
0aba763
raw
history blame
5.99 kB
import cv2
import numpy as np
#2024-11-27 add copy image
#2024-12-04 plot_text = False,plot line first
#2024-11-30 copy paste
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("入力画像の形状が一致しません。")
# 画像を float 型に変換
image1 = image1.astype(float)
image2 = image2.astype(float)
# マスクを 3 チャンネルに変換し、0-1 の範囲にスケール
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.")
# Type check
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}")
# Paste the overlapping part
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]
#not check safe
def paste(image,replace_image,x,y):
height,width = replace_image.shape[:2]
image[y:y+height, x:x+width] = replace_image