Ejemplo n.º 1
0
 def __init__(self, frame):
     self.blob_image = opencv.cvCloneImage(frame.iplimage)
     self.blob_gray = opencv.cvCreateImage(opencv.cvGetSize(self.blob_image), 8, 1)
     self.blob_mask = opencv.cvCreateImage(opencv.cvGetSize(self.blob_image), 8, 1)
     opencv.cvSet(self.blob_mask, 1)
     opencv.cvCvtColor(self.blob_image, self.blob_gray, opencv.CV_BGR2GRAY)
     # opencv.cvEqualizeHist(self.blob_gray, self.blob_gray)
     # opencv.cvThreshold(self.blob_gray, self.blob_gray, frame.thresh, 255, opencv.CV_THRESH_BINARY)
     # opencv.cvThreshold(self.blob_gray, self.blob_gray, frame.thresh, 255, opencv.CV_THRESH_TOZERO)
     opencv.cvThreshold(self.blob_gray, self.blob_gray, frame.bthresh, 255, frame.bthreshmode)
     # opencv.cvAdaptiveThreshold(self.blob_gray, self.blob_gray, 255, opencv.CV_ADAPTIVE_THRESH_MEAN_C, opencv.CV_THRESH_BINARY_INV)
     self._frame_blobs = CBlobResult(self.blob_gray, self.blob_mask, 100, True)
     self._frame_blobs.filter_blobs(10, 10000)
     self.count = self._frame_blobs.GetNumBlobs()
     self.items = []
     for i in range(self.count):
         self.items.append(self._frame_blobs.GetBlob(i))
Ejemplo n.º 2
0
class Blobs:
    
    def __init__(self, frame):
        self.blob_image = opencv.cvCloneImage(frame.iplimage)
        self.blob_gray = opencv.cvCreateImage(opencv.cvGetSize(self.blob_image), 8, 1)
        self.blob_mask = opencv.cvCreateImage(opencv.cvGetSize(self.blob_image), 8, 1)
        opencv.cvSet(self.blob_mask, 1)        
        opencv.cvCvtColor(self.blob_image, self.blob_gray, opencv.CV_BGR2GRAY)
        #opencv.cvEqualizeHist(self.blob_gray, self.blob_gray)
        #opencv.cvThreshold(self.blob_gray, self.blob_gray, frame.thresh, 255, opencv.CV_THRESH_BINARY)	
        #opencv.cvThreshold(self.blob_gray, self.blob_gray, frame.thresh, 255, opencv.CV_THRESH_TOZERO)
        opencv.cvThreshold(self.blob_gray, self.blob_gray, frame.bthresh, 255, frame.bthreshmode)
        #opencv.cvAdaptiveThreshold(self.blob_gray, self.blob_gray, 255, opencv.CV_ADAPTIVE_THRESH_MEAN_C, opencv.CV_THRESH_BINARY_INV)
        self._frame_blobs = CBlobResult(self.blob_gray, self.blob_mask, 100, True)
        self._frame_blobs.filter_blobs(10, 10000)
        self.count = self._frame_blobs.GetNumBlobs()
        self.items = []
        for i in range(self.count):
            self.items.append(self._frame_blobs.GetBlob(i)) 
Ejemplo n.º 3
0
        frame = highgui.cvQueryFrame(capture)
        if frame is None:
            # no image captured... end the processing
            break

        # mirror the captured image
        cv.cvFlip(frame, None, 1)

        cv.cvCvtColor(frame, my_grayscale, cv.CV_RGB2GRAY)
        cv.cvThreshold(my_grayscale, my_grayscale, 128, 255,
                       cv.CV_THRESH_BINARY)
        if not blob_overlay:
            # Convert black-and-white version back into three-color representation
            cv.cvCvtColor(my_grayscale, frame, cv.CV_GRAY2RGB)

        myblobs = CBlobResult(my_grayscale, mask, 100, True)

        myblobs.filter_blobs(10, 10000)
        blob_count = myblobs.GetNumBlobs()

        for i in range(blob_count):

            my_enumerated_blob = myblobs.GetBlob(i)
            #		print "%d: Area = %d" % (i, my_enumerated_blob.Area())
            my_enumerated_blob.FillBlob(frame, hsv2rgb(i * 180.0 / blob_count),
                                        0, 0)

        # we can now display the images
        highgui.cvShowImage('Blob View', frame)

        # handle events
Ejemplo n.º 4
0
def main():
    if len(sys.argv) == 1:
        print 'Usage: %s [inputfile]' % sys.argv[0]
        sys.exit(1)

    # initialize window
    cvNamedWindow('threshold', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('threshold', 10, 10)

    cvNamedWindow('combined', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('combined', 10, 10)


    cvNamedWindow('video', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('video', 10, 10)

    cvNamedWindow('flow', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('flow', 500, 10)

    cvNamedWindow('edges', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('edges', 500, 10)

    capture = cvCreateFileCapture(sys.argv[1])
    if not capture: print 'Error opening capture'; sys.exit(1)

    # Load bg image
    bg = cvLoadImage('bg.png')

    # Discard some frames
    cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES,
                         #8276399)
                         7919999)
    #for i in xrange(2300):
    #    cvGrabFrame(capture)

    #print cvGetCaptureProperty(capture, 
    #                           CV_CAP_PROP_POS_FRAMES)

    frame = cvQueryFrame(capture)
    frame_size = cvGetSize(frame)

    # vars for playback
    fps = 25
    play = True
    velx = cvCreateImage(frame_size, IPL_DEPTH_32F, 1)
    vely = cvCreateImage(frame_size, IPL_DEPTH_32F, 1)
    combined = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    prev = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    curr = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    frame_sub = cvCreateImage(frame_size, IPL_DEPTH_8U, 3)

    flow = cvCreateImage(frame_size, IPL_DEPTH_8U, 3)

    edges = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    prev_edges = None
    storage = cvCreateMemStorage(0)

    blob_mask = cvCreateImage (frame_size, IPL_DEPTH_8U, 1)
    cvSet(blob_mask, 1)

    hough_in = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    hough_storage = cvCreateMat( 100, 1, CV_32FC3 )

    seg_mask = cvCreateImage(frame_size, IPL_DEPTH_32F, 1)
    seg_storage = cvCreateMemStorage(0)

    kf_near = cvCreateKalman(4, 2, 0)
    kf_far = cvCreateKalman(4, 2, 0)
    kf_ball = cvCreateKalman(4, 2, 0)

    for kalman in [kf_near, kf_far, kf_ball]:
        # transition matrix F is initialized to identity
        # want F = [1 0 1 0
        #           0 1 0 1
        #           0 0 1 0
        #           0 0 0 1]
        # because x1 = x coordinate and x3 = d/dt x1
        #         x2 = y coordinate and x4 = d/dt x3
        kalman.transition_matrix[0,2] = 1
        kalman.transition_matrix[1,3] = 1
        cvSetIdentity(kalman.measurement_matrix, 1)
        cvSetIdentity(kalman.process_noise_cov, 1e-5)
        cvSetIdentity(kalman.measurement_noise_cov, 1e-1)
        cvSetIdentity(kalman.error_cov_post, 1)

    cvSetIdentity(kf_ball.process_noise_cov, 1e-3)

    # initialize random number generator
    rng = cvRNG()

    # x_k = state variables
    x_ball = cvCreateMat(4, 1, CV_32FC1)
    cvZero(x_ball)
    cvZero(kf_ball.state_post)
    x_near = cvCreateMat(4, 1, CV_32FC1)
    cvZero(x_near)
    cvZero(kf_near.state_post)

    # w_k = noise
    w_k = cvCreateMat(4, 1, CV_32FC1)

    # z_k = measurements
    z_k = cvCreateMat(2, 1, CV_32FC1)


    frame_count = 0
    ball_count = 0
    present_count = 0
    present = []
    while frame_count<585:

        if play:
            frame_count += 1

            frame = cvQueryFrame(capture)

            start_time=time.clock()
            cvSub(frame, bg, frame_sub)

            '''#detect people
            found = list(cvHOGDetectMultiScale(frame, storage, win_stride=(8,8),
                padding=(32,32), scale=1.05, group_threshold=2))
            for r in found:
                (rx, ry), (rw, rh) = r
                tl = (rx + int(rw*0.1), ry + int(rh*0.07))
                br = (rx + int(rw*0.9), ry + int(rh*0.87))
                cvRectangle(frame, tl, br, (0, 255, 0), 3)
            '''
            '''
            #color thresholding
            hsv = cvCreateImage(frame_size, IPL_DEPTH_8U, 3);
            cvCvtColor(frame, hsv, CV_BGR2HSV)
            mask = cvCreateMat(frame_size.height, frame_size.width, 
                                CV_8UC1)
            cvInRangeS(hsv, (0.03*256, 0.2*256, 0.6*256, 0),
                        (0.16*256, 1.0*256, 1.0*256, 0), mask)
            cvShowImage('threshold', mask)
            '''

            #optical flow method
            # store previous frame
            prev, curr = curr, prev
            # convert next frame to single channel grayscale
            cvCvtColor(frame_sub, curr, CV_BGR2GRAY)
            #cvCalcOpticalFlowLK(prev, curr, (3,3), velx, vely)
            #cvThreshold(velx, velx, 8.0, 0, CV_THRESH_TOZERO)
            cvCalcOpticalFlowHS(prev, curr, 1, velx, vely, 0.5,
                                 (CV_TERMCRIT_ITER, 10, 0))
            cvThreshold(velx, velx, 0.5, 0, CV_THRESH_TOZERO)
            cvThreshold(vely, vely, 0.5, 0, CV_THRESH_TOZERO)
            cvErode(vely, vely, 
                     cvCreateStructuringElementEx(2, 2, 0, 0, 
                                                   CV_SHAPE_ELLIPSE))
            cvAdd(vely, velx, vely)
            cvShowImage('flow', vely)

            #edge detection/dilation
            cvCanny(curr, edges, 50, 100)
            cvDilate(edges, edges,
                     cvCreateStructuringElementEx(7, 7, 0, 0, 
                                                  CV_SHAPE_ELLIPSE))
            #cvErode(edges, edges)
            cvShowImage('edges', edges)

            # do optical flow using edge detection/dilation
            if prev_edges:
                cvCalcOpticalFlowHS(prev_edges, edges, 1, velx, vely, 0.5,
                                     (CV_TERMCRIT_ITER, 10, 0))
                #cvThreshold(vely, vely, 0.5, 0, CV_THRESH_TOZERO)
                #cvShowImage('flow', vely)
            prev_edges = edges

            cvThreshold(vely, combined, 0.5, 255, CV_THRESH_BINARY)
            cvMin(combined, edges, combined)
            cvShowImage('combined', combined)

            # blobs
            myblobs = CBlobResult(edges, blob_mask, 100, True)
            myblobs.filter_blobs(10, 10000)
            blob_count = myblobs.GetNumBlobs()

            near_player = []
            far_player = []
            possible_ball = []
            for i in range(blob_count):
                blob = myblobs.GetBlob(i)

                # Group blobs by their center point
                x, y = blob_center(blob)
                if y > 142:
                    near_player.append(blob)
                elif y < 40:
                    far_player.append(blob)
                else:
                    possible_ball.append(blob)
                    
            '''
            # Remove outliers - this was commented out because
            #  it's not as effective as hoped
            outliers = [remove_outlier(near_player), 
                        remove_outlier(far_player)]
            outliers = [x for x in outliers if x]

            print outliers

            # If no ball found in the range y=(40, 145) then
            #  find the closest blob to our state estimate
            #  that is small enough to be a ball.
            if len(possible_ball) == 0:
                outliers = [blob for blob in outliers if blob.Area() < 100]
                if len(outliers) > 0:
                    center = cvKalmanPredict(kf_ball)
                    outliers.sort(key=lambda x: \
                                      distance_sq(blob_center(x), center))
                    possible_ball.append(outliers[0])
            '''

            ball = None
            maxv = -1
            # Find the ball that's moving the fastest
            for blob in possible_ball:
                # get optical flow velocity at blob center
                x, y = blob_center(blob)
                x, y = int(x), int(y)
                # v = magnitude of velocity vector
                v = pow(cvGetReal2D(velx, y, x), 2) + \
                    pow(cvGetReal2D(vely, y, x), 2)
                if v > maxv:
                    ball = blob
                    maxv = v
            if ball and maxv > 0.01:
                x, y = blob_center(ball)
                print x, y
                #cvRectangle(frame, (ball.MinX(), ball.MinY()),
                #            (ball.MaxX(), ball.MaxY()), CV_RGB(0, 255, 0))
                cvRectangle(frame, (x-5,y-5), (x+5,y+5), CV_RGB(0, 255, 0))
                ball_count += 1
                #ball.FillBlob(frame, cvScalar(0, 255, 0), 0, 0)

            # Ask user if moving ball is present
            has_ball = raw_input("Moving ball present [y/N]?")
            has_ball = (has_ball.lower() == 'y')
            if has_ball: present_count += 1
            present.append(has_ball)
            
            print 'ball found in %d of %d frames' % \
                (ball_count, present_count)
            cvShowImage('video', frame)

            #print time.clock()-start_time

            ''' crashes
            #hough transform on dilated image
            cvCopy(edges, hough_in)
            cvSmooth(hough_in, hough_in, CV_GAUSSIAN, 15, 15, 0, 0)
            cvHoughCircles(hough_in, hough_storage, CV_HOUGH_GRADIENT,
                            4, frame_size[1]/10, 100, 40, 0, 0)
            print hough_storage
            '''


        k = cvWaitKey(1000/fps)
        if k == 27:  # ESC key
            break
        elif k == 'p':   # play/pause
            play = not play
Ejemplo n.º 5
0
    cv2.cv.Not(thresh_image_ipl, inverted_license_plate_grayscale_ipl)

    # Min blob size and Max blob size
    min_blob_size = 100 # Blob must be 30 px by 30 px
    max_blob_size = 10000
    threshold = 100

    # Plate area as % of image area:
    max_plate_to_image_ratio = 0.3
    min_plate_to_image_ratio = 0.01
    image_area = license_plate_size[0] * license_plate_size[1]

    # Mask - Blob extracted where mask is set to 1
    # Third parameter is threshold value to apply prior to blob detection
    # Boolean indicating whether we find moments
    myblobs = CBlobResult(thresh_image_ipl, mask, threshold, True)
    myblobs.filter_blobs(min_blob_size, max_blob_size)
    blob_count = myblobs.GetNumBlobs()
    print "Found %d blob[s] betweeen size %d and %d using threshold %d" % (
            blob_count, min_blob_size, max_blob_size, threshold)

    for i in range(blob_count):

        my_enumerated_blob = myblobs.GetBlob(i)
#        print "%d: Area = %d" % (i, my_enumerated_blob.Area())
        my_enumerated_blob.FillBlob(
                license_plate_grayscale_ipl,
                #license_plate_ipl,
                #cv2.cv.Scalar(255, 0, 0),
                cv2.cv.CV_RGB(255, 0, 0),
                0, 0)
Ejemplo n.º 6
0
    cv2.cv.Not(thresh_image_ipl, inverted_license_plate_grayscale_ipl)

    # Min blob size and Max blob size
    min_blob_size = 100  # Blob must be 30 px by 30 px
    max_blob_size = 10000
    threshold = 100

    # Plate area as % of image area:
    max_plate_to_image_ratio = 0.3
    min_plate_to_image_ratio = 0.01
    image_area = license_plate_size[0] * license_plate_size[1]

    # Mask - Blob extracted where mask is set to 1
    # Third parameter is threshold value to apply prior to blob detection
    # Boolean indicating whether we find moments
    myblobs = CBlobResult(thresh_image_ipl, mask, threshold, True)
    myblobs.filter_blobs(min_blob_size, max_blob_size)
    blob_count = myblobs.GetNumBlobs()
    print "Found %d blob[s] betweeen size %d and %d using threshold %d" % (
        blob_count, min_blob_size, max_blob_size, threshold)

    for i in range(blob_count):

        my_enumerated_blob = myblobs.GetBlob(i)
        #        print "%d: Area = %d" % (i, my_enumerated_blob.Area())
        my_enumerated_blob.FillBlob(
            license_plate_grayscale_ipl,
            #license_plate_ipl,
            #cv2.cv.Scalar(255, 0, 0),
            cv2.cv.CV_RGB(255, 0, 0),
            0,
Ejemplo n.º 7
0
def main():
    if len(sys.argv) == 1:
        print 'Usage: %s [inputfile]' % sys.argv[0]
        sys.exit(1)

    # initialize window
    cv.NamedWindow('video', cv.CV_WINDOW_AUTOSIZE)
    cv.MoveWindow('video', 10, 10)

    cv.NamedWindow('threshold', cv.CV_WINDOW_AUTOSIZE)
    cv.MoveWindow('threshold', 10, 500)

    cv.NamedWindow('flow', cv.CV_WINDOW_AUTOSIZE)
    cv.MoveWindow('flow', 500, 10)

    cv.NamedWindow('edges', cv.CV_WINDOW_AUTOSIZE)
    cv.MoveWindow('edges', 500, 500)

    cv.NamedWindow('combined', cv.CV_WINDOW_AUTOSIZE)
    cv.MoveWindow('combined', 1000, 10)

    capture = cv.CreateFileCapture(sys.argv[1])
    if not capture: print 'Error opening capture'; sys.exit(1)

    # Load bg image
    bg = cv.LoadImage('bg.png')

    # Discard some frames
    for i in xrange(2300):
        cv.GrabFrame(capture)

    frame = cv.QueryFrame(capture)
    frame_size = cv.GetSize(frame)

    # vars for playback
    fps = 25
    play = True
    velx = cv.CreateImage(frame_size, cv.IPL_DEPTH_32F, 1)
    vely = cv.CreateImage(frame_size, cv.IPL_DEPTH_32F, 1)
    combined = cv.CreateImage(frame_size, cv.IPL_DEPTH_8U, 1)
    prev = cv.CreateImage(frame_size, cv.IPL_DEPTH_8U, 1)
    curr = cv.CreateImage(frame_size, cv.IPL_DEPTH_8U, 1)
    frame_sub = cv.CreateImage(frame_size, cv.IPL_DEPTH_8U, 3)

    edges = cv.CreateImage(frame_size, cv.IPL_DEPTH_8U, 1)
    prev_edges = None
    storage = cv.CreateMemStorage(0)

    blob_mask = cv0.cvCreateImage (frame_size, cv.IPL_DEPTH_8U, 1)
    cv0.cvSet(blob_mask, 1)

    hough_in = cv.CreateImage(frame_size, cv.IPL_DEPTH_8U, 1)
    hough_storage = cv.CreateMat( 100, 1, cv.CV_32FC3 )

    '''
    cv.CvtColor(frame, prev, cv.CV_BGR2GRAY)
    frame = cv.QueryFrame(capture)
    cv.CvtColor(frame, curr, cv.CV_BGR2GRAY)

    # winSize can't have even numbers
    cv.CalcOpticalFlowLK(prev, curr, (3,3), velx, vely)
    cv.ShowImage('video', frame)
    cv.ShowImage('flow', velx)
    cv.WaitKey(0)
    '''

    while True:

        if play:
            frame = cv.QueryFrame(capture)
            cv.Sub(frame, bg, frame_sub)

            '''#detect people
            found = list(cv.HOGDetectMultiScale(frame, storage, win_stride=(8,8),
                padding=(32,32), scale=1.05, group_threshold=2))
            for r in found:
                (rx, ry), (rw, rh) = r
                tl = (rx + int(rw*0.1), ry + int(rh*0.07))
                br = (rx + int(rw*0.9), ry + int(rh*0.87))
                cv.Rectangle(frame, tl, br, (0, 255, 0), 3)
            '''

            #color thresholding
            hsv = cv.CreateImage(frame_size, cv.IPL_DEPTH_8U, 3);
            cv.CvtColor(frame, hsv, cv.CV_BGR2HSV)
            mask = cv.CreateMat(frame_size[1], frame_size[0], 
                                cv.CV_8UC1)
            cv.InRangeS(hsv, (0.06*256, 0.2*256, 0.6*256, 0),
                        (0.16*256, 1.0*256, 1.0*256, 0), mask)
            cv.ShowImage('threshold', mask)
            

            #optical flow method
            # store previous frame
            prev, curr = curr, prev
            # convert next frame to single channel grayscale
            cv.CvtColor(frame_sub, curr, cv.CV_BGR2GRAY)
            #cv.CalcOpticalFlowLK(prev, curr, (3,3), velx, vely)
            #cv.Threshold(velx, velx, 8.0, 0, cv.CV_THRESH_TOZERO)
            cv.CalcOpticalFlowHS(prev, curr, 1, velx, vely, 0.5,
                                 (cv.CV_TERMCRIT_ITER, 10, 0))
            cv.Threshold(velx, velx, 0.5, 0, cv.CV_THRESH_TOZERO)
            cv.Threshold(vely, vely, 0.5, 0, cv.CV_THRESH_TOZERO)
            cv.Erode(vely, vely, 
                     cv.CreateStructuringElementEx(2, 2, 0, 0, 
                                                   cv.CV_SHAPE_ELLIPSE))
            cv.Add(vely, velx, vely)
            cv.ShowImage('flow', vely)

            #edge detection
            cv.Canny(curr, edges, 50, 100)
            cv.Dilate(edges, edges,
                     cv.CreateStructuringElementEx(7, 7, 0, 0, 
                                                   cv.CV_SHAPE_ELLIPSE))
            cv.ShowImage('edges', edges)

            if prev_edges:
                cv.CalcOpticalFlowHS(prev_edges, edges, 1, velx, vely, 0.5,
                                     (cv.CV_TERMCRIT_ITER, 10, 0))
                cv.Threshold(velx, velx, 0.5, 0, cv.CV_THRESH_TOZERO)
                cv.Threshold(vely, vely, 0.5, 0, cv.CV_THRESH_TOZERO)
                cv.ShowImage('flow', vely)
            prev_edges = edges

            cv.Threshold(vely, combined, 0.5, 255, cv.CV_THRESH_BINARY)
            cv.Min(combined, edges, combined)
            cv.ShowImage('combined', combined)

            # blobs
            myblobs = CBlobResult(edges, blob_mask, 100, False)
            myblobs.filter_blobs(10, 10000)
            blob_count = myblobs.GetNumBlobs()
            
            for i in range(blob_count):
                
                my_enumerated_blob = myblobs.GetBlob(i)
#               print "%d: Area = %d" % (i, my_enumerated_blob.Area())
                my_enumerated_blob.FillBlob(frame, 
                                            hsv2rgb( i*180.0/blob_count), 0, 0)


            cv.ShowImage('video', frame)

            ''' crashes
            #hough transform on dilated image
            #http://wiki.elphel.com/index.php?
            # title=OpenCV_Tennis_balls_recognizing_tutorial&redirect=no
            cv.Copy(edges, hough_in)
            cv.Smooth(hough_in, hough_in, cv.CV_GAUSSIAN, 15, 15, 0, 0)
            cv.HoughCircles(hough_in, hough_storage, cv.CV_HOUGH_GRADIENT,
                            4, frame_size[1]/10, 100, 40, 0, 0)
            print hough_storage
            '''


        k = cv.WaitKey(1000/fps)
        if k == 27:  # ESC key
            break
        elif k == 'p':   # play/pause
            play = not play
Ejemplo n.º 8
0
def main():
    if len(sys.argv) == 1:
        print 'Usage: %s [inputfile]' % sys.argv[0]
        sys.exit(1)

    # initialize window
    cvNamedWindow('video', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('video', 10, 10)

    cvNamedWindow('segment', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('segment', 10, 500)

    cvNamedWindow('flow', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('flow', 500, 10)

    cvNamedWindow('edges', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('edges', 500, 500)

    capture = cvCreateFileCapture(sys.argv[1])
    if not capture:
        print 'Error opening capture'
        sys.exit(1)

    # Load bg image
    bg = cvLoadImage('bg.png')

    # Discard some frames
    for i in xrange(2300):
        cvGrabFrame(capture)

    frame = cvQueryFrame(capture)
    frame_size = cvGetSize(frame)

    # vars for playback
    fps = 25
    play = True
    velx = cvCreateImage(frame_size, IPL_DEPTH_32F, 1)
    vely = cvCreateImage(frame_size, IPL_DEPTH_32F, 1)
    combined = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    prev = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    frame_gray = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    frame_sub = cvCreateImage(frame_size, IPL_DEPTH_8U, 3)

    flow = cvCreateImage(frame_size, IPL_DEPTH_8U, 3)

    edges = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    prev_edges = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    storage = cvCreateMemStorage(0)

    blob_mask = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    cvSet(blob_mask, 1)

    hough_in = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    hough_storage = cvCreateMat(100, 1, CV_32FC3)

    silhouette = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    mhi = cvCreateImage(frame_size, IPL_DEPTH_32F, 1)
    seg_mask = cvCreateImage(frame_size, IPL_DEPTH_32F, 1)
    seg_storage = cvCreateMemStorage(0)

    kf_near = cvCreateKalman(4, 2, 0)
    kf_far = cvCreateKalman(4, 2, 0)
    kf_ball = cvCreateKalman(4, 2, 0)

    for kalman in [kf_near, kf_far, kf_ball]:
        # transition matrix F is initialized to identity
        # want F = [1 0 1 0
        #           0 1 0 1
        #           0 0 1 0
        #           0 0 0 1]
        # because x1 = x coordinate and x3 = d/dt x1
        #         x2 = y coordinate and x4 = d/dt x3
        kalman.transition_matrix[0, 2] = 1
        kalman.transition_matrix[1, 3] = 1
        cvSetIdentity(kalman.measurement_matrix, 1)
        cvSetIdentity(kalman.process_noise_cov, 1e-5)
        cvSetIdentity(kalman.measurement_noise_cov, 1e-1)
        cvSetIdentity(kalman.error_cov_post, 1)

    cvSetIdentity(kf_ball.process_noise_cov, 1e-3)

    # initialize random number generator
    rng = cvRNG()

    # x_k = state variables
    x_ball = cvCreateMat(4, 1, CV_32FC1)
    cvZero(x_ball)
    cvZero(kf_ball.state_post)
    x_near = cvCreateMat(4, 1, CV_32FC1)
    cvZero(x_near)
    cvZero(kf_near.state_post)

    # w_k = noise
    w_k = cvCreateMat(4, 1, CV_32FC1)

    # z_k = measurements
    z_k = cvCreateMat(2, 1, CV_32FC1)

    ball_last = None

    while True:

        if play:
            frame = cvQueryFrame(capture)

            # do background subtraction using manually created frame
            # TODO do averaging to generate bg
            cvSub(frame, bg, frame_sub)

            # convert to grayscale
            cvCvtColor(frame_sub, frame_gray, CV_BGR2GRAY)

            # edge detection/dilation
            cvCanny(frame_gray, edges, 50, 100)
            cvDilate(
                edges, edges,
                cvCreateStructuringElementEx(7, 7, 0, 0, CV_SHAPE_ELLIPSE))
            #cvErode(edges, edges)
            cvShowImage('edges', edges)

            # do optical flow using edge detection/dilation image
            #cvCalcOpticalFlowLK(prev_edges, edges, (7,7), velx, vely)
            cvCalcOpticalFlowHS(prev_edges, edges, 1, velx, vely, 0.5,
                                (CV_TERMCRIT_ITER, 10, 0))
            #cvThreshold(vely, vely, 0.5, 0, CV_THRESH_TOZERO)
            #cvAdd(velx, vely, vely)
            cvShowImage('flow', vely)
            cvCopy(edges, prev_edges)
            '''
            # segment motion
            cvThreshold(vely, silhouette, 0.5, 255, CV_THRESH_BINARY)
            cvUpdateMotionHistory(silhouette, mhi, time.clock()/1000, 1)
            components = cvSegmentMotion(mhi, seg_mask, seg_storage,
                                         time.clock()/1000,
                                         1/fps)
            #http://opencv.willowgarage.com/documentation/python/imgproc_miscellaneous_image_transformations.html?highlight=connectedcomp#CvConnectedComp
            for c in components:
                area, value, rect = c.area, c.value, c.rect
                x, y, w, h = rect.x, rect.y, rect.width, rect.height
                cvRectangle(frame, (x,y), (x+w,y+h), CV_RGB(255, 0, 0))

            cvShowImage('segment', seg_mask)
            '''

            blobs = CBlobResult(edges, blob_mask, 100, True)
            blobs.filter_blobs(10, 10000)
            blob_count = blobs.GetNumBlobs()

            # Find blob closest to last ball position
            if ball_last:
                last_center = blob_center(ball_last)

                mind2 = 1e100
                ball = None
                for i in range(blob_count):
                    blob = blobs.GetBlob(i)
                    center = blob_center(blob)
                    d2 = distance_sq(last_center, center)
                    if d2 < mind2:
                        mind2 = d2
                        ball = blob
                if ball:
                    cvRectangle(frame, (ball.MinX(), ball.MinY()),
                                (ball.MaxX(), ball.MaxY()), CV_RGB(0, 255, 0))
                ball_last = ball
            # Initialize ball estimate
            else:
                possible_ball = []
                for i in range(blob_count):
                    blob = blobs.GetBlob(i)

                    x, y = blob_center(blob)
                    if 40 < y < 142:
                        possible_ball.append(blob)

                    # Find fastest-moving possible ball
                    maxv = 3
                    ball = None
                    for blob in possible_ball:
                        #blob.FillBlob(frame, cvScalar(0, 255, 0), 0, 0)

                        x1, y1 = int(blob.MinX()), int(blob.MinY())
                        x2, y2 = int(blob.MaxX()), int(blob.MaxY())

                        # get mean optical flow velocity over bounding box
                        vx = numpy.mean(velx[y1:y2, x1:x2])
                        vy = numpy.mean(vely[y1:y2, x1:x2])
                        '''
                        # get mean at center of blob
                        x, y = int((x1+x2)/2), int((y1+y2)/2)
                        vx = velx[y,x]
                        vy = vely[y,x]
                        '''
                        # v = proportional to sq magnitude of velocity vector
                        v = vx * vx + vy * vy
                        print v
                        if v > maxv:
                            ball = blob
                            maxv = v
                    if ball:
                        cvRectangle(frame, (ball.MinX(), ball.MinY()),
                                    (ball.MaxX(), ball.MaxY()),
                                    CV_RGB(0, 255, 0))
                        ball_last = ball

            cvShowImage('video', frame)
            '''
            # blobs
            myblobs = CBlobResult(edges, blob_mask, 100, True)
            myblobs.filter_blobs(10, 10000)
            blob_count = myblobs.GetNumBlobs()

            near_player = []
            far_player = []
            possible_ball = []
            for i in range(blob_count):
                blob = myblobs.GetBlob(i)

                # Group blobs by their center point
                x, y = blob_center(blob)
                if y > 142:
                    near_player.append(blob)
                elif y < 40:
                    far_player.append(blob)
                else:
                    possible_ball.append(blob)
                    

            outliers = [remove_outlier(near_player), 
                        remove_outlier(far_player)]
            outliers = [x for x in outliers if x]

            print outliers

            # If no ball found in the range y=(40, 145) then
            #  find the closest blob to our state estimate
            #  that is small enough to be a ball.
            if len(possible_ball) == 0:
                outliers = [blob for blob in outliers if blob.Area() < 100]
                if len(outliers) > 0:
                    center = cvKalmanPredict(kf_ball)
                    outliers.sort(key=lambda x: \
                                      distance_sq(blob_center(x), center))
                    possible_ball.append(outliers[0])

            ball = None
            maxv = -1
            # Find the ball that's moving the fastest
            for blob in possible_ball:
                # get optical flow velocity at blob center
                x, y = blob_center(blob)
                x, y = int(x), int(y)
                # v = magnitude of velocity vector
                v = pow(cvGetReal2D(velx, y, x), 2) + \
                    pow(cvGetReal2D(vely, y, x), 2)
                if v > maxv:
                    ball = blob
                    maxv = v
            if ball and maxv > 0.01:
                cvRectangle(frame, (ball.MinX(), ball.MinY()),
                            (ball.MaxX(), ball.MaxY()), CV_RGB(0, 255, 0))
                #ball.FillBlob(frame, cvScalar(0, 255, 0), 0, 0)

            # Estimate position of near player
            if len(near_player) > 0:
                # Find x center
                xLocs = []
                yLocs = []
                for blob in near_player:
                    x, y = blob_center(blob)
                    xLocs.append(x)
                    yLocs.append(y)

                if len(xLocs) > 0:
                    xmin, ymin = min(xLocs), min(yLocs)
                    xmax, ymax = max(xLocs), max(yLocs)
                    cvRectangle(frame, (xmin, ymin), (xmax, ymax),
                                CV_RGB(255, 0, 0))

                    y_k = cvKalmanPredict(kf_near)
                    print 'near player at', y_k[0], y_k[1]
                    draw_cross(frame, y_k, CV_RGB(255, 0, 0), 10)

                    # z1, z2 = position measurement
                    z_k[0], z_k[1] = (xmin+xmax)/2, (ymin+ymax)/2
                    cvMatMulAdd(kf_near.measurement_matrix, x_near, z_k, z_k)
                    cvKalmanCorrect(kf_near, z_k)

                    # apply process noise and update state
                    cvRandArr(rng, w_k, CV_RAND_NORMAL, 0,
                              numpy.sqrt(kf_near.process_noise_cov[0,0]))
                    cvMatMulAdd(kf_near.transition_matrix, x_near, w_k, x_near)

            # Estimate position of far player
            xLocs = []
            yLocs = []
            for blob in far_player:
                x,y = blob_center(blob)
                xLocs.append(x)
                yLocs.append(y)
            if len(xLocs) > 0:
                xmin, ymin = min(xLocs), min(yLocs)
                xmax, ymax = max(xLocs), max(yLocs)
                cvRectangle(frame, (xmin, ymin), (xmax, ymax),
                            CV_RGB(0, 0, 255))
                print 'far player at', (xmin+xmax)/2, (ymin+ymax)/2

            # Estimate position of the ball
            y_k = cvKalmanPredict(kf_ball)
            x, y = y_k[0], y_k[1]
            print 'ball at', x, y
            draw_cross(frame, y_k, CV_RGB(0, 255, 0), 5)

            # kalman filter update
            if ball and maxv > 0.01:
                # z1, z2 = position measurement
                x, y = blob_center(ball)
                z_k[0], z_k[1] = x, y
                # z3, z4 = velocity measurement
                #x, y = int(x), int(y)
                #z_k[2], z_k[3] = cvGetReal2D(velx, y, x), \
                #    cvGetReal2D(vely, y, x)
                cvMatMulAdd(kf_ball.measurement_matrix, x_ball, z_k, z_k)
                cvKalmanCorrect(kf_ball, z_k)

                # apply process noise and update state
                cvRandArr(rng, w_k, CV_RAND_NORMAL, 0,
                          numpy.sqrt(kf_ball.process_noise_cov[0,0]))
                cvMatMulAdd(kf_ball.transition_matrix, x_ball, w_k, x_ball)
            #else:
                #kf_ball.transition_matrix[0,2] = 0
                #kf_ball.transition_matrix[1,3] = 0
                #x_ball = cvKalmanPredict(kf_ball)
            '''
            ''' crashes
            #hough transform on dilated image
            cvCopy(edges, hough_in)
            cvSmooth(hough_in, hough_in, CV_GAUSSIAN, 15, 15, 0, 0)
            cvHoughCircles(hough_in, hough_storage, CV_HOUGH_GRADIENT,
                            4, frame_size[1]/10, 100, 40, 0, 0)
            print hough_storage
            '''

        k = cvWaitKey(1000 / fps)
        if k == 27:  # ESC key
            break
        elif k == 'p':  # play/pause
            play = not play
Ejemplo n.º 9
0
def main():
    if len(sys.argv) == 1:
        print 'Usage: %s [inputfile]' % sys.argv[0]
        sys.exit(1)

    # initialize window
    cvNamedWindow('video', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('video', 10, 10)

    cvNamedWindow('segment', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('segment', 10, 500)

    cvNamedWindow('flow', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('flow', 500, 10)

    cvNamedWindow('edges', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('edges', 500, 500)


    capture = cvCreateFileCapture(sys.argv[1])
    if not capture: print 'Error opening capture'; sys.exit(1)

    # Load bg image
    bg = cvLoadImage('bg.png')

    # Discard some frames
    for i in xrange(2300):
        cvGrabFrame(capture)

    frame = cvQueryFrame(capture)
    frame_size = cvGetSize(frame)

    # vars for playback
    fps = 25
    play = True
    velx = cvCreateImage(frame_size, IPL_DEPTH_32F, 1)
    vely = cvCreateImage(frame_size, IPL_DEPTH_32F, 1)
    combined = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    prev = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    frame_gray = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    frame_sub = cvCreateImage(frame_size, IPL_DEPTH_8U, 3)

    flow = cvCreateImage(frame_size, IPL_DEPTH_8U, 3)

    edges = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    prev_edges = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    storage = cvCreateMemStorage(0)

    blob_mask = cvCreateImage (frame_size, IPL_DEPTH_8U, 1)
    cvSet(blob_mask, 1)

    hough_in = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    hough_storage = cvCreateMat( 100, 1, CV_32FC3 )

    silhouette = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    mhi = cvCreateImage(frame_size, IPL_DEPTH_32F, 1)
    seg_mask = cvCreateImage(frame_size, IPL_DEPTH_32F, 1)
    seg_storage = cvCreateMemStorage(0)

    kf_near = cvCreateKalman(4, 2, 0)
    kf_far = cvCreateKalman(4, 2, 0)
    kf_ball = cvCreateKalman(4, 2, 0)

    for kalman in [kf_near, kf_far, kf_ball]:
        # transition matrix F is initialized to identity
        # want F = [1 0 1 0
        #           0 1 0 1
        #           0 0 1 0
        #           0 0 0 1]
        # because x1 = x coordinate and x3 = d/dt x1
        #         x2 = y coordinate and x4 = d/dt x3
        kalman.transition_matrix[0,2] = 1
        kalman.transition_matrix[1,3] = 1
        cvSetIdentity(kalman.measurement_matrix, 1)
        cvSetIdentity(kalman.process_noise_cov, 1e-5)
        cvSetIdentity(kalman.measurement_noise_cov, 1e-1)
        cvSetIdentity(kalman.error_cov_post, 1)

    cvSetIdentity(kf_ball.process_noise_cov, 1e-3)

    # initialize random number generator
    rng = cvRNG()

    # x_k = state variables
    x_ball = cvCreateMat(4, 1, CV_32FC1)
    cvZero(x_ball)
    cvZero(kf_ball.state_post)
    x_near = cvCreateMat(4, 1, CV_32FC1)
    cvZero(x_near)
    cvZero(kf_near.state_post)

    # w_k = noise
    w_k = cvCreateMat(4, 1, CV_32FC1)

    # z_k = measurements
    z_k = cvCreateMat(2, 1, CV_32FC1)

    ball_last = None

    while True:

        if play:
            frame = cvQueryFrame(capture)

            # do background subtraction using manually created frame
            # TODO do averaging to generate bg
            cvSub(frame, bg, frame_sub)

            # convert to grayscale
            cvCvtColor(frame_sub, frame_gray, CV_BGR2GRAY)

            # edge detection/dilation
            cvCanny(frame_gray, edges, 50, 100)
            cvDilate(edges, edges,
                     cvCreateStructuringElementEx(7, 7, 0, 0, 
                                                  CV_SHAPE_ELLIPSE))
            #cvErode(edges, edges)
            cvShowImage('edges', edges)

            # do optical flow using edge detection/dilation image
            #cvCalcOpticalFlowLK(prev_edges, edges, (7,7), velx, vely)
            cvCalcOpticalFlowHS(prev_edges, edges, 1, velx, vely, 0.5,
                                (CV_TERMCRIT_ITER, 10, 0))
            #cvThreshold(vely, vely, 0.5, 0, CV_THRESH_TOZERO)
            #cvAdd(velx, vely, vely)
            cvShowImage('flow', vely)
            cvCopy(edges, prev_edges)

            '''
            # segment motion
            cvThreshold(vely, silhouette, 0.5, 255, CV_THRESH_BINARY)
            cvUpdateMotionHistory(silhouette, mhi, time.clock()/1000, 1)
            components = cvSegmentMotion(mhi, seg_mask, seg_storage,
                                         time.clock()/1000,
                                         1/fps)
            #http://opencv.willowgarage.com/documentation/python/imgproc_miscellaneous_image_transformations.html?highlight=connectedcomp#CvConnectedComp
            for c in components:
                area, value, rect = c.area, c.value, c.rect
                x, y, w, h = rect.x, rect.y, rect.width, rect.height
                cvRectangle(frame, (x,y), (x+w,y+h), CV_RGB(255, 0, 0))

            cvShowImage('segment', seg_mask)
            '''

            blobs = CBlobResult(edges, blob_mask, 100, True)
            blobs.filter_blobs(10, 10000)
            blob_count = blobs.GetNumBlobs()

            # Find blob closest to last ball position
            if ball_last:
                last_center = blob_center(ball_last)

                mind2 = 1e100
                ball = None
                for i in range(blob_count):
                    blob = blobs.GetBlob(i)
                    center = blob_center(blob)
                    d2 = distance_sq(last_center, center)
                    if d2 < mind2:
                        mind2 = d2
                        ball = blob
                if ball:
                    cvRectangle(frame, (ball.MinX(), ball.MinY()),
                                (ball.MaxX(), ball.MaxY()),
                                CV_RGB(0, 255, 0))
                ball_last = ball
            # Initialize ball estimate
            else:
                possible_ball = []
                for i in range(blob_count):
                    blob = blobs.GetBlob(i)

                    x, y = blob_center(blob)
                    if 40 < y < 142:
                        possible_ball.append(blob)

                    # Find fastest-moving possible ball
                    maxv = 3
                    ball = None
                    for blob in possible_ball:
                        #blob.FillBlob(frame, cvScalar(0, 255, 0), 0, 0)

                        x1, y1 = int(blob.MinX()), int(blob.MinY())
                        x2, y2 = int(blob.MaxX()), int(blob.MaxY())
                        
                        # get mean optical flow velocity over bounding box
                        vx = numpy.mean(velx[y1:y2, x1:x2])
                        vy = numpy.mean(vely[y1:y2, x1:x2])
                        '''
                        # get mean at center of blob
                        x, y = int((x1+x2)/2), int((y1+y2)/2)
                        vx = velx[y,x]
                        vy = vely[y,x]
                        '''
                        # v = proportional to sq magnitude of velocity vector
                        v = vx*vx + vy*vy
                        print v
                        if v > maxv:
                            ball = blob
                            maxv = v
                    if ball:
                        cvRectangle(frame, (ball.MinX(), ball.MinY()),
                                    (ball.MaxX(), ball.MaxY()),
                                    CV_RGB(0, 255, 0))
                        ball_last = ball

            cvShowImage('video', frame)

            '''
            # blobs
            myblobs = CBlobResult(edges, blob_mask, 100, True)
            myblobs.filter_blobs(10, 10000)
            blob_count = myblobs.GetNumBlobs()

            near_player = []
            far_player = []
            possible_ball = []
            for i in range(blob_count):
                blob = myblobs.GetBlob(i)

                # Group blobs by their center point
                x, y = blob_center(blob)
                if y > 142:
                    near_player.append(blob)
                elif y < 40:
                    far_player.append(blob)
                else:
                    possible_ball.append(blob)
                    

            outliers = [remove_outlier(near_player), 
                        remove_outlier(far_player)]
            outliers = [x for x in outliers if x]

            print outliers

            # If no ball found in the range y=(40, 145) then
            #  find the closest blob to our state estimate
            #  that is small enough to be a ball.
            if len(possible_ball) == 0:
                outliers = [blob for blob in outliers if blob.Area() < 100]
                if len(outliers) > 0:
                    center = cvKalmanPredict(kf_ball)
                    outliers.sort(key=lambda x: \
                                      distance_sq(blob_center(x), center))
                    possible_ball.append(outliers[0])

            ball = None
            maxv = -1
            # Find the ball that's moving the fastest
            for blob in possible_ball:
                # get optical flow velocity at blob center
                x, y = blob_center(blob)
                x, y = int(x), int(y)
                # v = magnitude of velocity vector
                v = pow(cvGetReal2D(velx, y, x), 2) + \
                    pow(cvGetReal2D(vely, y, x), 2)
                if v > maxv:
                    ball = blob
                    maxv = v
            if ball and maxv > 0.01:
                cvRectangle(frame, (ball.MinX(), ball.MinY()),
                            (ball.MaxX(), ball.MaxY()), CV_RGB(0, 255, 0))
                #ball.FillBlob(frame, cvScalar(0, 255, 0), 0, 0)

            # Estimate position of near player
            if len(near_player) > 0:
                # Find x center
                xLocs = []
                yLocs = []
                for blob in near_player:
                    x, y = blob_center(blob)
                    xLocs.append(x)
                    yLocs.append(y)

                if len(xLocs) > 0:
                    xmin, ymin = min(xLocs), min(yLocs)
                    xmax, ymax = max(xLocs), max(yLocs)
                    cvRectangle(frame, (xmin, ymin), (xmax, ymax),
                                CV_RGB(255, 0, 0))

                    y_k = cvKalmanPredict(kf_near)
                    print 'near player at', y_k[0], y_k[1]
                    draw_cross(frame, y_k, CV_RGB(255, 0, 0), 10)

                    # z1, z2 = position measurement
                    z_k[0], z_k[1] = (xmin+xmax)/2, (ymin+ymax)/2
                    cvMatMulAdd(kf_near.measurement_matrix, x_near, z_k, z_k)
                    cvKalmanCorrect(kf_near, z_k)

                    # apply process noise and update state
                    cvRandArr(rng, w_k, CV_RAND_NORMAL, 0,
                              numpy.sqrt(kf_near.process_noise_cov[0,0]))
                    cvMatMulAdd(kf_near.transition_matrix, x_near, w_k, x_near)

            # Estimate position of far player
            xLocs = []
            yLocs = []
            for blob in far_player:
                x,y = blob_center(blob)
                xLocs.append(x)
                yLocs.append(y)
            if len(xLocs) > 0:
                xmin, ymin = min(xLocs), min(yLocs)
                xmax, ymax = max(xLocs), max(yLocs)
                cvRectangle(frame, (xmin, ymin), (xmax, ymax),
                            CV_RGB(0, 0, 255))
                print 'far player at', (xmin+xmax)/2, (ymin+ymax)/2

            # Estimate position of the ball
            y_k = cvKalmanPredict(kf_ball)
            x, y = y_k[0], y_k[1]
            print 'ball at', x, y
            draw_cross(frame, y_k, CV_RGB(0, 255, 0), 5)

            # kalman filter update
            if ball and maxv > 0.01:
                # z1, z2 = position measurement
                x, y = blob_center(ball)
                z_k[0], z_k[1] = x, y
                # z3, z4 = velocity measurement
                #x, y = int(x), int(y)
                #z_k[2], z_k[3] = cvGetReal2D(velx, y, x), \
                #    cvGetReal2D(vely, y, x)
                cvMatMulAdd(kf_ball.measurement_matrix, x_ball, z_k, z_k)
                cvKalmanCorrect(kf_ball, z_k)

                # apply process noise and update state
                cvRandArr(rng, w_k, CV_RAND_NORMAL, 0,
                          numpy.sqrt(kf_ball.process_noise_cov[0,0]))
                cvMatMulAdd(kf_ball.transition_matrix, x_ball, w_k, x_ball)
            #else:
                #kf_ball.transition_matrix[0,2] = 0
                #kf_ball.transition_matrix[1,3] = 0
                #x_ball = cvKalmanPredict(kf_ball)
            '''

            ''' crashes
            #hough transform on dilated image
            cvCopy(edges, hough_in)
            cvSmooth(hough_in, hough_in, CV_GAUSSIAN, 15, 15, 0, 0)
            cvHoughCircles(hough_in, hough_storage, CV_HOUGH_GRADIENT,
                            4, frame_size[1]/10, 100, 40, 0, 0)
            print hough_storage
            '''


        k = cvWaitKey(1000/fps)
        if k == 27:  # ESC key
            break
        elif k == 'p':   # play/pause
            play = not play
Ejemplo n.º 10
0
def main():
    if len(sys.argv) == 1:
        print 'Usage: %s [inputfile]' % sys.argv[0]
        sys.exit(1)

    # initialize window
    cvNamedWindow('video', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('video', 10, 10)

    cvNamedWindow('threshold', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('threshold', 10, 500)

    cvNamedWindow('flow', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('flow', 500, 10)

    cvNamedWindow('edges', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('edges', 500, 500)

    cvNamedWindow('combined', CV_WINDOW_AUTOSIZE)
    cvMoveWindow('combined', 10, 1000)

    capture = cvCreateFileCapture(sys.argv[1])
    if not capture: print 'Error opening capture'; sys.exit(1)

    # Load bg image
    bg = cvLoadImage('bg.png')

    # Discard some frames
    for i in xrange(2300):
        cvGrabFrame(capture)

    frame = cvQueryFrame(capture)
    frame_size = cvGetSize(frame)

    # vars for playback
    fps = 25
    play = True
    velx = cvCreateImage(frame_size, IPL_DEPTH_32F, 1)
    vely = cvCreateImage(frame_size, IPL_DEPTH_32F, 1)
    combined = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    prev = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    curr = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    frame_sub = cvCreateImage(frame_size, IPL_DEPTH_8U, 3)

    flow = cvCreateImage(frame_size, IPL_DEPTH_8U, 3)

    edges = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    prev_edges = None
    storage = cvCreateMemStorage(0)

    blob_mask = cvCreateImage (frame_size, IPL_DEPTH_8U, 1)
    cvSet(blob_mask, 1)

    hough_in = cvCreateImage(frame_size, IPL_DEPTH_8U, 1)
    hough_storage = cvCreateMat( 100, 1, CV_32FC3 )

    seg_mask = cvCreateImage(frame_size, IPL_DEPTH_32F, 1)
    seg_storage = cvCreateMemStorage(0)

    '''
    cvCvtColor(frame, prev, CV_BGR2GRAY)
    frame = cvQueryFrame(capture)
    cvCvtColor(frame, curr, CV_BGR2GRAY)

    # winSize can't have even numbers
    cvCalcOpticalFlowLK(prev, curr, (3,3), velx, vely)
    cvShowImage('video', frame)
    cvShowImage('flow', velx)
    cvWaitKey(0)
    '''

    kf_near = cvCreateKalman(4, 2, 0)
    kf_far = cvCreateKalman(4, 2, 0)
    kf_ball = cvCreateKalman(4, 2, 0)

    for kalman in [kf_near, kf_far, kf_ball]:
        # transition matrix F is initialized to identity
        # want F = [1 0 1 0
        #           0 1 0 1
        #           0 0 1 0
        #           0 0 0 1]
        # because x1 = x coordinate and x3 = d/dt x1
        #         x2 = y coordinate and x4 = d/dt x3
        kalman.transition_matrix[0,2] = 1
        kalman.transition_matrix[1,3] = 1
        cvSetIdentity(kalman.measurement_matrix, 1)
        cvSetIdentity(kalman.process_noise_cov, 1e-5)
        cvSetIdentity(kalman.measurement_noise_cov, 1e-1)
        cvSetIdentity(kalman.error_cov_post, 1)

    cvSetIdentity(kf_ball.process_noise_cov, 1e-3)

    # initialize random number generator
    rng = cvRNG()

    # x_k = state variables
    x_ball = cvCreateMat(4, 1, CV_32FC1)
    cvZero(x_ball)
    cvZero(kf_ball.state_post)
    x_near = cvCreateMat(4, 1, CV_32FC1)
    cvZero(x_near)
    cvZero(kf_near.state_post)

    # w_k = noise
    w_k = cvCreateMat(4, 1, CV_32FC1)

    # z_k = measurements
    z_k = cvCreateMat(2, 1, CV_32FC1)

    while True:

        if play:
            frame = cvQueryFrame(capture)
            cvSub(frame, bg, frame_sub)

            '''#detect people
            found = list(cvHOGDetectMultiScale(frame, storage, win_stride=(8,8),
                padding=(32,32), scale=1.05, group_threshold=2))
            for r in found:
                (rx, ry), (rw, rh) = r
                tl = (rx + int(rw*0.1), ry + int(rh*0.07))
                br = (rx + int(rw*0.9), ry + int(rh*0.87))
                cvRectangle(frame, tl, br, (0, 255, 0), 3)
            '''

            #color thresholding
            hsv = cvCreateImage(frame_size, IPL_DEPTH_8U, 3);
            cvCvtColor(frame, hsv, CV_BGR2HSV)
            mask = cvCreateMat(frame_size.height, frame_size.width, 
                                CV_8UC1)
            cvInRangeS(hsv, (0.03*256, 0.2*256, 0.6*256, 0),
                        (0.16*256, 1.0*256, 1.0*256, 0), mask)
            cvShowImage('threshold', mask)
            

            #optical flow method
            # store previous frame
            prev, curr = curr, prev
            # convert next frame to single channel grayscale
            cvCvtColor(frame_sub, curr, CV_BGR2GRAY)
            #cvCalcOpticalFlowLK(prev, curr, (3,3), velx, vely)
            #cvThreshold(velx, velx, 8.0, 0, CV_THRESH_TOZERO)
            cvCalcOpticalFlowHS(prev, curr, 1, velx, vely, 0.5,
                                 (CV_TERMCRIT_ITER, 10, 0))
            cvThreshold(velx, velx, 0.5, 0, CV_THRESH_TOZERO)
            cvThreshold(vely, vely, 0.5, 0, CV_THRESH_TOZERO)
            cvErode(vely, vely, 
                     cvCreateStructuringElementEx(2, 2, 0, 0, 
                                                   CV_SHAPE_ELLIPSE))
            cvAdd(vely, velx, vely)
            cvShowImage('flow', vely)

            #edge detection/dilation
            cvCanny(curr, edges, 50, 100)
            cvDilate(edges, edges,
                     cvCreateStructuringElementEx(7, 7, 0, 0, 
                                                  CV_SHAPE_ELLIPSE))
            #cvErode(edges, edges)
            cvShowImage('edges', edges)

            # do optical flow using edge detection/dilation
            if prev_edges:
                cvCalcOpticalFlowHS(prev_edges, edges, 1, velx, vely, 0.5,
                                     (CV_TERMCRIT_ITER, 10, 0))
                #cvThreshold(vely, vely, 0.5, 0, CV_THRESH_TOZERO)
                cvShowImage('flow', vely)
            prev_edges = edges

            cvThreshold(vely, combined, 0.5, 255, CV_THRESH_BINARY)
            cvMin(combined, edges, combined)
            cvShowImage('combined', combined)

            # blobs
            myblobs = CBlobResult(edges, blob_mask, 100, True)
            myblobs.filter_blobs(10, 10000)
            blob_count = myblobs.GetNumBlobs()

            near_player = []
            far_player = []
            possible_ball = []
            for i in range(blob_count):
                blob = myblobs.GetBlob(i)

                # Group blobs by their center point
                x, y = blob_center(blob)
                if y > 142:
                    near_player.append(blob)
                elif y < 40:
                    far_player.append(blob)
                else:
                    possible_ball.append(blob)
                    
            '''
            # Remove outliers - this was commented out because
            #  it's not as effective as hoped
            outliers = [remove_outlier(near_player), 
                        remove_outlier(far_player)]
            outliers = [x for x in outliers if x]

            print outliers

            # If no ball found in the range y=(40, 145) then
            #  find the closest blob to our state estimate
            #  that is small enough to be a ball.
            if len(possible_ball) == 0:
                outliers = [blob for blob in outliers if blob.Area() < 100]
                if len(outliers) > 0:
                    center = cvKalmanPredict(kf_ball)
                    outliers.sort(key=lambda x: \
                                      distance_sq(blob_center(x), center))
                    possible_ball.append(outliers[0])
            '''

            ball = None
            maxv = -1
            # Find the ball that's moving the fastest
            for blob in possible_ball:
                # get optical flow velocity at blob center
                x, y = blob_center(blob)
                x, y = int(x), int(y)
                # v = magnitude of velocity vector
                v = pow(cvGetReal2D(velx, y, x), 2) + \
                    pow(cvGetReal2D(vely, y, x), 2)
                if v > maxv:
                    ball = blob
                    maxv = v
            if ball and maxv > 0.01:
                x, y = blob_center(ball)
                #cvRectangle(frame, (ball.MinX(), ball.MinY()),
                #            (ball.MaxX(), ball.MaxY()), CV_RGB(0, 255, 0))
                cvRectangle(frame, (x-5,y-5), (x+5,y+5), CV_RGB(0, 255, 0))
                #ball.FillBlob(frame, cvScalar(0, 255, 0), 0, 0)

            # Estimate position of near player
            if len(near_player) > 0:
                # Find x center
                xLocs = []
                yLocs = []
                for blob in near_player:
                    x, y = blob_center(blob)
                    xLocs.append(x)
                    yLocs.append(y)

                if len(xLocs) > 0:
                    xmin, ymin = min(xLocs), min(yLocs)
                    xmax, ymax = max(xLocs), max(yLocs)
                    #cvRectangle(frame, (xmin, ymin), (xmax, ymax),
                    #            CV_RGB(255, 0, 0))

                    y_k = cvKalmanPredict(kf_near)
                    print 'near player at', y_k[0], y_k[1]
                    #draw_cross(frame, y_k, CV_RGB(255, 0, 0), 10)

                    # z1, z2 = position measurement
                    z_k[0], z_k[1] = (xmin+xmax)/2, (ymin+ymax)/2
                    cvMatMulAdd(kf_near.measurement_matrix, x_near, z_k, z_k)
                    cvKalmanCorrect(kf_near, z_k)

                    # apply process noise and update state
                    cvRandArr(rng, w_k, CV_RAND_NORMAL, 0,
                              numpy.sqrt(kf_near.process_noise_cov[0,0]))
                    cvMatMulAdd(kf_near.transition_matrix, x_near, w_k, x_near)

            # Estimate position of far player
            xLocs = []
            yLocs = []
            for blob in far_player:
                x,y = blob_center(blob)
                xLocs.append(x)
                yLocs.append(y)
            if len(xLocs) > 0:
                xmin, ymin = min(xLocs), min(yLocs)
                xmax, ymax = max(xLocs), max(yLocs)
                #cvRectangle(frame, (xmin, ymin), (xmax, ymax),
                #            CV_RGB(0, 0, 255))
                print 'far player at', (xmin+xmax)/2, (ymin+ymax)/2

            # Estimate position of the ball
            y_k = cvKalmanPredict(kf_ball)
            x, y = y_k[0], y_k[1]
            print 'ball at', x, y
            #draw_cross(frame, y_k, CV_RGB(0, 255, 0), 5)

            # kalman filter update
            if ball and maxv > 0.01:
                # z1, z2 = position measurement
                x, y = blob_center(ball)
                z_k[0], z_k[1] = x, y
                # z3, z4 = velocity measurement
                #x, y = int(x), int(y)
                #z_k[2], z_k[3] = cvGetReal2D(velx, y, x), \
                #    cvGetReal2D(vely, y, x)
                cvMatMulAdd(kf_ball.measurement_matrix, x_ball, z_k, z_k)
                cvKalmanCorrect(kf_ball, z_k)

                # apply process noise and update state
                cvRandArr(rng, w_k, CV_RAND_NORMAL, 0,
                          numpy.sqrt(kf_ball.process_noise_cov[0,0]))
                cvMatMulAdd(kf_ball.transition_matrix, x_ball, w_k, x_ball)
            #else:
                #kf_ball.transition_matrix[0,2] = 0
                #kf_ball.transition_matrix[1,3] = 0
                #x_ball = cvKalmanPredict(kf_ball)

            cvShowImage('video', frame)

            ''' crashes
            #hough transform on dilated image
            cvCopy(edges, hough_in)
            cvSmooth(hough_in, hough_in, CV_GAUSSIAN, 15, 15, 0, 0)
            cvHoughCircles(hough_in, hough_storage, CV_HOUGH_GRADIENT,
                            4, frame_size[1]/10, 100, 40, 0, 0)
            print hough_storage
            '''


        k = cvWaitKey(1000/fps)
        if k == 27:  # ESC key
            break
        elif k == 'p':   # play/pause
            play = not play
Ejemplo n.º 11
0
def main():
    if len(sys.argv) == 1:
        print 'Usage: %s [inputfile]' % sys.argv[0]
        sys.exit(1)

    # initialize window
    cv.NamedWindow('video', cv.CV_WINDOW_AUTOSIZE)
    cv.MoveWindow('video', 10, 10)

    cv.NamedWindow('threshold', cv.CV_WINDOW_AUTOSIZE)
    cv.MoveWindow('threshold', 10, 500)

    cv.NamedWindow('flow', cv.CV_WINDOW_AUTOSIZE)
    cv.MoveWindow('flow', 500, 10)

    cv.NamedWindow('edges', cv.CV_WINDOW_AUTOSIZE)
    cv.MoveWindow('edges', 500, 500)

    cv.NamedWindow('combined', cv.CV_WINDOW_AUTOSIZE)
    cv.MoveWindow('combined', 1000, 10)

    capture = cv.CreateFileCapture(sys.argv[1])
    if not capture:
        print 'Error opening capture'
        sys.exit(1)

    # Load bg image
    bg = cv.LoadImage('bg.png')

    # Discard some frames
    for i in xrange(2300):
        cv.GrabFrame(capture)

    frame = cv.QueryFrame(capture)
    frame_size = cv.GetSize(frame)

    # vars for playback
    fps = 25
    play = True
    velx = cv.CreateImage(frame_size, cv.IPL_DEPTH_32F, 1)
    vely = cv.CreateImage(frame_size, cv.IPL_DEPTH_32F, 1)
    combined = cv.CreateImage(frame_size, cv.IPL_DEPTH_8U, 1)
    prev = cv.CreateImage(frame_size, cv.IPL_DEPTH_8U, 1)
    curr = cv.CreateImage(frame_size, cv.IPL_DEPTH_8U, 1)
    frame_sub = cv.CreateImage(frame_size, cv.IPL_DEPTH_8U, 3)

    edges = cv.CreateImage(frame_size, cv.IPL_DEPTH_8U, 1)
    prev_edges = None
    storage = cv.CreateMemStorage(0)

    blob_mask = cv0.cvCreateImage(frame_size, cv.IPL_DEPTH_8U, 1)
    cv0.cvSet(blob_mask, 1)

    hough_in = cv.CreateImage(frame_size, cv.IPL_DEPTH_8U, 1)
    hough_storage = cv.CreateMat(100, 1, cv.CV_32FC3)
    '''
    cv.CvtColor(frame, prev, cv.CV_BGR2GRAY)
    frame = cv.QueryFrame(capture)
    cv.CvtColor(frame, curr, cv.CV_BGR2GRAY)

    # winSize can't have even numbers
    cv.CalcOpticalFlowLK(prev, curr, (3,3), velx, vely)
    cv.ShowImage('video', frame)
    cv.ShowImage('flow', velx)
    cv.WaitKey(0)
    '''

    while True:

        if play:
            frame = cv.QueryFrame(capture)
            cv.Sub(frame, bg, frame_sub)
            '''#detect people
            found = list(cv.HOGDetectMultiScale(frame, storage, win_stride=(8,8),
                padding=(32,32), scale=1.05, group_threshold=2))
            for r in found:
                (rx, ry), (rw, rh) = r
                tl = (rx + int(rw*0.1), ry + int(rh*0.07))
                br = (rx + int(rw*0.9), ry + int(rh*0.87))
                cv.Rectangle(frame, tl, br, (0, 255, 0), 3)
            '''

            #color thresholding
            hsv = cv.CreateImage(frame_size, cv.IPL_DEPTH_8U, 3)
            cv.CvtColor(frame, hsv, cv.CV_BGR2HSV)
            mask = cv.CreateMat(frame_size[1], frame_size[0], cv.CV_8UC1)
            cv.InRangeS(hsv, (0.06 * 256, 0.2 * 256, 0.6 * 256, 0),
                        (0.16 * 256, 1.0 * 256, 1.0 * 256, 0), mask)
            cv.ShowImage('threshold', mask)

            #optical flow method
            # store previous frame
            prev, curr = curr, prev
            # convert next frame to single channel grayscale
            cv.CvtColor(frame_sub, curr, cv.CV_BGR2GRAY)
            #cv.CalcOpticalFlowLK(prev, curr, (3,3), velx, vely)
            #cv.Threshold(velx, velx, 8.0, 0, cv.CV_THRESH_TOZERO)
            cv.CalcOpticalFlowHS(prev, curr, 1, velx, vely, 0.5,
                                 (cv.CV_TERMCRIT_ITER, 10, 0))
            cv.Threshold(velx, velx, 0.5, 0, cv.CV_THRESH_TOZERO)
            cv.Threshold(vely, vely, 0.5, 0, cv.CV_THRESH_TOZERO)
            cv.Erode(
                vely, vely,
                cv.CreateStructuringElementEx(2, 2, 0, 0, cv.CV_SHAPE_ELLIPSE))
            cv.Add(vely, velx, vely)
            cv.ShowImage('flow', vely)

            #edge detection
            cv.Canny(curr, edges, 50, 100)
            cv.Dilate(
                edges, edges,
                cv.CreateStructuringElementEx(7, 7, 0, 0, cv.CV_SHAPE_ELLIPSE))
            cv.ShowImage('edges', edges)

            if prev_edges:
                cv.CalcOpticalFlowHS(prev_edges, edges, 1, velx, vely, 0.5,
                                     (cv.CV_TERMCRIT_ITER, 10, 0))
                cv.Threshold(velx, velx, 0.5, 0, cv.CV_THRESH_TOZERO)
                cv.Threshold(vely, vely, 0.5, 0, cv.CV_THRESH_TOZERO)
                cv.ShowImage('flow', vely)
            prev_edges = edges

            cv.Threshold(vely, combined, 0.5, 255, cv.CV_THRESH_BINARY)
            cv.Min(combined, edges, combined)
            cv.ShowImage('combined', combined)

            # blobs
            myblobs = CBlobResult(edges, blob_mask, 100, False)
            myblobs.filter_blobs(10, 10000)
            blob_count = myblobs.GetNumBlobs()

            for i in range(blob_count):

                my_enumerated_blob = myblobs.GetBlob(i)
                #               print "%d: Area = %d" % (i, my_enumerated_blob.Area())
                my_enumerated_blob.FillBlob(frame,
                                            hsv2rgb(i * 180.0 / blob_count), 0,
                                            0)

            cv.ShowImage('video', frame)
            ''' crashes
            #hough transform on dilated image
            #http://wiki.elphel.com/index.php?
            # title=OpenCV_Tennis_balls_recognizing_tutorial&redirect=no
            cv.Copy(edges, hough_in)
            cv.Smooth(hough_in, hough_in, cv.CV_GAUSSIAN, 15, 15, 0, 0)
            cv.HoughCircles(hough_in, hough_storage, cv.CV_HOUGH_GRADIENT,
                            4, frame_size[1]/10, 100, 40, 0, 0)
            print hough_storage
            '''

        k = cv.WaitKey(1000 / fps)
        if k == 27:  # ESC key
            break
        elif k == 'p':  # play/pause
            play = not play
Ejemplo n.º 12
0
        # 1. capture the current image
        frame = highgui.cvQueryFrame(capture)
        if frame is None:
            # no image captured... end the processing
            break

        # mirror the captured image
        cv.cvFlip(frame, None, 1)

        cv.cvCvtColor(frame, my_grayscale, cv.CV_RGB2GRAY)
        cv.cvThreshold(my_grayscale, my_grayscale, 128, 255, cv.CV_THRESH_BINARY)
        if not blob_overlay:
            # Convert black-and-white version back into three-color representation
            cv.cvCvtColor(my_grayscale, frame, cv.CV_GRAY2RGB)

        myblobs = CBlobResult(my_grayscale, mask, 100, True)

        myblobs.filter_blobs(10, 10000)
        blob_count = myblobs.GetNumBlobs()

        for i in range(blob_count):

            my_enumerated_blob = myblobs.GetBlob(i)
            # 		print "%d: Area = %d" % (i, my_enumerated_blob.Area())
            my_enumerated_blob.FillBlob(frame, hsv2rgb(i * 180.0 / blob_count), 0, 0)

            # we can now display the images
        highgui.cvShowImage("Blob View", frame)

        # handle events
        k = highgui.cvWaitKey(10)