如何分割相交正方形以统计图像中正方形的总数量
解决方案
你可以不需要先分割相交正方形,直接通过霍夫直线检测+正方形特征匹配的方式完成统计,也可以通过距离变换+分水岭算法先分割相交区域后再做统计,两种方式都可以实现需求,前者实现更简单。
具体实现步骤
- 首先在你现有二值化结果的基础上做一次开运算,消除残留的细碎噪点,避免后续检测受干扰
- 用霍夫直线变换检测图像中所有的水平、竖直直线段,过滤掉长度过短的无效线段
- 遍历所有线段组合,匹配满足「四条边长度近似相等、相邻边夹角近似90度、四个端点闭合」特征的组合,每匹配到一组就计数+1
- 针对相交的正方形轮廓,可以通过角点数量辅助校验,进一步提升计数准确率
完整可运行代码
import cv2 import numpy as np import matplotlib.pyplot as plt # 读取并预处理图像 image = cv2.imread("1.bmp") image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) # 二值化+开运算去噪 _, binary = cv2.threshold(gray, 3, 255, cv2.THRESH_BINARY) kernel = np.ones((3,3), np.uint8) binary = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel, iterations=2) # 统计正方形数量 square_count = 0 # 先检测外轮廓做初步筛选 contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for cnt in contours: # 过滤小面积噪声 area = cv2.contourArea(cnt) if area < 100: continue # 多边形拟合识别独立正方形 epsilon = 0.02 * cv2.arcLength(cnt, True) approx = cv2.approxPolyDP(cnt, epsilon, True) if len(approx) == 4: x,y,w,h = cv2.boundingRect(approx) aspect_ratio = float(w)/h if 0.95 <= aspect_ratio <= 1.05: square_count +=1 # 处理相交的正方形轮廓:通过角点数量估算 else: mask = np.zeros_like(binary) cv2.drawContours(mask, [cnt], -1, 255, -1) corners = cv2.goodFeaturesToTrack(mask, maxCorners=100, qualityLevel=0.01, minDistance=10) corners = np.int0(corners) square_count += len(corners)//4 print(f"检测到的正方形总数为:{square_count}") # 可视化结果 plt.imshow(binary, cmap="gray") plt.title(f"Square count: {square_count}") plt.show()
如果你的场景中正方形大小统一,可以直接在代码中加入边长校验逻辑,进一步提升检测准确率;如果相交情况非常复杂,可以替换为分水岭分割方案,先拆分每个独立的正方形区域再做计数。
内容的提问来源于stack exchange,提问作者rangihrad
相关产品推荐
相关产品推荐

