mi-task/test/text-image/text_image.py
2025-08-21 14:04:38 +08:00

181 lines
6.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import cv2
import numpy as np
import os
from pathlib import Path
def preprocess_image(image):
"""
预处理图像转换为HSV色彩空间检测白色区域
"""
# 转换为HSV色彩空间
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
# 定义白色的HSV范围 - 放宽范围
# 白色在HSV中饱和度低明度高
# 原来的范围lower_white = np.array([0, 0, 200]), upper_white = np.array([180, 30, 255])
# 放宽后的范围:
lower_white = np.array([0, 0, 150]) # 降低明度下限从200降到150
upper_white = np.array([180, 60, 255]) # 提高饱和度上限从30提高到60
# 创建白色掩码
white_mask = cv2.inRange(hsv, lower_white, upper_white)
# 形态学操作:开运算去除小噪点,闭运算填充小孔
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
cleaned = cv2.morphologyEx(white_mask, cv2.MORPH_OPEN, kernel)
cleaned = cv2.morphologyEx(cleaned, cv2.MORPH_CLOSE, kernel)
return cleaned
def find_white_rectangles(binary_image):
"""
查找白色矩形区域
"""
contours, _ = cv2.findContours(
binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
# 筛选合适的矩形轮廓
valid_rectangles = []
for contour in contours:
area = cv2.contourArea(contour)
if area > 200: # 过滤太小的区域从500降低到200
# 计算轮廓的边界矩形
x, y, w, h = cv2.boundingRect(contour)
# 计算轮廓的近似多边形
epsilon = 0.02 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
# 检查是否为四边形(矩形)
if len(approx) == 4:
# 计算宽高比
aspect_ratio = w / h
# 矩形应该有合理的宽高比(不是太细长)
if 0.3 < aspect_ratio < 3.0:
valid_rectangles.append((contour, (x, y, w, h), approx))
return valid_rectangles
def analyze_white_region(roi, original_roi):
"""
分析白色区域的特征
"""
# 计算白色像素比例
total_pixels = roi.shape[0] * roi.shape[1]
white_pixels = np.sum(roi == 255)
white_ratio = white_pixels / total_pixels
# 计算区域的形状特征
height, width = roi.shape
aspect_ratio = width / height
# 计算边缘强度(白色区域应该有清晰的边缘)
edges = cv2.Canny(original_roi, 50, 150)
edge_density = np.sum(edges > 0) / total_pixels
return {
'white_ratio': white_ratio,
'aspect_ratio': aspect_ratio,
'edge_density': edge_density,
'area': total_pixels
}
def detect_white_rectangles_in_image(image_path):
"""
检测图片中的白色矩形区域
"""
# 读取图像
image = cv2.imread(image_path)
if image is None:
print(f"无法读取图像: {image_path}")
return []
# 预处理
white_mask = preprocess_image(image)
# 查找白色矩形
valid_rectangles = find_white_rectangles(white_mask)
results = []
for contour, (x, y, w, h), approx in valid_rectangles:
# 提取ROI
roi_mask = white_mask[y:y+h, x:x+w]
roi_original = image[y:y+h, x:x+w]
# 分析特征
features = analyze_white_region(roi_mask, roi_original)
# 判断是否为有效的白色矩形
is_valid_white_rectangle = (
features['white_ratio'] > 0.4 and # 白色像素比例要求降低从0.6降到0.4
features['edge_density'] > 0.005 # 边缘密度要求降低从0.01降到0.005
)
if is_valid_white_rectangle:
results.append({
'type': 'white_rectangle',
'position': (x, y, w, h),
'features': features,
'confidence': 'high' if features['white_ratio'] > 0.8 else 'medium'
})
# 在图像上绘制结果
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(image, f"白色矩形", (x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
# 绘制轮廓点
cv2.drawContours(image, [approx], -1, (255, 0, 0), 2)
return image, results
def main():
"""
主函数:测试白色矩形检测
"""
# 图片路径
img_dir = Path("imgs")
img1_path = img_dir / "1.jpg"
img2_path = img_dir / "2.jpg"
print("开始检测图片中的白色矩形区域...")
# 检测第一张图片
if img1_path.exists():
print(f"\n检测图片: {img1_path}")
result_img1, results1 = detect_white_rectangles_in_image(str(img1_path))
print("检测结果:")
for result in results1:
print(f" 类型: {result['type']}, 位置: {result['position']}, 置信度: {result['confidence']}")
print(f" 特征: 白色比例={result['features']['white_ratio']:.2f}, "
f"宽高比={result['features']['aspect_ratio']:.2f}")
# 保存结果图片
output_path1 = img_dir / "result_1.jpg"
cv2.imwrite(str(output_path1), result_img1)
print(f"结果图片已保存到: {output_path1}")
# 检测第二张图片
if img2_path.exists():
print(f"\n检测图片: {img2_path}")
result_img2, results2 = detect_white_rectangles_in_image(str(img2_path))
print("检测结果:")
for result in results2:
print(f" 类型: {result['type']}, 位置: {result['position']}, 置信度: {result['confidence']}")
print(f" 特征: 白色比例={result['features']['white_ratio']:.2f}, "
f"宽高比={result['features']['aspect_ratio']:.2f}")
# 保存结果图片
output_path2 = img_dir / "result_2.jpg"
cv2.imwrite(str(output_path2), result_img2)
print(f"结果图片已保存到: {output_path2}")
print("\n检测完成!")
if __name__ == "__main__":
main()