OpenCV圆检测中的抖动

14ifxucb  于 2023-03-19  发布在  其他
关注(0)|答案(1)|浏览(205)

我正在做一个项目,我需要确定从摄像机实时饲料中圆圈的位置。
我已经设法让这种运行,但我得到了一个奇怪的抖动与识别的圆圈,有时一个圆圈是不承认在所有。
下面是一个例子:

我用于编辑图像的功能是:

def preprocess_image(self):
        self.image = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        
        # apply GuassianBlur to reduce noise. medianBlur is also added for smoothening, reducing noise.
        self.image = cv2.GaussianBlur(self.image,(5,5),0);
        self.image = cv2.medianBlur(self.image,5)
        
        # Adaptive Guassian Threshold is to detect sharp edges in the Image. For more information Google it.
        self.image = cv2.adaptiveThreshold(self.image,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
                cv2.THRESH_BINARY,11,3.5)
        
        kernel = np.ones((2,2),np.uint8)
        self.image = cv2.erode(self.image,kernel,iterations = 1) # gray = erosion
        self.image = cv2.dilate(self.image,kernel,iterations = 1) # gray = dilation

检测圆的方法为:

def get_circles(self):
        rows = self.image.shape[0] # width of the image (1280)
        # detect circles in the image
        self.circles = cv2.HoughCircles(
            self.image, 
            cv2.HOUGH_GRADIENT, 
            1, 
            rows / 8, 
            param1=self.parameters["param1"], 
            param2=self.parameters["param2"], 
            minRadius=self.parameters["minRadius"], 
            maxRadius=self.parameters["maxRadius"]
        )

        if self.circles is None: return None
        self.circles = np.round(self.circles[0, :]).astype("int")

如何消除这种抖动以及有时无法识别圆圈的问题?

piok6c0g

piok6c0g1#

我解决了这个问题,放弃了hough变换,而是按照Christoph拉克维茨的建议,使用connectedComponentsWithStats将圆圈变换为黑色斑点。
然后我使用SimpleBlobDetector来检测想要的圆。
这比以前好用多了!
下面是我使用的代码:

import cv2
import numpy as np

def detect_circles(image):
    _, labels, _, _ = cv2.connectedComponentsWithStats(image)

    # Extract the pixels associated with the current label
    label_mask = np.zeros(image.shape, dtype=np.uint8)
    label_mask[labels == 1] = 255

    params = cv2.SimpleBlobDetector_Params()

    # Set Area filtering parameters
    params.filterByArea = True
    params.minArea = 1000
    params.maxArea = 10000

    params.filterByCircularity = True
    params.minCircularity = .7

    # Create a detector with the parameters
    detector = cv2.SimpleBlobDetector_create(params)

    # Detect blobs
    keypoints = detector.detect(label_mask)
    circles = []
    for kp in keypoints:
        circles.append(np.array([int(kp.pt[0]), int(kp.pt[1]), int(kp.size / 2)]))
    
    return circles

cap = cv2.VideoCapture("<your sample video>")

while True:
    ret, frame = cap.read()
    if np.sum(frame) == 0:[![enter image description here][1]][1]
        break

    detect_circles(frame)

    # draw the circles on image here 

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break   

cv2.destroyAllWindows()
cap.release()

这就是结果

相关问题