我们如何计算该图像中的三角形:
首先,我们需要消除颜色噪声。然后我们可以尝试 cv2.Canny 和 cv2.findCountours。但是 cv2.findCountours 如何区分各个交叉形状?
我尝试了这个:
img = cv2.fastNlMeansDenoisingColored(img, None, 6, 6)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
结果不好......
以下是如何使用 OpenCV 在 Python 中计算图像中三角形的数量:
import cv2
# 读取图像
image = cv2.imread("triangles.png")
# 将图像转换为灰度
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 对图像应用阈值处理
thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)[1]
# 使用形态学运算来清理图像
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=3)
# 查找轮廓
cnts = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
# 循环遍历轮廓
triangle_count = 0
for c in cnts:
# 使用周长和面积比来逼近形状
perimeter = cv2.arcLength(c, True)
area = cv2.contourArea(c)
if perimeter > 0: # 避免被零除
compactness = 4 * cv2.pi * area / (perimeter**2)
# 三角形的紧实度值较低
# 调整此阈值以适应你的图像
if compactness > 0.15:
cv2.drawContours(image, [c], -1, (0, 255, 0), 2)
triangle_count += 1
# 显示结果
print("三角形数量:", triangle_count)
cv2.imshow("Result", image)
cv2.waitKey(0)
解释:
- 预处理:
- 将图像转换为灰度以进行简单的处理。
- 对图像应用阈值处理以创建二值图像。
-
使用形态学运算(膨胀后腐蚀)来清理图像,关闭小的间隙和孔洞。
-
查找轮廓:
-
使用
cv2.findContours
函数查找二值图像中的轮廓。 -
使用
cv2.RETR_EXTERNAL
仅检索外部轮廓。 -
分析轮廓和计数三角形:
- 循环遍历每个轮廓并计算其周长和面积。
-
计算紧实度(也称为形状因子),定义为
(4 * pi * 面积) / (周长)^2
。该值对于圆形接近 1,而对于更复杂的形状则较低。 - 通过实验确定一个阈值紧实度值,以区分三角形和其他形状。
-
如果一个轮廓的紧实度高于阈值,则将其计为三角形,并在原始图像上绘制该轮廓以进行可视化。
-
显示结果:
- 打印检测到的三角形的总数。
- 显示结果图像,其中突出显示了检测到的三角形。
注意:
- 可能需要根据你的特定图像调整形态学运算的内核大小和迭代次数,以及紧实度阈值。
- 此方法依赖于形状紧实度,并且可能无法在所有情况下完美地识别所有三角形,尤其是在形状严重扭曲或部分被遮挡的情况下。你可能需要探索更强大的形状检测技术或结合其他特征以获得更稳健的结果。