gpt4 book ai didi

python - cv2.HoughCircles 的结果不可靠

转载 作者:太空狗 更新时间:2023-10-29 20:52:24 32 4
gpt4 key购买 nike

我有一个包含 5 个油滴的视频,我正在尝试使用 cv2.HoughCircles 来找到它们。

这是我的代码:

import cv, cv2
import numpy as np

foreground1 = cv2.imread("foreground1.jpg")
vid = cv2.VideoCapture("NB14.avi")

cv2.namedWindow("video")
cv2.namedWindow("canny")
cv2.namedWindow("blur")

while True:
ret, frame = vid.read()
subtract1 = cv2.subtract( foreground1, frame)
framegrey1 = cv2.cvtColor(subtract1, cv.CV_RGB2GRAY)
blur = cv2.GaussianBlur(framegrey1, (0,0), 2)
circles = cv2.HoughCircles(blur, cv2.cv.CV_HOUGH_GRADIENT, 2, 10, np.array([]), 40, 80, 5, 100)
if circles is not None:
for c in circles[0]:
cv2.circle(frame, (c[0],c[1]), c[2], (0,255,0),2)
edges = cv2.Canny( blur, 40, 80 )
cv2.imshow("video", frame)
cv2.imshow("canny", edges)
cv2.imshow("blur", blur)
key = cv2.waitKey(30)

我会说canny边缘检测器看起来很好,而霍夫变换的结果很不稳定,每一帧都会提供不同的结果。

例子:

frame1

frame2

frame3

我一直在研究参数,老实说我不知道​​如何获得更稳定的结果。

最佳答案

最初我虽然在你的油滴中不会有重叠,但有。因此,Hough 确实可以通过一种很好的方法在这里使用,但我在将 RANSAC 与它结合时有更好的经验。我建议探索它,但在这里我将提供一些与此不同的东西。

首先,我无法执行您所做的背景减法,因为我没有这个“foreground1.jpg”图像(因此可以轻松改进结果)。我也不关心画圆圈,但你可以这样做,我只是画出我认为是圆圈的对象的边界。

所以,首先让我们假设没有重叠。然后找到图像中的边缘(简单),通过 Otsu 将边缘检测器的响应二值化,填充孔,最后测量圆度就足够了。现在如果有重叠,我们可以结合使用 Watershed 变换和 Distance 变换来分离液滴。那么问题是你不会得到真正的圆形物体,我不太关心这个,但你可以对此进行调整。

在下面的代码中,我还必须使用 scipy 来标记连接的组件(对于构建分水岭的标记很重要),因为 OpenCV 缺少这一点。代码并不十分简短,但应该易于理解。此外,鉴于完整的当前代码,不需要循环检查,因为在 Watershed 分割之后,只剩下您之后的对象。最后,有一些基于到对象中心的粗略距离的简单跟踪。

import sys
import cv2
import math
import numpy
from scipy.ndimage import label

pi_4 = 4*math.pi

def segment_on_dt(img):
border = img - cv2.erode(img, None)

dt = cv2.distanceTransform(255 - img, 2, 3)
dt = ((dt - dt.min()) / (dt.max() - dt.min()) * 255).astype(numpy.uint8)
_, dt = cv2.threshold(dt, 100, 255, cv2.THRESH_BINARY)

lbl, ncc = label(dt)
lbl[border == 255] = ncc + 1

lbl = lbl.astype(numpy.int32)
cv2.watershed(cv2.cvtColor(img, cv2.COLOR_GRAY2RGB), lbl)
lbl[lbl < 1] = 0
lbl[lbl > ncc] = 0

lbl = lbl.astype(numpy.uint8)
lbl = cv2.erode(lbl, None)
lbl[lbl != 0] = 255
return lbl


def find_circles(frame):
frame_gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
frame_gray = cv2.GaussianBlur(frame_gray, (5, 5), 2)

edges = frame_gray - cv2.erode(frame_gray, None)
_, bin_edge = cv2.threshold(edges, 0, 255, cv2.THRESH_OTSU)
height, width = bin_edge.shape
mask = numpy.zeros((height+2, width+2), dtype=numpy.uint8)
cv2.floodFill(bin_edge, mask, (0, 0), 255)

components = segment_on_dt(bin_edge)

circles, obj_center = [], []
contours, _ = cv2.findContours(components,
cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

for c in contours:
c = c.astype(numpy.int64) # XXX OpenCV bug.
area = cv2.contourArea(c)
if 100 < area < 3000:
arclen = cv2.arcLength(c, True)
circularity = (pi_4 * area) / (arclen * arclen)
if circularity > 0.5: # XXX Yes, pretty low threshold.
circles.append(c)
box = cv2.boundingRect(c)
obj_center.append((box[0] + (box[2] / 2), box[1] + (box[3] / 2)))

return circles, obj_center

def track_center(objcenter, newdata):
for i in xrange(len(objcenter)):
ostr, oc = objcenter[i]
best = min((abs(c[0]-oc[0])**2+abs(c[1]-oc[1])**2, j)
for j, c in enumerate(newdata))
j = best[1]
if i == j:
objcenter[i] = (ostr, new_center[j])
else:
print "Swapping %s <-> %s" % ((i, objcenter[i]), (j, objcenter[j]))
objcenter[i], objcenter[j] = objcenter[j], objcenter[i]


video = cv2.VideoCapture(sys.argv[1])

obj_center = None
while True:
ret, frame = video.read()
if not ret:
break

circles, new_center = find_circles(frame)
if obj_center is None:
obj_center = [(str(i + 1), c) for i, c in enumerate(new_center)]
else:
track_center(obj_center, new_center)

for i in xrange(len(circles)):
cv2.drawContours(frame, circles, i, (0, 255, 0))
cstr, ccenter = obj_center[i]
cv2.putText(frame, cstr, ccenter, cv2.FONT_HERSHEY_COMPLEX, 0.5,
(255, 255, 255), 1, cv2.CV_AA)

cv2.imshow("result", frame)
cv2.waitKey(10)
if len(circles[0]) < 5:
print "lost something"

这适用于您的整个视频,这里有两个示例:

enter image description here enter image description here

关于python - cv2.HoughCircles 的结果不可靠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14609980/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com