系列文章目录
Python 检测学习:方形物体实时抓捕(简易)
前言
进行一个简易的方形物体检测,可能会存在误差出现,还需要进一步的详细调整。
一、项目需求
实时从摄像头中检测正方形物体,在检测到的物体周围绘制轮廓,并在画面中显示检测数量
二、代码分析
1.思路分析
1.1导入模块
-
import cv2:导入OpenCV库,用于图像处理和计算机视觉任务。
-
import numpy as np:导入NumPy库,通常用于数学运算,但在这段代码中似乎没有直接使用。
1.2定义is_square函数
- 该函数接收一个轮廓(contour)作为参数。
- 使用cv2.arcLength计算轮廓的周长。
- 使用cv2.approxPolyDP对轮廓进行多边形近似,参数0.02 * perimeter用于确定多边形的精度。
- 如果近似后的多边形有4个顶点并且是凸的(使用cv2.isContourConvex判断),则认为它可能是一个正方形。
1.3定义main函数
- 使用cv2.VideoCapture(0)打开默认摄像头。
- 使用循环读取摄像头的每一帧图像。
- 如果无法读取帧,打印错误信息并退出循环。
- 将读取的帧转换为灰度图像,使用cv2.cvtColor。
- 对灰度图像应用高斯模糊,使用cv2.GaussianBlur,以减少图像噪声。
- 使用Canny算法进行边缘检测,使用cv2.Canny。
- 使用cv2.findContours查找边缘检测后的轮廓。
- 遍历找到的轮廓,使用is_square函数检测是否为正方形,如果是,则添加到squares列表中。
- 在原图上绘制检测到的正方形轮廓,使用cv2.drawContours。
- 在图像上显示检测到的正方形数量,使用cv2.putText。
- 使用cv2.imshow显示处理后的图像。
- 如果按下’q’键,则退出循环。
- 循环结束后,释放摄像头并关闭所有OpenCV窗口。
1.4注意事项
- is_square函数中对正方形的判断较为简单,可能需要根据实际情况调整参数以提高检测准确性。
- 程序没有异常处理机制,例如摄像头打开失败或读取失败时,程序会直接退出,可能需要添加更复杂的错误处理逻辑。
- 程序在检测到正方形时,只是简单地绘制了轮廓,没有进一步的处理或分析。
2.源代码
代码如下:
# 导入OpenCV库,用于图像处理和计算机视觉任务
import cv2
# 导入NumPy库,通常用于数学运算,但在这段代码中似乎没有直接使用
import numpy as np
# 定义一个函数,用于判断给定轮廓是否为正方形
def is_square(contour):
# 计算轮廓的周长
perimeter = cv2.arcLength(contour, True)
# 使用轮廓的周长作为精度参数,对轮廓进行多边形近似
approx = cv2.approxPolyDP(contour, 0.02 * perimeter, True)
# 如果多边形的顶点数为4,并且是凸四边形,则可能是正方形
if len(approx) == 4 and cv2.isContourConvex(approx):
return True
# 如果不是4个顶点或者不是凸四边形,则返回False
return False
# 定义主函数
def main():
# 尝试打开摄像头,参数0通常表示默认的摄像头
cap = cv2.VideoCapture(0)
# 检查摄像头是否成功打开
if not cap.isOpened():
print("无法打开摄像头")
return
# 循环直到用户决定退出
while True:
# 从摄像头读取一帧图像
ret, frame = cap.read()
# 如果读取失败,则打印错误信息并退出循环
if not ret:
print("无法读取帧")
break
# 将图像转换为灰度图像,这有助于减少处理时间和提高某些算法的效果
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 对灰度图像进行高斯模糊,以减少图像噪声,提高边缘检测的准确性
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# 使用Canny算法进行边缘检测,50和150是阈值参数
edges = cv2.Canny(blurred, 50, 150)
# 查找边缘检测图像中的轮廓
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 初始化一个列表,用于存储检测到的正方形轮廓
squares = []
# 遍历所有轮廓
for contour in contours:
# 如果轮廓是正方形,则添加到列表中
if is_square(contour):
squares.append(contour)
# 遍历检测到的正方形轮廓,并在原图上绘制轮廓
for square in squares:
# 计算轮廓的面积和周长,虽然这里没有使用这些值,但可以用于进一步分析
area = cv2.contourArea(square)
perimeter = cv2.arcLength(square, True)
# 使用绿色线条在原图上绘制轮廓
cv2.drawContours(frame, [square], -1, (0, 255, 0), 2)
# 在图像的左上角显示检测到的正方形数量
cv2.putText(frame, f'Objects: {len(squares)}', (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
# 显示处理后的图像
cv2.imshow('Frame', frame)
# 等待1ms,如果按下'q'键,则退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放摄像头资源
cap.release()
# 关闭所有OpenCV创建的窗口
cv2.destroyAllWindows()
# 程序入口
if __name__ == '__main__':
main()
总结
以上代码是一个完整的Python脚本,用于实时从摄像头中检测正方形物体,并在检测到的物体周围绘制轮廓。代码中包含了基本的图像处理步骤,如灰度转换、高斯模糊、Canny边缘检测和轮廓查找。此外,还定义了一个辅助函数is_square来判断轮廓是否为正方形。程序运行时会显示处理后的图像,并在左上角显示检测到的正方形数量。用户可以通过按’q’键退出程序。