如何用自定义网格生成的单位正方形测量单色区域面积
实现步骤与代码示例
1. 检测网格并分割单位正方形
原始图像无网格,首先需要识别并提取网格线,将图像分割为独立的单位正方形:
- 使用边缘检测(Canny)提取图像中的线条轮廓
- 通过霍夫直线变换检测水平和垂直网格线
- 根据检测到的直线坐标,计算每个单位正方形的边界框,同时排除图像边框区域
import cv2 import numpy as np # 读取图像 img = cv2.imread("your_image_path.jpg") gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 边缘检测提取线条轮廓 edges = cv2.Canny(gray, 50, 150, apertureSize=3) # 霍夫直线变换检测水平、垂直直线 lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=100, minLineLength=100, maxLineGap=10) # 分离水平与垂直直线 horizontal_lines = [] vertical_lines = [] for line in lines: x1, y1, x2, y2 = line[0] if abs(y2 - y1) < abs(x2 - x1): horizontal_lines.append(y1) else: vertical_lines.append(x1) # 去重排序,筛选内部网格(排除边框) horizontal_lines = sorted(list(set(horizontal_lines)))[1:-1] vertical_lines = sorted(list(set(vertical_lines)))[1:-1] # 生成所有单位正方形的边界框 squares = [] for i in range(len(horizontal_lines)-1): for j in range(len(vertical_lines)-1): x1 = vertical_lines[j] y1 = horizontal_lines[i] x2 = vertical_lines[j+1] y2 = horizontal_lines[i+1] squares.append((x1, y1, x2, y2))
2. 判断正方形是否为单色区域
将图像转换为HSV色彩空间(更适合颜色阈值筛选),为黄、橙、蓝三种颜色设定阈值,对每个正方形区域判断是否为纯单色:
- 设定每种颜色的HSV阈值范围
- 对每个正方形区域,统计落在对应颜色阈值内的像素占比
- 占比超过设定阈值(如95%)则判定为该颜色的单色正方形,否则排除(混色、网格区域)
# 转换为HSV色彩空间 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 定义各颜色的HSV阈值(需根据实际图像微调) color_ranges = { "yellow": [(20, 100, 100), (30, 255, 255)], "orange": [(10, 100, 100), (20, 255, 255)], "blue": [(90, 100, 100), (120, 255, 255)] } # 初始化各颜色的单色正方形计数 color_counts = {color: 0 for color in color_ranges} for (x1, y1, x2, y2) in squares: square_hsv = hsv[y1:y2, x1:x2] square_area = (x2 - x1) * (y2 - y1) # 逐一匹配颜色阈值 for color, (lower, upper) in color_ranges.items(): lower = np.array(lower, dtype=np.uint8) upper = np.array(upper, dtype=np.uint8) mask = cv2.inRange(square_hsv, lower, upper) color_pixel_num = cv2.countNonZero(mask) # 像素占比超过95%则判定为单色正方形 if color_pixel_num / square_area > 0.95: color_counts[color] += 1 break # 一个正方形仅归属一种颜色
3. 计算各颜色区域面积
假设每个单位正方形的实际面积为unit_area(根据网格实际尺寸设定),则各颜色总面积为:
# 设定单位正方形实际面积(示例为1平方厘米) unit_area = 1.0 # 计算各颜色总面积 color_areas = {color: count * unit_area for color, count in color_counts.items()} # 输出结果 for color, area in color_areas.items(): print(f"{color}区域总面积: {area}")
注意事项
- 需根据实际图像调整HSV颜色阈值,确保颜色识别准确
- 霍夫变换的参数(阈值、最小线长等)可能需要根据图像网格的清晰度微调
- 若网格存在轻微变形,可先使用透视变换校正图像后再分割正方形
内容的提问来源于stack exchange,提问作者Loc Nguyen
相关产品推荐
相关产品推荐

