我有一段代码,是对二值图进行聚类,然后画框,但是大框中包含许多小框,请你帮我添加一段代码在我的代码基础上,做一个nms抑制,优化这种情况,我的代码如下:_, binary_image = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) connectivity = 4 output = cv2.connectedComponentsWithStats(binary_image, connectivity, cv2.CV_32S) num_labels = output[0] labels = output[1] stats = output[2] centroids = output[3] print(num_labels) # 遍历每个聚类 for i in range(1, num_labels): x, y, w, h, area = stats[i]
时间: 2023-11-20 14:06:49 浏览: 72
图像聚类处理
好的,你需要添加的是一个非极大值抑制(Non-Maximum Suppression,NMS)的过程,用来筛选掉重叠的小框,只保留最大的一个框。以下是代码示例:
```
_, binary_image = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
connectivity = 4
output = cv2.connectedComponentsWithStats(binary_image, connectivity, cv2.CV_32S)
num_labels = output[0]
labels = output[1]
stats = output[2]
centroids = output[3]
print(num_labels)
# 定义NMS函数
def nms(bboxes, scores, threshold):
if len(bboxes) == 0:
return []
x1 = bboxes[:, 0]
y1 = bboxes[:, 1]
x2 = bboxes[:, 0] + bboxes[:, 2]
y2 = bboxes[:, 1] + bboxes[:, 3]
areas = (x2 - x1 + 1) * (y2 - y1 + 1)
order = scores.argsort()[::-1]
keep = []
while order.size > 0:
i = order[0]
keep.append(i)
xx1 = np.maximum(x1[i], x1[order[1:]])
yy1 = np.maximum(y1[i], y1[order[1:]])
xx2 = np.minimum(x2[i], x2[order[1:]])
yy2 = np.minimum(y2[i], y2[order[1:]])
w = np.maximum(0.0, xx2 - xx1 + 1)
h = np.maximum(0.0, yy2 - yy1 + 1)
overlap = w * h / areas[order[1:]]
inds = np.where(overlap <= threshold)[0]
order = order[inds + 1]
return keep
# 初始化框和得分列表
bboxes = []
scores = []
# 遍历每个聚类
for i in range(1, num_labels):
x, y, w, h, area = stats[i]
score = area # 以面积作为得分
bboxes.append([x, y, w, h])
scores.append(score)
# 进行NMS
keep = nms(np.array(bboxes), np.array(scores), threshold=0.5)
# 画出保留的框
for i in keep:
x, y, w, h = bboxes[i]
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
```
其中,`nms`函数是一个常用的NMS实现,输入是框的坐标和得分,输出是经过抑制后保留的框的索引。在代码中,我们先将每个聚类的区域作为一个框,以其面积作为得分,然后调用`nms`函数进行抑制,最后在原图上画出保留的框。你可以自行调整`threshold`参数来控制抑制的严格程度。
阅读全文