findcontours函数得到数据再进行平滑
时间: 2024-06-10 20:09:36 浏览: 122
findContours函数可以通过轮廓提取得到一系列的点集,但是这些轮廓可能过于复杂不平滑。为了使轮廓更加平滑,可以使用approxPolyDP函数对轮廓进行适当的近似。approxPolyDP函数可以根据指定的精度,将原始曲线与近似曲线之间的最大距离控制在一定范围内。这样可以得到一个较为平滑的多边形曲线。
相关问题
opencv findcontours()函数详细介绍
`findContours()` 函数是 OpenCV 库中的一个函数,用于查找二值图像中的轮廓。该函数的函数原型如下:
```python
cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]])
```
函数参数解释如下:
- `image`:输入图像,必须是二值化后的图像,即像素值为 0 或 255。
- `mode`:轮廓检索模式,决定轮廓的检索方式。有以下几个模式:
- `cv2.RETR_EXTERNAL`:只检测最外层轮廓。
- `cv2.RETR_LIST`:检测所有轮廓,但不建立轮廓间的父子关系。
- `cv2.RETR_CCOMP`:检测所有轮廓,建立两层轮廓的层次结构。
- `cv2.RETR_TREE`:检测所有轮廓,建立完整的轮廓层次结构。
- `method`:轮廓逼近方法,决定轮廓的输出方式。有以下几个方法:
- `cv2.CHAIN_APPROX_NONE`:存储所有轮廓点,相邻的两个点的像素位置差不超过 1。
- `cv2.CHAIN_APPROX_SIMPLE`:仅存储垂直、水平和对角线方向的端点,例如一个矩形轮廓只需 4 个点来保存轮廓信息。
- `cv2.CHAIN_APPROX_TC89_L1` 和 `cv2.CHAIN_APPROX_TC89_KCOS`:使用 Teh-Chin 链逼近算法进行轮廓压缩,输出较为平滑的轮廓。
- `contours`:轮廓数据,一个由点向量组成的列表,每个点向量表示一个轮廓点。
- `hierarchy`:轮廓层次信息,一个包含每个轮廓的属性的列表。
- `offset`:可选的偏移量,用于调整轮廓中的每个点的坐标。
`findContours()` 函数返回两个值,分别是轮廓数据和轮廓层次信息。轮廓层次信息用于描述轮廓之间的关系,每个轮廓有四个相关信息:它的父轮廓、它的第一个子轮廓、它的下一个兄弟轮廓以及它自己的索引。
使用 `findContours()` 函数可以实现一些图像处理的功能,例如目标检测、图像分割和形状识别等。
def Process(img): # 高斯平滑 gaussian = cv2.GaussianBlur(img, (3, 3), 0, 0, cv2.BORDER_DEFAULT)#高斯模糊函数 median = cv2.medianBlur(gaussian, 5)#中值滤波 sobel = cv2.Sobel(median, cv2.CV_8U, 1, 0, ksize=3)#Sobel算子,梯度方向是X # 二值化 ret, binary = cv2.threshold(sobel,200, 255, cv2.THRESH_BINARY)#cv2简单阙值函数 # 核函数 element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 1))#得到一个结构元素(卷积核)。主要用于后续的腐蚀、膨胀等运算。 element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 7)) dilation = cv2.dilate(binary, element2, iterations=1)#膨胀函数 # 腐蚀 erosion = cv2.erode(dilation, element1, iterations=1) # 膨胀 dilation2 = cv2.dilate(erosion, element2, iterations=3) return dilation2 def GetRegion(img): regions = [] # 查找轮廓 contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)#检测图像中物体轮廓 for contour in contours: area = cv2.contourArea(contour)#计算轮廓面积 if (area<2000): continue eps = 0.001* cv2.arcLength(contour, True)#计算封闭轮廓或者曲线的长度 approx = cv2.approxPolyDP(contour, eps, True)#轮廓多边形逼近 rect = cv2.minAreaRect(contour)#求最小面积矩形框 box = cv2.boxPoints(rect)#获取最小面积矩形框的四个顶点坐标 box = np.int0(box)#整型化 height = abs(box[0][1] - box[2][1]) width = abs(box[0][0] - box[2][0]) ratio =float(width) / float(height) if (ratio < 5 and ratio > 1.8): regions.append(box) return regions def detect(img): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#图片灰度化 prc = Process(gray) regions = GetRegion(prc) print('[INFO]:Detect %d license plates' % len(regions)) for box in regions: cv2.drawContours(img, [box], 0, (0, 0,255), 2) cv2.imwrite(r'C:\Users\86182\Pictures\Saved Pictures\test.png', img) cv2.waitKey(0) cv2.destroyAllWindows()该代码在实现车牌区域检测的过程中用到了什么算法
这段代码实现车牌区域检测主要用到了以下算法:
1. 高斯平滑(GaussianBlur)和中值滤波(medianBlur):用于平滑图像,减少噪声的影响。
2. Sobel算子(Sobel):用于检测图像边缘。
3. 二值化(threshold):将图像转换为黑白两色,方便后续处理。
4. 膨胀(dilate)和腐蚀(erode):用于调整图像形态,填补边缘空洞,去除小的噪点等。
5. 轮廓查找(findContours)和轮廓逼近(approxPolyDP):用于识别图像中的轮廓,并将其逼近为多边形。
6. 最小面积矩形框(minAreaRect):用于求出包含轮廓的最小面积矩形框。
7. 整型化(np.int0):将浮点型数据转换为整型数据。
8. 输出识别到的车牌数量,并将标记后的图像保存在本地。
阅读全文