FakeOrange
预计阅读时间:3分钟31秒

OpenCV数量检测教程FindContour方式介绍

数量检测介绍及应用

0
0

1. 概述

  • 目标:通过图像处理技术检测图像中的物体数量。
  • 使用技术
    • 灰度化
    • 图像二值化
    • 形态学操作(膨胀、腐蚀)
    • 轮廓检测
    • 过滤噪声
  • OpenCV库官方文档:点击此处

2. 环境准备

  • 安装Python:确保安装Python 3.x。
  • 安装OpenCV 与 Numpy
pip install opencv-python
pip install numpy

3. 导入必要的库

首先,我们需要导入所需的库。、

import cv2
import numpy as np

4. 图像读取与预处理

我们首先读取图像并对其进行预处理,如灰度化、二值化和形态学操作。

# 读取图像
img = cv2.imread('objects.jpg')

# 转为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 应用高斯模糊以减少噪声,高斯模糊为常用消除噪点手法,通过调整(11,11)kernel大小影响最终模糊效果
blurred = cv2.GaussianBlur(gray, (11, 11), 0) 
# 应用二值化处理(阈值化)通过范围将像素值转化为0或255,uint8范围0-255
_, thresh = cv2.threshold(blurred, 150, 255, cv2.THRESH_BINARY_INV)

# 显示预处理结果,python运行使用
cv2.imshow('Threshold Image', thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()


#Notebook 可用以下方式
import matplotlib.pyplot as plt
plt.imshow(thresh,cmap='gray')

代码说明

  1. 灰度化:将图像从彩色空间转换为灰度,以简化处理。RGB图像为三通道,三个数值组成颜色。灰阶为单通道,一个数值表示。
  2. 高斯模糊:减少噪声,使边缘更加平滑。(建议调整高斯模糊的kernel大小去看看不同效果,会有更好的应用理解)
  3. 二值化:将图像转换为黑白图像,其中白色部分代表感兴趣的区域。(灰阶图像像素值0为黑色,255为白色)

5. 形态学操作

为了确保目标物体被正确检测,我们可以使用形态学操作,如膨胀和腐蚀,来增强图像中的物体特征。

# 定义一个核(用于膨胀和腐蚀)
kernel = np.ones((3, 3), np.uint8)

# 应用膨胀操作,使目标更明显,使像素值非0的部分膨胀
dilated = cv2.dilate(thresh, kernel, iterations=2)

# 显示形态学操作后的结果
cv2.imshow('Dilated Image', dilated)
cv2.waitKey(0)
cv2.destroyAllWindows()

#Notebook 可用以下方式
import matplotlib.pyplot as plt
plt.imshow(thresh,cmap='gray')

代码说明

  • 膨胀:通过增大白色区域使物体更突出,有助于连接破碎的边缘。(分水岭算法通过计算梯度,如高地不被淹没去找寻目标区域,所以破碎或不连接处可能会导致整体被分割为不同个体。具体情况具体操作,其他情况也可以使用腐蚀的方式去剥离重叠部分。)


6. 轮廓检测

接下来,通过轮廓检测来找到图像中的所有物体。

pythonCopy code# 检测图像中的轮廓
contours, _ = cv2.findContours(dilated.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 在原图上绘制轮廓
cv2.drawContours(img, contours, -1, (0, 255, 0), 3)

# 显示检测到轮廓的图像
cv2.imshow('Contours', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

代码说明

  • cv2.findContours:查找图像中的所有轮廓。
  • cv2.drawContours:在原始图像上绘制检测到的轮廓。

7. 物体数量统计

使用检测到的轮廓数量,统计图像中的物体数量。

pythonCopy code# 打印检测到的物体数量
print(f"检测到的物体数量: {len(contours)}")#f"{变量}"大括号内可写变量。

代码说明

  • len(contours):返回轮廓的数量,等同于检测到的物体数量。

8. 完整代码

下面是完整的代码片段,将以上步骤结合起来,完整实现物体数量检测。

pythonCopy codeimport cv2
import numpy as np

# 读取图像
img = cv2.imread('objects.jpg')

# 转为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 应用高斯模糊以减少噪声
blurred = cv2.GaussianBlur(gray, (11, 11), 0)

# 应用二值化处理(阈值化)
_, thresh = cv2.threshold(blurred, 150, 255, cv2.THRESH_BINARY_INV)

# 定义一个核(用于膨胀和腐蚀)
kernel = np.ones((3, 3), np.uint8)

# 应用膨胀操作,使目标更明显
dilated = cv2.dilate(thresh, kernel, iterations=2)

# 检测图像中的轮廓
contours, _ = cv2.findContours(dilated.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 在原图上绘制轮廓
cv2.drawContours(img, contours, -1, (0, 255, 0), 3)

# 显示检测到轮廓的图像
cv2.imshow('Contours', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 打印检测到的物体数量
print(f"检测到的物体数量: {len(contours)}")

9. 总结

通过使用OpenCV进行图像的灰度化、二值化、形态学操作以及轮廓检测,我们可以有效地检测图像中的物体数量。这种方法适用于检测具有明显边缘的物体,如硬币、螺母、细胞等。


评论
Copyright Created by DataER | 沪ICP备2024052789号-5 | 沪公网安备31010402336337号