@@ -122,21 +122,42 @@ def cvt_two_to_three(img: np.ndarray) -> np.ndarray:
122122
123123 @staticmethod
124124 def cvt_four_to_three (img : np .ndarray ) -> np .ndarray :
125- """RGBA → BGR"""
126- r , g , b , a = cv2 .split (img )
127- new_img = cv2 .merge ((b , g , r ))
125+ """自动调整背景颜色,以增强文字对比度"""
128126
129- not_a = cv2 .bitwise_not (a )
130- not_a = cv2 .cvtColor (not_a , cv2 .COLOR_GRAY2BGR )
131-
132- new_img = cv2 .bitwise_and (new_img , new_img , mask = a )
127+ rgb = img [:, :, :3 ] # shape (H, W, 3)
128+ alpha = img [:, :, 3 ] # shape (H, W)
133129
134- mean_color = np .mean (new_img )
135- if mean_color <= 0.0 :
136- new_img = cv2 .add (new_img , not_a )
130+ # 获取非透明区域的 RGB 像素
131+ mask = alpha > 0
132+ non_transparent_rgb = rgb [mask ] # shape (N, 3)
133+ if non_transparent_rgb .size == 0 :
134+ # 全透明图像:默认用白色背景
135+ bg_color = (255 , 255 , 255 )
137136 else :
138- new_img = cv2 .bitwise_not (new_img )
139- return new_img
137+ # 使用加权灰度公式计算亮度均值
138+ # luminance = 0.299*R + 0.587*G + 0.114*B
139+ r , g , b = (
140+ non_transparent_rgb [:, 0 ],
141+ non_transparent_rgb [:, 1 ],
142+ non_transparent_rgb [:, 2 ],
143+ )
144+ luminance = 0.299 * r + 0.587 * g + 0.114 * b
145+ avg_luminance = np .mean (luminance )
146+
147+ # 根据平均亮度选择高对比度背景
148+ bg_color = (255 , 255 , 255 ) if avg_luminance < 128 else (0 , 0 , 0 )
149+
150+ # 构建背景图像
151+ background = np .full_like (rgb , bg_color , dtype = np .uint8 )
152+
153+ # 合成:前景 = rgb * (alpha/255), 背景 = bg * (1 - alpha/255)
154+ alpha_norm = alpha .astype (np .float32 ) / 255.0
155+ foreground_blend = rgb .astype (np .float32 ) * alpha_norm [..., None ]
156+ background_blend = background .astype (np .float32 ) * (1.0 - alpha_norm )[..., None ]
157+
158+ blended = (foreground_blend + background_blend ).astype (np .uint8 )
159+
160+ return cv2 .cvtColor (blended , cv2 .COLOR_RGB2BGR )
140161
141162
142163class LoadImageError (Exception ):
0 commit comments