OpenCV:带降噪的对象跟踪
OpenCV: Object tracking with denoising
我正在尝试提取一个蓝色物体,它与 https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_colorspaces/py_colorspaces.html#object-tracking
中描述的非常相似
这里是要提取三个蓝色形状的原始图像示例:
捕获的图像有噪声并且未过滤的形状检测 returns 成百上千个 "blue" 形状。为了缓解这种情况,我应用了以下步骤:
- 在过滤图像之前对其进行模糊处理,从而产生封闭的表面
- 将蒙版图像(
bitwise_and
之后)转换回灰度
- 应用 OTSU 阈值
- 最后,检测轮廓
完整代码为:
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while(True):
ret, frame = cap.read()
blur = cv2.GaussianBlur(frame, (15, 15), 0)
hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)
lower_red = np.array([115, 50, 50])
upper_red = np.array([125, 255, 255])
mask = cv2.inRange(hsv, lower_red, upper_red)
blue = cv2.bitwise_and(blur, blur, mask=mask)
gray = cv2.cvtColor(blue, cv2.COLOR_BGR2GRAY)
(T, ted) = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)
im2, contours, hierarchy = cv2.findContours(
ted, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
cv2.drawContours(frame, [cnt], 0, (0, 255, 0), 3)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(frame, str(len(contours)), (10, 500), font, 2, (0, 0, 255), 2, cv2.LINE_AA)
cv2.imshow('mask', mask)
cv2.imshow('blue', blue)
cv2.imshow('grey', gray)
cv2.imshow('thresholded', ted)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
不幸的是,还剩下 6-7 个轮廓,而应该是三个。
如何进一步优化图像处理以仅获得三种形状?
您可以结合使用形态学运算和连通分量分析:
- 对灰度图像应用侵蚀:https://docs.opencv.org/2.4/modules/imgproc/doc/filtering.html?highlight=erode#erode
- 求连通分量,函数cv::connectedComponents (https://docs.opencv.org/3.1.0/d3/dc0/group__imgproc__shape.html#gac2718a64ade63475425558aa669a943a)
- 保留面积大于给定阈值的连通分量。
- 扩大生成的蒙版:https://docs.opencv.org/2.4/modules/imgproc/doc/filtering.html?highlight=dilate#dilate
如果您要查找的形状是特定形状(例如形状),您可以使用一些形状描述符。
最后,我建议您尝试用双边滤波器替换高斯滤波器(https://docs.opencv.org/3.0-beta/modules/imgproc/doc/filtering.html#bilateralfilter) to better preserve the shapes. If you want an even better filter, have a look at this tutorial on NL-means filter (https://docs.opencv.org/3.3.1/d5/d69/tutorial_py_non_local_means.html)
我正在尝试提取一个蓝色物体,它与 https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_colorspaces/py_colorspaces.html#object-tracking
中描述的非常相似这里是要提取三个蓝色形状的原始图像示例:
捕获的图像有噪声并且未过滤的形状检测 returns 成百上千个 "blue" 形状。为了缓解这种情况,我应用了以下步骤:
- 在过滤图像之前对其进行模糊处理,从而产生封闭的表面
- 将蒙版图像(
bitwise_and
之后)转换回灰度 - 应用 OTSU 阈值
- 最后,检测轮廓
完整代码为:
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while(True):
ret, frame = cap.read()
blur = cv2.GaussianBlur(frame, (15, 15), 0)
hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)
lower_red = np.array([115, 50, 50])
upper_red = np.array([125, 255, 255])
mask = cv2.inRange(hsv, lower_red, upper_red)
blue = cv2.bitwise_and(blur, blur, mask=mask)
gray = cv2.cvtColor(blue, cv2.COLOR_BGR2GRAY)
(T, ted) = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)
im2, contours, hierarchy = cv2.findContours(
ted, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
cv2.drawContours(frame, [cnt], 0, (0, 255, 0), 3)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(frame, str(len(contours)), (10, 500), font, 2, (0, 0, 255), 2, cv2.LINE_AA)
cv2.imshow('mask', mask)
cv2.imshow('blue', blue)
cv2.imshow('grey', gray)
cv2.imshow('thresholded', ted)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
不幸的是,还剩下 6-7 个轮廓,而应该是三个。
如何进一步优化图像处理以仅获得三种形状?
您可以结合使用形态学运算和连通分量分析:
- 对灰度图像应用侵蚀:https://docs.opencv.org/2.4/modules/imgproc/doc/filtering.html?highlight=erode#erode
- 求连通分量,函数cv::connectedComponents (https://docs.opencv.org/3.1.0/d3/dc0/group__imgproc__shape.html#gac2718a64ade63475425558aa669a943a)
- 保留面积大于给定阈值的连通分量。
- 扩大生成的蒙版:https://docs.opencv.org/2.4/modules/imgproc/doc/filtering.html?highlight=dilate#dilate
如果您要查找的形状是特定形状(例如形状),您可以使用一些形状描述符。
最后,我建议您尝试用双边滤波器替换高斯滤波器(https://docs.opencv.org/3.0-beta/modules/imgproc/doc/filtering.html#bilateralfilter) to better preserve the shapes. If you want an even better filter, have a look at this tutorial on NL-means filter (https://docs.opencv.org/3.3.1/d5/d69/tutorial_py_non_local_means.html)