File size: 5,990 Bytes
0aba763 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
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
|