Camera Custom Tracking Type
As you've seen in the previous tutorial step about detecting and attaching to the camera, there are a bunch of events that you can use. One of the events allows you to create a custom tracking type as a plugin, which is real cool!Uses for creating a custom tracking type is if you want to experiment with OpenCV or any other vision libraries. Because ARC leverages .Net, we recommend the x86 nuget install of EMGUCV (https://github.com/emgucv/emgucv). Installing from NUGET is the easiest and most convenient.
The camera events that we'll use for creating a custom tracking type are...
Code:
        // assign an event that raises when the camera wants to initialize tracking types
        _camera.Camera.OnInitCustomTracking += Camera_OnInitCustomTracking;
        // assign an event that raises with a new frame that you can use for tracking
        _camera.OnCustomDetection += Camera_OnCustomDetection;
Once inside the OnCustomDetection() event, you have access to a bunch of different bitmaps throughout the flow of the detection process. They are...
Code:
// **********************
// From the EZ_B.Camera class
// **********************
    /// 
    /// This is a temporary bitmap that we can use to draw on but is lost per tracking type
    /// 
    public volatile Bitmap _WorkerBitmap;
    /// 
    /// This is the resized original bitmap that is never drawn on. Each tracking type uses this as the main source image for tracking, and then draws on the _OutputBitmap for tracking details
    /// 
    public volatile AForge.Imaging.UnmanagedImage _OriginalBitmap; // resized image that we process
    /// 
    /// Image that is outputted to the display. We draw on this bitmap with the tracking details
    /// 
    public volatile AForge.Imaging.UnmanagedImage _OutputBitmap;
    /// 
    /// Raw image unsized directly from the input device
    /// 
    public volatile AForge.Imaging.UnmanagedImage _RawUnsizedBitmap;
    /// 
    /// Last image for the GetCurrentImage 
    /// 
    public volatile AForge.Imaging.UnmanagedImage _RawUnsizedLastBitmap;
Understanding the images available, the ones we care about for creating a tracking type of our own are...
Code:
    /// 
    /// This is the resized original bitmap that is never drawn on. Each tracking type uses this as the main source image for tracking, and then draws on the _OutputBitmap for tracking details
    /// 
    public volatile AForge.Imaging.UnmanagedImage _OriginalBitmap; // resized image that we process
    /// 
    /// Image that is outputted to the display. We draw on this bitmap with the tracking details
    /// 
    public volatile AForge.Imaging.UnmanagedImage _OutputBitmap;
This is because we can use the _OriginalBitmap for our detection, and then draw on the _OutputBitmap where our detection was.
Example
This is an example that fakes detection by drawing a rectangle on the _OutputBitmap that bounces around the screen. It moves with every frame in the CustomDetection event.
Code:
    // faking an object being tracked
    int _xPos = 0;
    int _yPos = 0;
    bool _xDir = true;
    bool _yDir = true;
    private EZ_B.ObjectLocation[] Camera_OnCustomDetection(EZ_Builder.UCForms.FormCameraDevice sender) {
      if (_isClosing)
        return new ObjectLocation[] { };
      if (!_camera.Camera.IsActive)
        return new ObjectLocation[] { };
      List objectLocations = new List();
      try {
        // This is demonstrating how you can return if an object has been detected and draw where it is
        // The camera control will start tracking when more than one ObjectLocation is returned
        // We're just putting fake bouncing rectable of a detected rect which will be displayed as a tracked object on the screen in the camera device
        if (_xDir)
          _xPos += 10;
        else
          _xPos -= 10;
        if (_yDir)
          _yPos += 10;
        else
          _yPos -= 10;
        var r = new Rectangle(_xPos, _yPos, 50, 50);
        if (r.Right > _camera.Camera._OutputBitmap.Width)
          _xDir = false;
        else if (r.Left  _camera.Camera._OutputBitmap.Height)
          _yDir = false;
        else if (r.Top <= 0)
          _yDir = true;
        var objectLocation = new ObjectLocation(ObjectLocation.TrackingTypeEnum.Custom);
        objectLocation.Rect = r;
        objectLocation.HorizontalLocation = _camera.Camera.GetHorizontalLocation(objectLocation.CenterX);
        objectLocation.VerticalLocation = _camera.Camera.GetVerticalLocation(objectLocation.CenterY);
        objectLocations.Add(objectLocation);
        AForge.Imaging.Drawing.Rectangle(_camera.Camera._OutputBitmap, r, Color.MediumSeaGreen);
      } catch (Exception ex) {
        EZ_Builder.EZBManager.Log(ex);
      }
      return objectLocations.ToArray();
    }