目录
绘制轮廓图像
实现思路
1. 读取图像并转换为灰度图像
2. 二值化处理
3. 查找轮廓
4. 绘制轮廓
5. 显示结果
代码实现
效果展示
动态逐步显示轮廓结果
实现思路
1. 读取图像并缩放
2. 转换为灰度图像
3. 二值化处理
4. 查找轮廓
5. 动态显示轮廓
6. 显示最终结果并关闭窗口
7. 使用 Matplotlib 显示最终图像
代码实现
效果展示
物体跟踪
实现思路
整体代码
效果展示
绘制轮廓图像
实现思路
使用 OpenCV 检测图像中的轮廓并在图像上绘制轮廓,最后通过 Matplotlib 来显示处理结果。以下是代码的具体实现思路:
1. 读取图像并转换为灰度图像
image = cv2.imread('./imgs/006.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
- 首先,通过
cv2.imread()
读取指定路径下的图片文件,并将其存储在image
变量中。image
是一个彩色图像,使用 BGR 颜色格式。 - 为了简化后续的轮廓检测处理,将彩色图像转换为灰度图像,使用
cv2.cvtColor()
函数进行 BGR 到灰度的颜色空间转换。gray
变量存储灰度图像数据,灰度图像的每个像素点只有亮度信息,去除了颜色信息。
2. 二值化处理
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
- 使用
cv2.threshold()
对灰度图像进行二值化处理。二值化的原理是将图像中的像素值按照阈值进行划分,大于 127 的像素值被设置为 255(白色),小于或等于 127 的像素值被设置为 0(黑色),生成一个只有黑白两色的图像thresh
。 - 这种处理方式非常适合用于轮廓检测,因为轮廓可以在二值化的图像中更加清晰地表现出来。
3. 查找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
- 在二值化图像
thresh
上查找轮廓,使用cv2.findContours()
函数。该函数返回两个值:contours
:一个包含所有轮廓信息的列表。每个轮廓由一组点的坐标构成。hierarchy
:轮廓之间的层次结构信息。
cv2.RETR_EXTERNAL
参数指定只提取外部轮廓(不处理嵌套轮廓),而cv2.CHAIN_APPROX_SIMPLE
参数则简化了轮廓的表示,去除了冗余点。
4. 绘制轮廓
cv2.drawContours(image, contours, -1, (0, 255, 0), 3)
- 使用
cv2.drawContours()
在原始图像image
上绘制所有检测到的轮廓。函数的参数解释如下:image
:要在其上绘制轮廓的图像。contours
:包含轮廓数据的列表。-1
:表示绘制所有轮廓。如果指定特定的索引,则只绘制该特定轮廓。(0, 255, 0)
:指定轮廓的颜色为绿色(BGR 格式中的绿色)。3
:指定轮廓线的粗细为 3 像素。
5. 显示结果
plt.figure(figsize=(10, 5))
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title('Detected Contours')
plt.axis('off')
plt.show()
- 使用 Matplotlib 来显示处理后的图像。由于 OpenCV 使用 BGR 颜色格式,而 Matplotlib 使用 RGB 格式,因此需要用
cv2.cvtColor()
函数将图像颜色从 BGR 转换为 RGB。 plt.imshow()
用于显示转换后的图像,并通过plt.axis('off')
隐藏坐标轴。- 最后通过
plt.show()
函数展示出图像,图像上会标注出绿色的轮廓。
代码实现
import cv2
import matplotlib.pyplot as plt
# 读取图像并转换为灰度
image = cv2.imread('./imgs/006.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 二值化
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 绘制轮廓
cv2.drawContours(image, contours, -1, (0, 255, 0), 3)
# 显示结果
plt.figure(figsize=(10, 5))
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title('Detected Contours')
plt.axis('off')
plt.show()
效果展示
还可以但也是略显拉胯
动态逐步显示轮廓结果
实现思路
通过 OpenCV 读取并处理图像,查找其中的轮廓,然后逐步绘制每个轮廓并动态显示处理结果,最后使用 Matplotlib 显示最终效果。代码的具体步骤如下:
1. 读取图像并缩放
image = cv2.imread('./imgs/006.jpg')
首先,使用 cv2.imread()
读取指定路径下的图片文件,并存储在变量 image
中。
scale_percent = 50 # 调整比例,例如50%表示图片缩小一半
width = int(image.shape[1] * scale_percent / 100)
height = int(image.shape[0] * scale_percent / 100)
dim = (width, height)
resized_image = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
接着,将读取的图片进行缩放,使其适合显示。scale_percent
设置为 50%,表示缩小至原图像的一半。cv2.resize()
根据新的宽度和高度调整图像大小,缩放后的图像存储在 resized_image
变量中。
2. 转换为灰度图像
gray = cv2.cvtColor(resized_image, cv2.COLOR_BGR2GRAY)
将缩放后的彩色图像转换为灰度图像,因为在接下来的步骤中,轮廓检测通常是在灰度图上进行的。使用 cv2.cvtColor()
完成从 BGR(彩色)到灰度的转换。
3. 二值化处理
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
使用 cv2.threshold()
对灰度图像进行二值化处理。该函数将图像中像素值大于 127 的部分设置为 255,其他部分设置为 0,生成一个只有黑白两种颜色的图像 thresh
。这有助于后续的轮廓检测,使得轮廓更为清晰。
4. 查找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
在二值化图像上查找轮廓,使用 cv2.findContours()
函数。cv2.RETR_EXTERNAL
表示只提取最外层的轮廓,cv2.CHAIN_APPROX_SIMPLE
则减少冗余点以优化轮廓的表示。函数返回检测到的轮廓列表 contours
,以及层次信息 hierarchy
。
5. 动态显示轮廓
for cnt in contours:
# 绘制每个轮廓
cv2.drawContours(resized_image, [cnt], -1, (0, 255, 0), 3)
# 动态显示当前的结果
cv2.imshow('Contour Detection', resized_image)
# 设置等待时间,每隔500ms显示一个轮廓
cv2.waitKey(500)
在这部分,遍历所有检测到的轮廓 contours
,并使用 cv2.drawContours()
将每个轮廓绘制在缩放后的图像 resized_image
上。每次绘制完一个轮廓后,使用 cv2.imshow()
动态显示当前处理的图像结果。
cv2.waitKey(500)
控制显示的时间间隔为 500 毫秒,这使得用户可以看到轮廓逐步被绘制的过程,营造动态展示的效果。
6. 显示最终结果并关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
在所有轮廓绘制完成后,程序会停留在最后的显示结果上,直到用户按下任意键关闭窗口。cv2.destroyAllWindows()
用于关闭所有由 OpenCV 打开的窗口。
7. 使用 Matplotlib 显示最终图像
plt.figure(figsize=(10, 5))
plt.imshow(cv2.cvtColor(resized_image, cv2.COLOR_BGR2RGB))
plt.title('Detected Contours')
plt.axis('off')
plt.show()
在完成 OpenCV 的处理后,使用 Matplotlib 来显示最终的检测结果。由于 OpenCV 使用的是 BGR 颜色空间,而 Matplotlib 使用 RGB,因此需要用 cv2.cvtColor()
将图像颜色从 BGR 转换为 RGB 格式。plt.imshow()
显示处理后的图像,并通过 plt.axis('off')
去掉坐标轴。
代码实现
import cv2
import matplotlib.pyplot as plt
# 读取图像并转换为灰度
image = cv2.imread('./imgs/006.jpg')
# 缩放图片,使窗口大小合适
scale_percent = 50 # 调整比例,例如50%表示图片缩小一半
width = int(image.shape[1] * scale_percent / 100)
height = int(image.shape[0] * scale_percent / 100)
dim = (width, height)
resized_image = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
# 转换为灰度
gray = cv2.cvtColor(resized_image, cv2.COLOR_BGR2GRAY)
# 二值化
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 动态显示每个轮廓
for cnt in contours:
# 绘制每个轮廓
cv2.drawContours(resized_image, [cnt], -1, (0, 255, 0), 3)
# 动态显示当前的结果
cv2.imshow('Contour Detection', resized_image)
# 设置等待时间,每隔500ms显示一个轮廓
cv2.waitKey(500)
# 显示最终结果并关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
# 使用matplotlib显示最终图像
plt.figure(figsize=(10, 5))
plt.imshow(cv2.cvtColor(resized_image, cv2.COLOR_BGR2RGB))
plt.title('Detected Contours')
plt.axis('off')
plt.show()
效果展示
这里的效果其实就是绘制轮廓图像然后让他一点点的绘制出来,就是这么个效果,动图不好截图,我就不再展示了。
物体跟踪
实现思路
- 摄像头捕获:
cv2.VideoCapture(0)
打开系统默认摄像头并开始捕获视频流。 - 背景减法:通过
cv2.createBackgroundSubtractorMOG2()
来生成前景掩码,用于检测运动物体。 - 轮廓检测:使用
cv2.findContours()
检测运动物体的轮廓。 - 物体跟踪:通过
cv2.boundingRect()
为每个符合条件的轮廓绘制边界框,实现物体的实时跟踪。 - 退出条件:按下 'q' 键可退出循环并停止摄像头。
整体代码
import cv2
# 初始化视频捕获,打开摄像头
cap = cv2.VideoCapture(0)
# 创建背景减法器
fgbg = cv2.createBackgroundSubtractorMOG2()
while True:
# 读取摄像头帧
ret, frame = cap.read()
if not ret:
break
# 对帧进行背景减除,获取前景掩码
fgmask = fgbg.apply(frame)
# 查找前景中的轮廓
contours, _ = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 遍历每个轮廓,进行物体跟踪
for cnt in contours:
# 忽略较小的轮廓,避免噪声
if cv2.contourArea(cnt) > 500:
# 获取轮廓的边界框
x, y, w, h = cv2.boundingRect(cnt)
# 绘制边界框
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 在物体上显示跟踪的文字
cv2.putText(frame, 'Tracking Object', (x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)
# 显示视频流
cv2.imshow('Object Tracking', frame)
# 按下 'q' 键退出循环
if cv2.waitKey(30) & 0xFF == ord('q'):
break
# 释放资源并关闭窗口
cap.release()
cv2.destroyAllWindows()