【问题标题】:OpenCV Python single (rather than multiple) blob tracking?OpenCV Python 单个(而不是多个)blob 跟踪?
【发布时间】:2012-10-08 05:56:39
【问题描述】:

我一直在尝试通过 Python 上的 OpenCV 进行单色斑点跟踪。 下面的代码正在工作,但它找到了所有跟踪像素的质心,而不仅仅是最大斑点的质心。这是因为我正在拍摄所有像素的时刻,但我不确定如何为轨迹着色。 我有点坚持我需要做些什么才能使它成为一个单一的 blob 跟踪器而不是一个多 blob 平均器。

代码如下:

#! /usr/bin/env python 

#if using newer versions of opencv, just "import cv"
import cv2.cv as cv

color_tracker_window = "Color Tracker" 

class ColorTracker: 

def __init__(self): 
    cv.NamedWindow( color_tracker_window, 1 ) 
    self.capture = cv.CaptureFromCAM(0) 

def run(self): 
    while True: 
        img = cv.QueryFrame( self.capture ) 

        #blur the source image to reduce color noise 
        cv.Smooth(img, img, cv.CV_BLUR, 3); 

        #convert the image to hsv(Hue, Saturation, Value) so its  
        #easier to determine the color to track(hue) 
        hsv_img = cv.CreateImage(cv.GetSize(img), 8, 3) 
        cv.CvtColor(img, hsv_img, cv.CV_BGR2HSV) 

        #limit all pixels that don't match our criteria, in this case we are  
        #looking for purple but if you want you can adjust the first value in  
        #both turples which is the hue range(120,140).  OpenCV uses 0-180 as  
        #a hue range for the HSV color model 
        thresholded_img =  cv.CreateImage(cv.GetSize(hsv_img), 8, 1) 
        cv.InRangeS(hsv_img, (120, 80, 80), (140, 255, 255), thresholded_img) 

        #determine the objects moments and check that the area is large  
        #enough to be our object 
        moments = cv.Moments(thresholded_img, 0) 
        area = cv.GetCentralMoment(moments, 0, 0) 

        #there can be noise in the video so ignore objects with small areas 
        if(area > 100000): 
            #determine the x and y coordinates of the center of the object 
            #we are tracking by dividing the 1, 0 and 0, 1 moments by the area 
            x = cv.GetSpatialMoment(moments, 1, 0)/area 
            y = cv.GetSpatialMoment(moments, 0, 1)/area 

            #print 'x: ' + str(x) + ' y: ' + str(y) + ' area: ' + str(area) 

            #create an overlay to mark the center of the tracked object 
            overlay = cv.CreateImage(cv.GetSize(img), 8, 3) 

            cv.Circle(overlay, (x, y), 2, (255, 255, 255), 20) 
            cv.Add(img, overlay, img) 
            #add the thresholded image back to the img so we can see what was  
            #left after it was applied 
            cv.Merge(thresholded_img, None, None, None, img) 

        #display the image  
        cv.ShowImage(color_tracker_window, img) 

        if cv.WaitKey(10) == 27: 
            break 

if __name__=="__main__": 
    color_tracker = ColorTracker() 
    color_tracker.run() 

【问题讨论】:

    标签: python opencv blob color-tracking


    【解决方案1】:

    你需要这样做:

    1) 使用 inRange 函数获取阈值图像,您可以应用一些侵蚀和膨胀来去除小的噪声粒子。这将有助于提高处理速度。

    2) 使用“findContours”功能查找轮廓

    3) 使用 'contourArea' 函数查找轮廓区域并选择具有最大面积的区域。

    4) 现在像你一样找到它的中心,并跟踪它。

    以下是新 cv2 模块中的示例代码:

    import cv2
    import numpy as np
    
    # create video capture
    cap = cv2.VideoCapture(0)
    
    while(1):
    
        # read the frames
        _,frame = cap.read()
    
        # smooth it
        frame = cv2.blur(frame,(3,3))
    
        # convert to hsv and find range of colors
        hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
        thresh = cv2.inRange(hsv,np.array((0, 80, 80)), np.array((20, 255, 255)))
        thresh2 = thresh.copy()
    
        # find contours in the threshold image
        contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
    
        # finding contour with maximum area and store it as best_cnt
        max_area = 0
        for cnt in contours:
            area = cv2.contourArea(cnt)
            if area > max_area:
                max_area = area
                best_cnt = cnt
    
        # finding centroids of best_cnt and draw a circle there
        M = cv2.moments(best_cnt)
        cx,cy = int(M['m10']/M['m00']), int(M['m01']/M['m00'])
        cv2.circle(frame,(cx,cy),5,255,-1)
    
        # Show it, if key pressed is 'Esc', exit the loop
        cv2.imshow('frame',frame)
        cv2.imshow('thresh',thresh2)
        if cv2.waitKey(33)== 27:
            break
    
    # Clean up everything before leaving
    cv2.destroyAllWindows()
    cap.release()
    

    您可以在此处找到一些关于跟踪彩色对象的示例:https://github.com/abidrahmank/OpenCV-Python/tree/master/Other_Examples

    另外,尝试使用新的 cv2 接口。它比旧的 cv 更简单、更快。更多详情,请查看:What is different between all these OpenCV Python interfaces?

    【讨论】:

    • 当我试图找到轮廓区域时出现错误,它说函数 cv.ContourArea(contour) 不起作用,因为轮廓必须是 CvSeq、CvArr 或数字序列
    • nvm 我只需要将其设为 cv.ContourArea(list(contour))
    【解决方案2】:

    阈值化后,使用 blob 检测或 cvfindcontours 获取单个 blob。

    【讨论】:

      猜你喜欢
      • 2017-04-25
      • 2011-06-21
      • 2011-03-23
      • 2013-01-10
      • 2018-02-01
      • 2021-02-25
      • 1970-01-01
      • 2021-11-27
      相关资源
      最近更新 更多