如何解决通过利用质心之间的欧式距离来提高检测精度
我正在一个项目中,我必须检测从鸟瞰鸟瞰的视频帧中的彩色汽车 视图。
为了进行检测,我使用直方图反投影获得了一个二进制图像,该图像假定仅包含目标目标区域。
在我尝试通过对包含具有相似颜色分布的对象的视频进行测试来概括检测结果(例如我在桌子底下爬行并且看到我的T恤的一部分可见)之前,该过程一直很好。
如您所见,汽车和无关的物体都在移动,检测结果为:
如您所见,共享相似颜色分布的不相关对象显示在二进制图像中。但是,多亏了Stack溢出专家,我可以通过添加以下约束来告诉算法选择代表目标对象的Blob,从而改善检测效果:
1-矩形检查 2面积和比例检查
在上述限制下,我可以摆脱检测到的大无关对象。但是,对于小物体(请参见二进制图像),的作用不大,因为目标物体(红色小汽车)的矩形范围在(0.72和1) 之间>并且无关紧要的小对象确实落在此范围内。因此,我决定添加另一个约束条件,该约束条件是通过执行以下操作来计算每5个连续帧移动的汽车质心之间的距离以及取决于该距离的阈值:
import scipy.spatial.distance
from collections import deque
#defining the Centroid
centroids=deque(maxlen=40) #double ended queue containing the detected centroids
.
.
.
centroids.appendleft(center)
#center comes from detection process. e.g centroids=[(120,130),(125,132),...
Distance = scipy.spatial.distance.euclidean(pts1_red[0],pts1_red[5])
if D<=50:
#choose that blob
在不同的视频上进行了测试,得出质心之间的距离在0到50之间(汽车停止时为0)。
所以我的问题是:
有没有办法我可以投资此属性,以便以某种方式帮助增强检测能力,以使检测忽略T恤?,因为当汽车不再可见且无关物体停留时,它将进行计算无关物体的距离差,直到小于50为止,该距离会变小!
预先感谢
解决方法
根据OP提供的信息,这是解决此问题的一种方法。
样本图像
我创建了一些样本图像,它们大致代表了随时间推移而移动的对象。中心对象代表我们正在寻找的汽车,分类器未正确检测到其他对象。
前四个图像代表一辆汽车(中心物体)从左向右移动,以及另外两个被错误检测到的物体。在第五张图像中,汽车已移出车架,但仍存在两个错误的检测结果。第六帧包括一辆新车,进入该车时还有其他不正确的检测结果。
解决方案-代码
注释包含有关算法的信息。我们正在计算每个斑点的质心,并将其与先前检测/提取的斑点的质心进行比较。
import os
import cv2
import numpy as np
# Reading files and sorting them in the right order
all_files = os.listdir(".")
all_images = [file_name for file_name in all_files if file_name.endswith(".png")]
all_images.sort(key=lambda k: k.split(".")[0][-1])
print(all_images) #
# Initially,no centroid information is available.
previous_centroid_x = -1
previous_centroid_y = -1
DIST_THRESHOLD = 30
for i,image_name in enumerate(all_images):
rgb_image = cv2.imread(image_name)
height,width = rgb_image.shape[:2]
gray_image = cv2.cvtColor(rgb_image,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray_image,127,255,0)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
blankImage = np.zeros_like(rgb_image)
for cnt in contours:
# Refer to https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_contour_features/py_contour_features.html#moments
M = cv2.moments(cnt)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
# Refer to https://www.pyimagesearch.com/2016/04/11/finding-extreme-points-in-contours-with-opencv/
# https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_contours/py_contour_properties/py_contour_properties.html#contour-properties
extLeft = tuple(cnt[cnt[:,:,0].argmin()][0])
extRight = tuple(cnt[cnt[:,0].argmax()][0])
extTop = tuple(cnt[cnt[:,1].argmin()][0])
extBot = tuple(cnt[cnt[:,1].argmax()][0])
color = (0,255)
if i == 0: # First frame - Assuming that you can find the correct blob accurately in the first frame
# Here,I am using a simple logic of checking if the blob is close to the centre of the image.
if abs(cY - (height / 2)) < DIST_THRESHOLD: # Check if the blob centre is close to the half the image's height
previous_centroid_x = cX # Update variables for finding the next blob correctly
previous_centroid_y = cY
DIST_THRESHOLD = (extBot[1] - extTop[1]) / 2 # Update centre distance error with half the height of the blob
color = (0,0)
else:
if abs(cY - previous_centroid_y) < DIST_THRESHOLD: # Compare with previous centroid y and see if it lies within Distance threshold
previous_centroid_x = cX
previous_centroid_y = cY
color = (0,0)
cv2.drawContours(blankImage,[cnt],color,-1)
cv2.circle(blankImage,(cX,cY),3,(255,0),-1)
cv2.imwrite("result_" + image_name,blankImage)
更新阈值使算法可以跨帧跟踪对象的质心。由于对象可以上下移动一点,因此我们希望将当前帧中找到的对象的质心与上一帧中找到的汽车的质心进行匹配。
解决方案-结果
绿色-选定的斑点 红色-斑点被拒 对象中心也已标记为参考。
注意-这不是一个完美的解决方案。它有一些局限性,但可以帮助您设计出近似的解决方案。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。