### 使用 OpenCV 实现矩形内外轮廓检测
为了实现矩形内外轮廓的检测,可以采用 `cv2.findContours` 函数来查找图像中的轮廓。该函数能够返回两个主要的结果:一个是轮廓本身,另一个是层次结构信息。
对于模式参数的选择,在想要获取所有的外部和内部轮廓时,应该使用不同的检索模式而不是仅限于外部轮廓。具体来说:
- **外部轮廓**可以通过设置 `mode` 参数为 `cv2.RETR_EXTERNAL` 来获得,这只会提取最外面的一层轮廓[^1]。
```python
import cv2
import numpy as np
# 加载图片并转换成灰度图
image = cv2.imread('rectangle.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 应用二值化阈值处理
_, thresh = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY_INV)
# 查找所有外部轮廓
external_contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
```
当目标是从给定形状中找到内嵌轮廓(即子轮廓),则应选择其他检索方式如 `cv2.RETR_TREE` 或者 `cv2.RETR_CCOMP`,这些选项会提供更详细的层次关系数据以便区分父级与子级轮廓[^2]。
下面是一个完整的例子用于展示如何同时捕捉到矩形对象上的内外边界:
```python
# 查找具有层级结构的所有轮廓
all_contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 创建一个新的空白图像用来绘制轮廓
blank_image = np.zeros_like(image)
# 绘制所有发现的轮廓及其对应的外接矩形
for i in range(len(all_contours)):
color = (np.random.randint(0, 256), np.random.randint(0, 256), np.random.randint(0, 256))
# 如果当前轮廓有上级,则认为它是内部轮廓;否则就是外部轮廓
if hierarchy[0][i][3] != -1:
contour_type = "internal"
else:
contour_type = "external"
# 在原始图像上标记轮廓类型
x,y,w,h = cv2.boundingRect(all_contours[i])
cv2.putText(image, f"{contour_type}", (x, y+h+20), cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2)
# 将轮廓画在新的空白图像上
cv2.drawContours(blank_image, all_contours, i, color, 2)
rect = cv2.minAreaRect(all_contours[i])
box = cv2.boxPoints(rect)
box = np.intp(box)
cv2.drawContours(blank_image,[box],0,color,2)
# 显示结果
cv2.imshow("Original Image with Labels", image)
cv2.imshow("Detected Contours on Blank Image", blank_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
这段代码不仅展示了如何识别不同类型的轮廓,还通过颜色编码的方式直观地区分了哪些属于外部轮廓而哪些又是内部轮廓,并且在外围添加标签说明[^3]。