/*
 * GStreamer
 * Copyright (C) 2013 Miguel Casas-Sanchez <miguelecasassanchez@gmail.com>
 * Except: Parts of code inside the preprocessor define CODE_FROM_OREILLY_BOOK,
 *  which are downloaded from O'Reilly website
 *  [http://examples.oreilly.com/9780596516130/]
 *  and adapted. Its license reads:
 *  "Oct. 3, 2008
 *   Right to use this code in any way you want without warrenty, support or
 *   any guarentee of it working. "
 *
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Alternatively, the contents of this file may be used under the
 * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
 * which case the following provisions apply instead of the ones
 * mentioned above:
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#define CODE_FROM_OREILLY_BOOK

/**
 * SECTION:element-segmentation
 *
 * This element creates and updates a fg/bg model using one of several approaches.
 * The one called "codebook" refers to the codebook approach following the opencv
 * O'Reilly book [1] implementation of the algorithm described in K. Kim,
 * T. H. Chalidabhongse, D. Harwood and L. Davis [2]. BackgroundSubtractorMOG [3],
 * or MOG for shorts, refers to a Gaussian Mixture-based Background/Foreground
 * Segmentation Algorithm. OpenCV MOG implements the algorithm described in [4].
 * BackgroundSubtractorMOG2 [5], refers to another Gaussian Mixture-based
 * Background/Foreground segmentation algorithm. OpenCV MOG2 implements the
 * algorithm described in [6] and [7].
 *
 * [1] Learning OpenCV: Computer Vision with the OpenCV Library by Gary Bradski
 * and Adrian Kaehler, Published by O'Reilly Media, October 3, 2008
 * [2] "Real-time Foreground-Background Segmentation using Codebook Model",
 * Real-time Imaging, Volume 11, Issue 3, Pages 167-256, June 2005.
 * [3] http://opencv.itseez.com/modules/video/doc/motion_analysis_and_object_tracking.html#backgroundsubtractormog
 * [4] P. KadewTraKuPong and R. Bowden, "An improved adaptive background
 * mixture model for real-time tracking with shadow detection", Proc. 2nd
 * European Workshop on Advanced Video-Based Surveillance Systems, 2001
 * [5] http://opencv.itseez.com/modules/video/doc/motion_analysis_and_object_tracking.html#backgroundsubtractormog2
 * [6] Z.Zivkovic, "Improved adaptive Gausian mixture model for background
 * subtraction", International Conference Pattern Recognition, UK, August, 2004.
 * [7] Z.Zivkovic, F. van der Heijden, "Efficient Adaptive Density Estimation
 * per Image Pixel for the Task of Background Subtraction", Pattern Recognition
 * Letters, vol. 27, no. 7, pages 773-780, 2006.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0  v4l2src device=/dev/video0 ! videoconvert ! segmentation test-mode=true method=2 ! videoconvert ! ximagesink
 * ]|
 * </refsect2>
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "gstsegmentation.h"
#include <opencv2/imgproc/imgproc_c.h>

GST_DEBUG_CATEGORY_STATIC (gst_segmentation_debug);
#define GST_CAT_DEFAULT gst_segmentation_debug

using namespace cv;
#if (CV_MAJOR_VERSION >= 3)
  using namespace cv::bgsegm;
#endif
/* Filter signals and args */
enum
{
  /* FILL ME */
  LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_TEST_MODE,
  PROP_METHOD,
  PROP_LEARNING_RATE
};
typedef enum
{
  METHOD_BOOK,
  METHOD_MOG,
  METHOD_MOG2
} GstSegmentationMethod;

#define DEFAULT_TEST_MODE FALSE
#define DEFAULT_METHOD  METHOD_MOG2
#define DEFAULT_LEARNING_RATE  0.01

#define GST_TYPE_SEGMENTATION_METHOD (gst_segmentation_method_get_type ())
static GType
gst_segmentation_method_get_type (void)
{
  static GType etype = 0;
  if (etype == 0) {
    static const GEnumValue values[] = {
      {METHOD_BOOK, "Codebook-based segmentation (Bradski2008)", "codebook"},
      {METHOD_MOG, "Mixture-of-Gaussians segmentation (Bowden2001)", "mog"},
      {METHOD_MOG2, "Mixture-of-Gaussians segmentation (Zivkovic2004)", "mog2"},
      {0, NULL, NULL},
    };
    etype = g_enum_register_static ("GstSegmentationMethod", values);
  }
  return etype;
}

G_DEFINE_TYPE (GstSegmentation, gst_segmentation, GST_TYPE_OPENCV_VIDEO_FILTER);

static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGBA")));

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("RGBA")));


static void gst_segmentation_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_segmentation_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static GstFlowReturn gst_segmentation_transform_ip (GstOpencvVideoFilter * filter,
    GstBuffer * buffer, IplImage * img);

static gboolean gst_segmentation_stop (GstBaseTransform * basesrc);
static gboolean gst_segmentation_set_caps (GstOpencvVideoFilter * filter, gint in_width,
    gint in_height, gint in_depth, gint in_channels,
    gint out_width, gint out_height, gint out_depth, gint out_channels);
static void gst_segmentation_release_all_pointers (GstSegmentation * filter);

/* Codebook algorithm + connected components functions*/
static int update_codebook (unsigned char *p, codeBook * c,
    unsigned *cbBounds, int numChannels);
static int clear_stale_entries (codeBook * c);
static unsigned char background_diff (unsigned char *p, codeBook * c,
    int numChannels, int *minMod, int *maxMod);
static void find_connected_components (IplImage * mask, int poly1_hull0,
    float perimScale, CvMemStorage * mem_storage, CvSeq * contours);

/* MOG (Mixture-of-Gaussians functions */
static int initialise_mog (GstSegmentation * filter);
static int run_mog_iteration (GstSegmentation * filter);
static int run_mog2_iteration (GstSegmentation * filter);
static int finalise_mog (GstSegmentation * filter);

/* initialize the segmentation's class */
static void
gst_segmentation_class_init (GstSegmentationClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstBaseTransformClass *basesrc_class = GST_BASE_TRANSFORM_CLASS (klass);
  GstOpencvVideoFilterClass *cvfilter_class =
      (GstOpencvVideoFilterClass *) klass;

  gobject_class = (GObjectClass *) klass;

  gobject_class->set_property = gst_segmentation_set_property;
  gobject_class->get_property = gst_segmentation_get_property;

  basesrc_class->stop = gst_segmentation_stop;

  cvfilter_class->cv_trans_ip_func = gst_segmentation_transform_ip;
  cvfilter_class->cv_set_caps = gst_segmentation_set_caps;

  g_object_class_install_property (gobject_class, PROP_METHOD,
      g_param_spec_enum ("method",
          "Segmentation method to use",
          "Segmentation method to use",
          GST_TYPE_SEGMENTATION_METHOD, DEFAULT_METHOD,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));

  g_object_class_install_property (gobject_class, PROP_TEST_MODE,
      g_param_spec_boolean ("test-mode", "test-mode",
          "If true, the output RGB is overwritten with the calculated foreground (white color)",
          DEFAULT_TEST_MODE, (GParamFlags)
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));

  g_object_class_install_property (gobject_class, PROP_LEARNING_RATE,
      g_param_spec_float ("learning-rate", "learning-rate",
          "Speed with which a motionless foreground pixel would become background (inverse of number of frames)",
          0, 1, DEFAULT_LEARNING_RATE, (GParamFlags) (G_PARAM_READWRITE)));

  gst_element_class_set_static_metadata (element_class,
      "Foreground/background video sequence segmentation",
      "Filter/Effect/Video",
      "Create a Foregound/Background mask applying a particular algorithm",
      "Miguel Casas-Sanchez <miguelecasassanchez@gmail.com>");

  gst_element_class_add_static_pad_template (element_class, &src_factory);
  gst_element_class_add_static_pad_template (element_class, &sink_factory);

}

/* initialize the new element
 * instantiate pads and add them to element
 * set pad calback functions
 * initialize instance structure
 */
static void
gst_segmentation_init (GstSegmentation * filter)
{
  filter->method = DEFAULT_METHOD;
  filter->test_mode = DEFAULT_TEST_MODE;
  filter->framecount = 0;
  filter->learning_rate = DEFAULT_LEARNING_RATE;
  gst_opencv_video_filter_set_in_place (GST_OPENCV_VIDEO_FILTER (filter), TRUE);
}

static void
gst_segmentation_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstSegmentation *filter = GST_SEGMENTATION (object);

  switch (prop_id) {
    case PROP_METHOD:
      filter->method = g_value_get_enum (value);
      break;
    case PROP_TEST_MODE:
      filter->test_mode = g_value_get_boolean (value);
      break;
    case PROP_LEARNING_RATE:
      filter->learning_rate = g_value_get_float (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_segmentation_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstSegmentation *filter = GST_SEGMENTATION (object);

  switch (prop_id) {
    case PROP_METHOD:
      g_value_set_enum (value, filter->method);
      break;
    case PROP_TEST_MODE:
      g_value_set_boolean (value, filter->test_mode);
      break;
    case PROP_LEARNING_RATE:
      g_value_set_float (value, filter->learning_rate);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_segmentation_set_caps (GstOpencvVideoFilter * filter, gint in_width,
    gint in_height, gint in_depth, gint in_channels,
    gint out_width, gint out_height, gint out_depth, gint out_channels)
{
  GstSegmentation *segmentation = GST_SEGMENTATION (filter);
  CvSize size;

  size = cvSize (in_width, in_height);
  segmentation->width = in_width;
  segmentation->height = in_height;

  if (NULL != segmentation->cvRGB)
    gst_segmentation_release_all_pointers (segmentation);

  segmentation->cvRGB = cvCreateImage (size, IPL_DEPTH_8U, 3);
  segmentation->cvYUV = cvCreateImage (size, IPL_DEPTH_8U, 3);

  segmentation->cvFG = cvCreateImage (size, IPL_DEPTH_8U, 1);
  cvZero (segmentation->cvFG);

  segmentation->ch1 = cvCreateImage (size, IPL_DEPTH_8U, 1);
  segmentation->ch2 = cvCreateImage (size, IPL_DEPTH_8U, 1);
  segmentation->ch3 = cvCreateImage (size, IPL_DEPTH_8U, 1);

  /* Codebook method */
  segmentation->TcodeBook = (codeBook *)
      g_malloc (sizeof (codeBook) *
      (segmentation->width * segmentation->height + 1));
  for (int j = 0; j < segmentation->width * segmentation->height; j++) {
    segmentation->TcodeBook[j].numEntries = 0;
    segmentation->TcodeBook[j].t = 0;
  }
  segmentation->learning_interval = (int) (1.0 / segmentation->learning_rate);

  /* Mixture-of-Gaussians (mog) methods */
  initialise_mog (segmentation);

  return TRUE;
}

/* Clean up */
static gboolean
gst_segmentation_stop (GstBaseTransform * basesrc)
{
  GstSegmentation *filter = GST_SEGMENTATION (basesrc);

  if (filter->cvRGB != NULL)
    gst_segmentation_release_all_pointers (filter);

  return TRUE;
}

static void
gst_segmentation_release_all_pointers (GstSegmentation * filter)
{
  cvReleaseImage (&filter->cvRGB);
  cvReleaseImage (&filter->cvYUV);
  cvReleaseImage (&filter->cvFG);
  cvReleaseImage (&filter->ch1);
  cvReleaseImage (&filter->ch2);
  cvReleaseImage (&filter->ch3);

  cvReleaseMemStorage (&filter->mem_storage);

  g_free (filter->TcodeBook);
  finalise_mog (filter);
}

static GstFlowReturn
gst_segmentation_transform_ip (GstOpencvVideoFilter * cvfilter, GstBuffer * buffer,
        IplImage * img)
{
  GstSegmentation *filter = GST_SEGMENTATION (cvfilter);
  int j;

  filter->framecount++;

  /*  Image preprocessing: color space conversion etc */
  cvCvtColor (img, filter->cvRGB, CV_RGBA2RGB);
  cvCvtColor (filter->cvRGB, filter->cvYUV, CV_RGB2YCrCb);

  /* Create and update a fg/bg model using a codebook approach following the
   * opencv O'Reilly book [1] implementation of the algo described in [2].
   *
   * [1] Learning OpenCV: Computer Vision with the OpenCV Library by Gary
   * Bradski and Adrian Kaehler, Published by O'Reilly Media, October 3, 2008
   * [2] "Real-time Foreground-Background Segmentation using Codebook Model",
   * Real-time Imaging, Volume 11, Issue 3, Pages 167-256, June 2005. */
  if (METHOD_BOOK == filter->method) {
    unsigned cbBounds[3] = { 10, 5, 5 };
    int minMod[3] = { 20, 20, 20 }, maxMod[3] = {
    20, 20, 20};

    if (filter->framecount < 30) {
      /* Learning background phase: update_codebook on every frame */
      for (j = 0; j < filter->width * filter->height; j++) {
        update_codebook ((unsigned char *) filter->cvYUV->imageData + j * 3,
            (codeBook *) & (filter->TcodeBook[j]), cbBounds, 3);
      }
    } else {
      /*  this updating is responsible for FG becoming BG again */
      if (filter->framecount % filter->learning_interval == 0) {
        for (j = 0; j < filter->width * filter->height; j++) {
          update_codebook ((uchar *) filter->cvYUV->imageData + j * 3,
              (codeBook *) & (filter->TcodeBook[j]), cbBounds, 3);
        }
      }
      if (filter->framecount % 60 == 0) {
        for (j = 0; j < filter->width * filter->height; j++)
          clear_stale_entries ((codeBook *) & (filter->TcodeBook[j]));
      }

      for (j = 0; j < filter->width * filter->height; j++) {
        if (background_diff
            ((uchar *) filter->cvYUV->imageData + j * 3,
                (codeBook *) & (filter->TcodeBook[j]), 3, minMod, maxMod)) {
          filter->cvFG->imageData[j] = (char) 255;
        } else {
          filter->cvFG->imageData[j] = 0;
        }
      }
    }

    /* 3rd param is the smallest area to show: (w+h)/param , in pixels */
    find_connected_components (filter->cvFG, 1, 10000,
        filter->mem_storage, filter->contours);

  }
  /* Create the foreground and background masks using BackgroundSubtractorMOG [1],
   *  Gaussian Mixture-based Background/Foreground segmentation algorithm. OpenCV
   * MOG implements the algorithm described in [2].
   *
   * [1] http://opencv.itseez.com/modules/video/doc/motion_analysis_and_object_tracking.html#backgroundsubtractormog
   * [2] P. KadewTraKuPong and R. Bowden, "An improved adaptive background
   * mixture model for real-time tracking with shadow detection", Proc. 2nd
   * European Workshop on Advanced Video-Based Surveillance Systems, 2001
   */
  else if (METHOD_MOG == filter->method) {
    run_mog_iteration (filter);
  }
  /* Create the foreground and background masks using BackgroundSubtractorMOG2
   * [1], Gaussian Mixture-based Background/Foreground segmentation algorithm.
   * OpenCV MOG2 implements the algorithm described in [2] and [3].
   *
   * [1] http://opencv.itseez.com/modules/video/doc/motion_analysis_and_object_tracking.html#backgroundsubtractormog2
   * [2] Z.Zivkovic, "Improved adaptive Gausian mixture model for background
   * subtraction", International Conference Pattern Recognition, UK, Aug 2004.
   * [3] Z.Zivkovic, F. van der Heijden, "Efficient Adaptive Density Estimation
   * per Image Pixel for the Task of Background Subtraction", Pattern
   * Recognition Letters, vol. 27, no. 7, pages 773-780, 2006.   */
  else if (METHOD_MOG2 == filter->method) {
    run_mog2_iteration (filter);
  }

  /*  if we want to test_mode, just overwrite the output */
  if (filter->test_mode) {
    cvCvtColor (filter->cvFG, filter->cvRGB, CV_GRAY2RGB);

    cvSplit (filter->cvRGB, filter->ch1, filter->ch2, filter->ch3, NULL);
  } else
    cvSplit (img, filter->ch1, filter->ch2, filter->ch3, NULL);

  /*  copy anyhow the fg/bg to the alpha channel in the output image */
  cvMerge (filter->ch1, filter->ch2, filter->ch3, filter->cvFG, img);


  return GST_FLOW_OK;
}

/* entry point to initialize the plug-in
 * initialize the plug-in itself
 * register the element factories and other features
 */
gboolean
gst_segmentation_plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (gst_segmentation_debug, "segmentation",
      0, "Performs Foreground/Background segmentation in video sequences");

  return gst_element_register (plugin, "segmentation", GST_RANK_NONE,
      GST_TYPE_SEGMENTATION);
}



#ifdef CODE_FROM_OREILLY_BOOK   /* See license at the beginning of the page */
/*
  int update_codebook(uchar *p, codeBook &c, unsigned cbBounds)
  Updates the codebook entry with a new data point

  p Pointer to a YUV or HSI pixel
  c Codebook for this pixel
  cbBounds Learning bounds for codebook (Rule of thumb: 10)
  numChannels Number of color channels we¡¯re learning

  NOTES:
  cvBounds must be of length equal to numChannels

  RETURN
  codebook index
*/
int
update_codebook (unsigned char *p, codeBook * c, unsigned *cbBounds,
    int numChannels)
{
/* c->t+=1; */
  unsigned int high[3], low[3];
  int n, i;
  int matchChannel;

  for (n = 0; n < numChannels; n++) {
    high[n] = p[n] + cbBounds[n];
    if (high[n] > 255)
      high[n] = 255;

    if (p[n] > cbBounds[n])
      low[n] = p[n] - cbBounds[n];
    else
      low[n] = 0;
  }

/*  SEE IF THIS FITS AN EXISTING CODEWORD */
  for (i = 0; i < c->numEntries; i++) {
    matchChannel = 0;
    for (n = 0; n < numChannels; n++) {
      if ((c->cb[i]->learnLow[n] <= *(p + n)) &&
/* Found an entry for this channel */
          (*(p + n) <= c->cb[i]->learnHigh[n])) {
        matchChannel++;
      }
    }
    if (matchChannel == numChannels) {  /* If an entry was found */
      c->cb[i]->t_last_update = c->t;
/* adjust this codeword for the first channel */
      for (n = 0; n < numChannels; n++) {
        if (c->cb[i]->max[n] < *(p + n)) {
          c->cb[i]->max[n] = *(p + n);
        } else if (c->cb[i]->min[n] > *(p + n)) {
          c->cb[i]->min[n] = *(p + n);
        }
      }
      break;
    }
  }
/*  OVERHEAD TO TRACK POTENTIAL STALE ENTRIES */
  for (int s = 0; s < c->numEntries; s++) {
/*  Track which codebook entries are going stale: */
    int negRun = c->t - c->cb[s]->t_last_update;
    if (c->cb[s]->stale < negRun)
      c->cb[s]->stale = negRun;
  }
/*  ENTER A NEW CODEWORD IF NEEDED */
  if (i == c->numEntries) {     /* if no existing codeword found, make one */
    code_element **foo =
        (code_element **) g_malloc (sizeof (code_element *) *
        (c->numEntries + 1));
    for (int ii = 0; ii < c->numEntries; ii++) {
      foo[ii] = c->cb[ii];      /* copy all pointers */
    }
    foo[c->numEntries] = (code_element *) g_malloc (sizeof (code_element));
    if (c->numEntries)
      g_free (c->cb);
    c->cb = foo;
    for (n = 0; n < numChannels; n++) {
      c->cb[c->numEntries]->learnHigh[n] = high[n];
      c->cb[c->numEntries]->learnLow[n] = low[n];
      c->cb[c->numEntries]->max[n] = *(p + n);
      c->cb[c->numEntries]->min[n] = *(p + n);
    }
    c->cb[c->numEntries]->t_last_update = c->t;
    c->cb[c->numEntries]->stale = 0;
    c->numEntries += 1;
  }
/*  SLOWLY ADJUST LEARNING BOUNDS */
  for (n = 0; n < numChannels; n++) {
    if (c->cb[i]->learnHigh[n] < high[n])
      c->cb[i]->learnHigh[n] += 1;
    if (c->cb[i]->learnLow[n] > low[n])
      c->cb[i]->learnLow[n] -= 1;
  }
  return (i);
}





/*
 int clear_stale_entries(codeBook &c)
  During learning, after you've learned for some period of time,
  periodically call this to clear out stale codebook entries

  c Codebook to clean up

  Return
  number of entries cleared
*/
int
clear_stale_entries (codeBook * c)
{
  int staleThresh = c->t >> 1;
  int *keep = (int *) g_malloc (sizeof (int) * (c->numEntries));
  int keepCnt = 0;
  code_element **foo;
  int k;
  int numCleared;
/*  SEE WHICH CODEBOOK ENTRIES ARE TOO STALE */
  for (int i = 0; i < c->numEntries; i++) {
    if (c->cb[i]->stale > staleThresh)
      keep[i] = 0;              /* Mark for destruction */
    else {
      keep[i] = 1;              /* Mark to keep */
      keepCnt += 1;
    }
  }
  /*  KEEP ONLY THE GOOD */
  c->t = 0;                     /* Full reset on stale tracking */
  foo = (code_element **) g_malloc (sizeof (code_element *) * keepCnt);
  k = 0;
  for (int ii = 0; ii < c->numEntries; ii++) {
    if (keep[ii]) {
      foo[k] = c->cb[ii];
      /* We have to refresh these entries for next clearStale */
      foo[k]->t_last_update = 0;
      k++;
    }
  }
  /*  CLEAN UP */
  g_free (keep);
  g_free (c->cb);
  c->cb = foo;
  numCleared = c->numEntries - keepCnt;
  c->numEntries = keepCnt;
  return (numCleared);
}



/*
  uchar background_diff( uchar *p, codeBook &c,
  int minMod, int maxMod)
  Given a pixel and a codebook, determine if the pixel is
  covered by the codebook

  p Pixel pointer (YUV interleaved)
  c Codebook reference
  numChannels Number of channels we are testing
  maxMod Add this (possibly negative) number onto

  max level when determining if new pixel is foreground
  minMod Subract this (possibly negative) number from
  min level when determining if new pixel is foreground

  NOTES:
  minMod and maxMod must have length numChannels,
  e.g. 3 channels => minMod[3], maxMod[3]. There is one min and
  one max threshold per channel.

  Return
  0 => background, 255 => foreground
*/
unsigned char
background_diff (unsigned char *p, codeBook * c, int numChannels,
    int *minMod, int *maxMod)
{
  int matchChannel;
/*  SEE IF THIS FITS AN EXISTING CODEWORD */
  int i;
  for (i = 0; i < c->numEntries; i++) {
    matchChannel = 0;
    for (int n = 0; n < numChannels; n++) {
      if ((c->cb[i]->min[n] - minMod[n] <= *(p + n)) &&
          (*(p + n) <= c->cb[i]->max[n] + maxMod[n])) {
        matchChannel++;         /* Found an entry for this channel */
      } else {
        break;
      }
    }
    if (matchChannel == numChannels) {
      break;                    /* Found an entry that matched all channels */
    }
  }
  if (i >= c->numEntries)
    return (255);
  return (0);
}




/*
 void find_connected_components(IplImage *mask, int poly1_hull0,
 float perimScale, int *num,
 CvRect *bbs, CvPoint *centers)
 This cleans up the foreground segmentation mask derived from calls
 to backgroundDiff

 mask Is a grayscale (8-bit depth) â€œrawâ€ mask image that
 will be cleaned up

 OPTIONAL PARAMETERS:
 poly1_hull0 If set, approximate connected component by
 (DEFAULT) polygon, or else convex hull (0)
 perimScale Len = image (width+height)/perimScale. If contour
 len < this, delete that contour (DEFAULT: 4)
 num Maximum number of rectangles and/or centers to
 return; on return, will contain number filled
 (DEFAULT: NULL)
 bbs Pointer to bounding box rectangle vector of
 length num. (DEFAULT SETTING: NULL)
 centers Pointer to contour centers vector of length
 num (DEFAULT: NULL)
*/

/* Approx.threshold - the bigger it is, the simpler is the boundary */
#define CVCONTOUR_APPROX_LEVEL 1
/* How many iterations of erosion and/or dilation there should be */
#define CVCLOSE_ITR 1
static void
find_connected_components (IplImage * mask, int poly1_hull0, float perimScale,
    CvMemStorage * mem_storage, CvSeq * contours)
{
  CvContourScanner scanner;
  CvSeq *c;
  int numCont = 0;
  /* Just some convenience variables */
  const CvScalar CVX_WHITE = CV_RGB (0xff, 0xff, 0xff);
  const CvScalar CVX_BLACK = CV_RGB (0x00, 0x00, 0x00);

  /* CLEAN UP RAW MASK */
  cvMorphologyEx (mask, mask, 0, 0, CV_MOP_OPEN, CVCLOSE_ITR);
  cvMorphologyEx (mask, mask, 0, 0, CV_MOP_CLOSE, CVCLOSE_ITR);
  /* FIND CONTOURS AROUND ONLY BIGGER REGIONS */
  if (mem_storage == NULL) {
    mem_storage = cvCreateMemStorage (0);
  } else {
    cvClearMemStorage (mem_storage);
  }

  scanner = cvStartFindContours (mask, mem_storage, sizeof (CvContour),
      CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint (0, 0));

  while ((c = cvFindNextContour (scanner)) != NULL) {
    double len = cvContourArea (c, CV_WHOLE_SEQ, 0);
    /* calculate perimeter len threshold: */
    double q = (mask->height + mask->width) / perimScale;
    /* Get rid of blob if its perimeter is too small: */
    if (len < q) {
      cvSubstituteContour (scanner, NULL);
    } else {
      /* Smooth its edges if its large enough */
      CvSeq *c_new;
      if (poly1_hull0) {
        /* Polygonal approximation */
        c_new =
            cvApproxPoly (c, sizeof (CvContour), mem_storage, CV_POLY_APPROX_DP,
            CVCONTOUR_APPROX_LEVEL, 0);
      } else {
        /* Convex Hull of the segmentation */
        c_new = cvConvexHull2 (c, mem_storage, CV_CLOCKWISE, 1);
      }
      cvSubstituteContour (scanner, c_new);
      numCont++;
    }
  }
  contours = cvEndFindContours (&scanner);

  /* PAINT THE FOUND REGIONS BACK INTO THE IMAGE */
  cvZero (mask);
  /* DRAW PROCESSED CONTOURS INTO THE MASK */
  for (c = contours; c != NULL; c = c->h_next)
    cvDrawContours (mask, c, CVX_WHITE, CVX_BLACK, -1, CV_FILLED, 8, cvPoint (0,
            0));
}
#endif /*ifdef CODE_FROM_OREILLY_BOOK */


int
initialise_mog (GstSegmentation * filter)
{
  filter->img_input_as_cvMat = (void *) new Mat (cvarrToMat (filter->cvYUV, false));
  filter->img_fg_as_cvMat = (void *) new Mat (cvarrToMat(filter->cvFG, false));

#if (CV_MAJOR_VERSION >= 3)
  filter->mog = bgsegm::createBackgroundSubtractorMOG ();
  filter->mog2 = createBackgroundSubtractorMOG2 ();
#else
  filter->mog = (void *) new BackgroundSubtractorMOG ();
  filter->mog2 = (void *) new BackgroundSubtractorMOG2 ();
#endif

  return (0);
}

int
run_mog_iteration (GstSegmentation * filter)
{
  ((cv::Mat *) filter->img_input_as_cvMat)->data =
      (uchar *) filter->cvYUV->imageData;
  ((cv::Mat *) filter->img_fg_as_cvMat)->data =
      (uchar *) filter->cvFG->imageData;

  /*
     BackgroundSubtractorMOG [1], Gaussian Mixture-based Background/Foreground
     Segmentation Algorithm. OpenCV MOG implements the algorithm described in [2].

     [1] http://opencv.itseez.com/modules/video/doc/motion_analysis_and_object_tracking.html#backgroundsubtractormog
     [2] P. KadewTraKuPong and R. Bowden, "An improved adaptive background
     mixture model for real-time tracking with shadow detection", Proc. 2nd
     European Workshop on Advanced Video-Based Surveillance Systems, 2001
   */

#if (CV_MAJOR_VERSION >= 3)
  filter->mog->apply (*((Mat *) filter->
          img_input_as_cvMat), *((Mat *) filter->img_fg_as_cvMat),
      filter->learning_rate);
#else
  (*((BackgroundSubtractorMOG *) filter->mog)) (*((Mat *) filter->
          img_input_as_cvMat), *((Mat *) filter->img_fg_as_cvMat),
      filter->learning_rate);
#endif

  return (0);
}

int
run_mog2_iteration (GstSegmentation * filter)
{
  ((Mat *) filter->img_input_as_cvMat)->data =
       (uchar *) filter->cvYUV->imageData;
  ((Mat *) filter->img_fg_as_cvMat)->data =
       (uchar *) filter->cvFG->imageData;

  /*
     BackgroundSubtractorMOG2 [1], Gaussian Mixture-based Background/Foreground
     segmentation algorithm. OpenCV MOG2 implements the algorithm described in
     [2] and [3].

     [1] http://opencv.itseez.com/modules/video/doc/motion_analysis_and_object_tracking.html#backgroundsubtractormog2
     [2] Z.Zivkovic, "Improved adaptive Gausian mixture model for background
     subtraction", International Conference Pattern Recognition, UK, August, 2004.
     [3] Z.Zivkovic, F. van der Heijden, "Efficient Adaptive Density Estimation per
     Image Pixel for the Task of Background Subtraction", Pattern Recognition
     Letters, vol. 27, no. 7, pages 773-780, 2006.
   */

#if (CV_MAJOR_VERSION >= 3)
  filter->mog2->apply (*((Mat *) filter->
          img_input_as_cvMat), *((Mat *) filter->img_fg_as_cvMat),
      filter->learning_rate);
#else
  (*((BackgroundSubtractorMOG *) filter->mog2)) (*((Mat *) filter->
          img_input_as_cvMat), *((Mat *) filter->img_fg_as_cvMat),
      filter->learning_rate);
#endif

  return (0);
}

int
finalise_mog (GstSegmentation * filter)
{
  delete (Mat *) filter->img_input_as_cvMat;
  delete (Mat *) filter->img_fg_as_cvMat;
#if (CV_MAJOR_VERSION >= 3)
  filter->mog.release ();
  filter->mog2.release ();
#else
  delete (BackgroundSubtractorMOG *) filter->mog;
  delete (BackgroundSubtractorMOG2 *) filter->mog2;
#endif
  return (0);
}
