<commit_before>/*

 * code.cpp
 *
 *  Created on: Oct 30, 2015
 *      Author: (Bu)nn

 TODO

 * Background Subtration to get just the hand (binarized image)
 *

 */

#include <core/cvdef.h>
#include <core/cvstd.hpp>
#include <core/mat.hpp>
#include <core/mat.inl.hpp>
#include <core/matx.hpp>
#include <core/ptr.inl.hpp>
#include <core/types.hpp>
#include <core.hpp>
#include <highgui.hpp>
#include <imgproc/types_c.h>
#include <imgproc.hpp>
#include <video/background_segm.hpp>
#include <videoio.hpp>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <utility>
#include <vector>

using namespace cv;
using namespace std;

Mat frame; //current frame
Mat fgMaskMOG2; //fg mask fg mask generated by MOG2 method
Mat back;
Ptr<BackgroundSubtractorMOG2> pMOG2; //MOG2 Background subtractor
vector<pair<Point, double>> palm_centers;

//This function returns the square of the euclidean distance between 2 points.
double dist(Point x, Point y) {
  return (x.x - y.x) * (x.x - y.x) + (x.y - y.y) * (x.y - y.y);
}

/*
void CallBackFunc(int event, int x, int y, int d, void *ptr)
{
     if  ( event == EVENT_LBUTTONDOWN )
     {
          cout << "Left button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
     }
     else if  ( event == EVENT_RBUTTONDOWN )
     {
          cout << "Right button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
     }
     else if  ( event == EVENT_MBUTTONDOWN )
     {
          cout << "Middle button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
     }
     else if ( event == EVENT_MOUSEMOVE )
     {
          cout << "Mouse move over the window - position (" << x << ", " << y << ")" << endl;

     }

     Point*p = (Point*)ptr;
     p->x = x;
     p->y = y;
}
*/

void on_mouse( int e, int x, int y, int d, void *ptr )
{
    Point*p = (Point*)ptr;
    p->x = x;
    p->y = y;
}

Mat pre_processing(Mat frame) {

//  GaussianBlur(frame, frame, Size(7, 7), 10, 10);
  Mat gray_scale;
  cvtColor(frame, gray_scale, COLOR_BGR2GRAY, 1);

  Mat element = (Mat_<uchar>(3, 3) << 0, 1, 0, 1, 1, 1, 0, 1, 0);
  morphologyEx(gray_scale, gray_scale, MORPH_OPEN, element);

  return gray_scale;
}

Mat bg_subtraction(VideoCapture cap, Mat frame) {
  //update the background model
  pMOG2->apply(frame, fgMaskMOG2);

  //Get background image to display it
  pMOG2->getBackgroundImage(back);
  pMOG2->setDetectShadows(0);
  pMOG2->setNMixtures(3);
  return fgMaskMOG2;
}

//This function returns the radius and the center of the circle given 3 points
//If a circle cannot be formed , it returns a zero radius circle centered at (0,0)
pair<Point, double> circleFromPoints(Point p1, Point p2, Point p3) {
  double offset = pow(p2.x, 2) + pow(p2.y, 2);
  double bc = (pow(p1.x, 2) + pow(p1.y, 2) - offset) / 2.0;
  double cd = (offset - pow(p3.x, 2) - pow(p3.y, 2)) / 2.0;
  double det = (p1.x - p2.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p2.y);
  double TOL = 0.0000001;
  if (abs(det) < TOL) {
    cout << "POINTS TOO CLOSE" << endl;
    return make_pair(Point(0, 0), 0);
  }

  double idet = 1 / det;
  double centerx = (bc * (p2.y - p3.y) - cd * (p1.y - p2.y)) * idet;
  double centery = (cd * (p1.x - p2.x) - bc * (p2.x - p3.x)) * idet;
  double radius = sqrt(pow(p2.x - centerx, 2) + pow(p2.y - centery, 2));

  return make_pair(Point(centerx, centery), radius);
}

Mat contouring(Mat binarized, Mat pre_processed) {
  vector<vector<Point>> contours;

  //Find the contours in the foreground

  findContours(binarized, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
  imshow("Binary", binarized);

  for (int i = 0; i < contours.size(); i++)
    //Ignore all small insignificant areas
    if (contourArea(contours[i]) >= 5000) {
      //Draw contour
      vector<vector<Point>> tcontours;
      tcontours.push_back(contours[i]);
      drawContours(pre_processed, tcontours, -1, Scalar(0, 0, 255), 2);

      //Detect Hull in current contour
      vector<vector<Point> > hulls(1);
      vector<vector<int> > hullsI(1);
      convexHull(Mat(tcontours[0]), hulls[0], false);
      convexHull(Mat(tcontours[0]), hullsI[0], false);
      drawContours(pre_processed, hulls, -1, Scalar(0, 255, 0), 2);

      //Find minimum area rectangle to enclose hand
      RotatedRect rect = minAreaRect(Mat(tcontours[0]));

      //Find Convex Defects
      vector<Vec4i> defects;
      if (hullsI[0].size() > 0) {
        Point2f rect_points[4];
        rect.points(rect_points);
        for (int j = 0; j < 4; j++)
          line(pre_processed, rect_points[j], rect_points[(j + 1) % 4],
              Scalar(255, 0, 0), 1, 8);
        Point rough_palm_center;
        convexityDefects(tcontours[0], hullsI[0], defects);
        if (defects.size() >= 3) {
          vector<Point> palm_points;
          for (int j = 0; j < defects.size(); j++) {
            int startidx = defects[j][0];
            Point ptStart(tcontours[0][startidx]);
            int endidx = defects[j][1];
            Point ptEnd(tcontours[0][endidx]);
            int faridx = defects[j][2];
            Point ptFar(tcontours[0][faridx]);
            //Sum up all the hull and defect points to compute average
            rough_palm_center += ptFar + ptStart + ptEnd;
            palm_points.push_back(ptFar);
            palm_points.push_back(ptStart);
            palm_points.push_back(ptEnd);
          }

          //Get palm center by 1st getting the average of all defect points, this is the rough palm center,
          //Then U chose the closest 3 points ang get the circle radius and center formed from them which is the palm center.
          rough_palm_center.x /= defects.size() * 3;
          rough_palm_center.y /= defects.size() * 3;
          Point closest_pt = palm_points[0];
          vector<pair<double, int> > distvec;
          for (int i = 0; i < palm_points.size(); i++)
            distvec.push_back(
                make_pair(dist(rough_palm_center, palm_points[i]), i));
          sort(distvec.begin(), distvec.end());

          //Keep choosing 3 points till you find a circle with a valid radius
          //As there is a high chance that the closes points might be in a linear line or too close that it forms a very large circle
          pair<Point, double> soln_circle;
          for (int i = 0; i + 2 < distvec.size(); i++) {
            Point p1 = palm_points[distvec[i + 0].second];
            Point p2 = palm_points[distvec[i + 1].second];
            Point p3 = palm_points[distvec[i + 2].second];
            soln_circle = circleFromPoints(p1, p2, p3); //Final palm center,radius
            if (soln_circle.second != 0)
              break;
          }

          //Find avg palm centers for the last few frames to stabilize its centers, also find the avg radius
          palm_centers.push_back(soln_circle);
          if (palm_centers.size() > 10)
            palm_centers.erase(palm_centers.begin());

          Point palm_center;
          double radius = 0;

          //averaging all palm centres
          for (int i = 0; i < palm_centers.size(); i++) {
            palm_center += palm_centers[i].first;
            radius += palm_centers[i].second;
          }
          palm_center.x /= palm_centers.size();
          palm_center.y /= palm_centers.size();
          radius /= palm_centers.size();

          //Draw the palm center and the palm circle
          //The size of the palm gives the depth of the hand
          circle(frame, palm_center, 5, Scalar(144, 144, 255), 3);
          circle(frame, palm_center, radius, Scalar(144, 144, 255), 2);

          //Detect fingers by finding points that form an almost isosceles triangle with certain thesholds
          int no_of_fingers = 0;
          for (int j = 0; j < defects.size(); j++) {
            int startidx = defects[j][0];
            Point ptStart(tcontours[0][startidx]);
            int endidx = defects[j][1];
            Point ptEnd(tcontours[0][endidx]);
            int faridx = defects[j][2];
            Point ptFar(tcontours[0][faridx]);
            //X o--------------------------o Y
            double Xdist = sqrt(dist(palm_center, ptFar));
            double Ydist = sqrt(dist(palm_center, ptStart));
            double length = sqrt(dist(ptFar, ptStart));

            double retLength = sqrt(dist(ptEnd, ptFar));
            //Play with these thresholds to improve performance
            if (length <= 3 * radius && Ydist >= 0.4 * radius && length >= 10
                && retLength >= 10
                && max(length, retLength) / min(length, retLength) >= 0.8)
              if (min(Xdist, Ydist) / max(Xdist, Ydist) <= 0.8) {
                if ((Xdist >= 0.1 * radius && Xdist <= 1.3 * radius
                    && Xdist < Ydist)
                    || (Ydist >= 0.1 * radius && Ydist <= 1.3 * radius
                        && Xdist > Ydist))
                  line(frame, ptEnd, ptFar, Scalar(0, 255, 0), 1), no_of_fingers++;
              }
          }
           no_of_fingers = min(5, no_of_fingers);
           cout << "NO OF FINGERS: " << no_of_fingers << endl;

           putText(pre_processed, "NO OF FINGERS: " + to_string(no_of_fingers), Point(30,30),
               FONT_HERSHEY_COMPLEX_SMALL, 0.8, Scalar(200,200,250), 1, CV_AA);

//           setMouseCallback("Frame", on_mouse, &palm_center);

/*           if(no_of_fingers == 1){
             cout << "NO OF FINGERS: " << no_of_fingers << endl;
             // Draw a line
             line( frame, palm_center,palm_centers[10].first, Scalar( 110, 220, 0 ),  2, 8 );

//             imshow("Line",frame);
           }*/
           }
      }

    }

  return pre_processed;
}

int process_video() {

  VideoCapture cap(0); // open the default camera
  if (!cap.isOpened())  // check if we succeeded
    return -1;

  for (;;) {

    //Capture the Frame and convert it to Grayscale
    cap >> frame; // get a new frame from camera

    Mat foreground;
    Mat i1 = pre_processing(frame);
    Mat bg_sub = bg_subtraction(cap, i1);
    absdiff(i1, back, foreground);

    Mat fg_binarized;
    threshold(foreground, fg_binarized, 0, 255, THRESH_BINARY | THRESH_OTSU);

    Mat contour = contouring(fg_binarized,frame);

    imshow("Frame", contour);
//    imshow("FG Mask MOG 2",bg_sub);
//    imshow("Background",back);
    if (waitKey(30) >= 0)
      break;
  }

  return 0;
}

int main(int, char**) {
  //create Background Subtractor objects
  pMOG2 = createBackgroundSubtractorMOG2(); //MOG2 approach
  int res = process_video();
  //Create a window
  namedWindow("Frame", 1);
  return 0;
}

<commit_msg>Circles drawn when one finger<commit_after>/*

 * code.cpp
 *
 *  Created on: Oct 30, 2015
 *      Author: (Bu)nn

 TODO

 * Background Subtration to get just the hand (binarized image)
 *

 */

#include <core/cvdef.h>
#include <core/cvstd.hpp>
#include <core/mat.hpp>
#include <core/mat.inl.hpp>
#include <core/matx.hpp>
#include <core/ptr.inl.hpp>
#include <core/types.hpp>
#include <core.hpp>
#include <highgui.hpp>
#include <imgproc/types_c.h>
#include <imgproc.hpp>
#include <video/background_segm.hpp>
#include <videoio.hpp>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <utility>
#include <vector>

using namespace cv;
using namespace std;

Mat frame; //current frame
Mat fgMaskMOG2; //fg mask fg mask generated by MOG2 method
Mat back;
Ptr<BackgroundSubtractorMOG2> pMOG2; //MOG2 Background subtractor
vector<pair<Point, double>> palm_centers;
Mat draw;
//This function returns the square of the euclidean distance between 2 points.
double dist(Point x, Point y) {
  return (x.x - y.x) * (x.x - y.x) + (x.y - y.y) * (x.y - y.y);
}

/*
void CallBackFunc(int event, int x, int y, int d, void *ptr)
{
     if  ( event == EVENT_LBUTTONDOWN )
     {
          cout << "Left button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
     }
     else if  ( event == EVENT_RBUTTONDOWN )
     {
          cout << "Right button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
     }
     else if  ( event == EVENT_MBUTTONDOWN )
     {
          cout << "Middle button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
     }
     else if ( event == EVENT_MOUSEMOVE )
     {
          cout << "Mouse move over the window - position (" << x << ", " << y << ")" << endl;

     }

     Point*p = (Point*)ptr;
     p->x = x;
     p->y = y;
}
*/

/*
void on_mouse( int e, int x, int y, int d, void *ptr )
{
    Point*p = (Point*)ptr;
    p->x = x;
    p->y = y;
}
*/

Mat pre_processing(Mat frame) {

//  GaussianBlur(frame, frame, Size(7, 7), 10, 10);
  Mat gray_scale;
  cvtColor(frame, gray_scale, COLOR_BGR2GRAY, 1);

  Mat element = (Mat_<uchar>(3, 3) << 0, 1, 0, 1, 1, 1, 0, 1, 0);
  morphologyEx(gray_scale, gray_scale, MORPH_OPEN, element);

  return gray_scale;
}

Mat bg_subtraction(VideoCapture cap, Mat frame) {
  //update the background model
  pMOG2->apply(frame, fgMaskMOG2);

  //Get background image to display it
  pMOG2->getBackgroundImage(back);
  pMOG2->setDetectShadows(0);
  pMOG2->setNMixtures(3);
  return fgMaskMOG2;
}

//This function returns the radius and the center of the circle given 3 points
//If a circle cannot be formed , it returns a zero radius circle centered at (0,0)
pair<Point, double> circleFromPoints(Point p1, Point p2, Point p3) {
  double offset = pow(p2.x, 2) + pow(p2.y, 2);
  double bc = (pow(p1.x, 2) + pow(p1.y, 2) - offset) / 2.0;
  double cd = (offset - pow(p3.x, 2) - pow(p3.y, 2)) / 2.0;
  double det = (p1.x - p2.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p2.y);
  double TOL = 0.0000001;
  if (abs(det) < TOL) {
    cout << "POINTS TOO CLOSE" << endl;
    return make_pair(Point(0, 0), 0);
  }

  double idet = 1 / det;
  double centerx = (bc * (p2.y - p3.y) - cd * (p1.y - p2.y)) * idet;
  double centery = (cd * (p1.x - p2.x) - bc * (p2.x - p3.x)) * idet;
  double radius = sqrt(pow(p2.x - centerx, 2) + pow(p2.y - centery, 2));

  return make_pair(Point(centerx, centery), radius);
}

Mat contouring(Mat binarized, Mat pre_processed) {
  vector<vector<Point>> contours;

  //Find the contours in the binarized foreground

  findContours(binarized, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
//  imshow("Binary", binarized);

  for (int i = 0; i < contours.size(); i++)
    //Ignore all small insignificant areas
    if (contourArea(contours[i]) >= 5000) {
      //Draw contour
      vector<vector<Point>> tcontours;
      tcontours.push_back(contours[i]);
      drawContours(pre_processed, tcontours, -1, Scalar(0, 0, 255), 2);

      //Detect Hull in current contour
      vector<vector<Point> > hulls(1);
      vector<vector<int> > hullsI(1);
      convexHull(Mat(tcontours[0]), hulls[0], false);
      convexHull(Mat(tcontours[0]), hullsI[0], false);
      drawContours(pre_processed, hulls, -1, Scalar(0, 255, 0), 2);

      //Find minimum area rectangle to enclose hand
      RotatedRect rect = minAreaRect(Mat(tcontours[0]));

      //Find Convex Defects
      vector<Vec4i> defects;
      if (hullsI[0].size() > 0) {
        Point2f rect_points[4];
        rect.points(rect_points);
        for (int j = 0; j < 4; j++)
          line(pre_processed, rect_points[j], rect_points[(j + 1) % 4],
              Scalar(255, 0, 0), 1, 8);
        Point rough_palm_center;
        convexityDefects(tcontours[0], hullsI[0], defects);
        if (defects.size() >= 3) {
          vector<Point> palm_points;
          for (int j = 0; j < defects.size(); j++) {
            int startidx = defects[j][0];
            Point ptStart(tcontours[0][startidx]);
            int endidx = defects[j][1];
            Point ptEnd(tcontours[0][endidx]);
            int faridx = defects[j][2];
            Point ptFar(tcontours[0][faridx]);
            //Sum up all the hull and defect points to compute average
            rough_palm_center += ptFar + ptStart + ptEnd;
            palm_points.push_back(ptFar);
            palm_points.push_back(ptStart);
            palm_points.push_back(ptEnd);
          }

          //Get palm center by 1st getting the average of all defect points, this is the rough palm center,
          //Then U chose the closest 3 points ang get the circle radius and center formed from them which is the palm center.
          rough_palm_center.x /= defects.size() * 3;
          rough_palm_center.y /= defects.size() * 3;
          Point closest_pt = palm_points[0];
          vector<pair<double, int> > distvec;
          for (int i = 0; i < palm_points.size(); i++)
            distvec.push_back(
                make_pair(dist(rough_palm_center, palm_points[i]), i));
          sort(distvec.begin(), distvec.end());

          //Keep choosing 3 points till you find a circle with a valid radius
          //As there is a high chance that the closes points might be in a linear line or too close that it forms a very large circle
          pair<Point, double> soln_circle;
          for (int i = 0; i + 2 < distvec.size(); i++) {
            Point p1 = palm_points[distvec[i + 0].second];
            Point p2 = palm_points[distvec[i + 1].second];
            Point p3 = palm_points[distvec[i + 2].second];
            soln_circle = circleFromPoints(p1, p2, p3); //Final palm center,radius
            if (soln_circle.second != 0)
              break;
          }

          //Find avg palm centers for the last few frames to stabilize its centers, also find the avg radius
          palm_centers.push_back(soln_circle);
          if (palm_centers.size() > 10)
            palm_centers.erase(palm_centers.begin());

          Point palm_center;
          double radius = 0;

          //averaging all palm centres
          for (int i = 0; i < palm_centers.size(); i++) {
            palm_center += palm_centers[i].first;
            radius += palm_centers[i].second;
          }
          palm_center.x /= palm_centers.size();
          palm_center.y /= palm_centers.size();
          radius /= palm_centers.size();

          //Draw the palm center and the palm circle
          //The size of the palm gives the depth of the hand
          circle(pre_processed, palm_center, 5, Scalar(144, 144, 255), 3);
          circle(pre_processed, palm_center, radius, Scalar(144, 144, 255), 2);

          //Detect fingers by finding points that form an almost isosceles triangle with certain thesholds
          int no_of_fingers = 0;
          for (int j = 0; j < defects.size(); j++) {
            int startidx = defects[j][0];
            Point ptStart(tcontours[0][startidx]);
            int endidx = defects[j][1];
            Point ptEnd(tcontours[0][endidx]);
            int faridx = defects[j][2];
            Point ptFar(tcontours[0][faridx]);
            //X o--------------------------o Y
            double Xdist = sqrt(dist(palm_center, ptFar));
            double Ydist = sqrt(dist(palm_center, ptStart));
            double length = sqrt(dist(ptFar, ptStart));

            double retLength = sqrt(dist(ptEnd, ptFar));
            //Play with these thresholds to improve performance
            if (length <= 3 * radius && Ydist >= 0.4 * radius && length >= 10
                && retLength >= 10
                && max(length, retLength) / min(length, retLength) >= 0.8)
              if (min(Xdist, Ydist) / max(Xdist, Ydist) <= 0.8) {
                if ((Xdist >= 0.1 * radius && Xdist <= 1.3 * radius
                    && Xdist < Ydist)
                    || (Ydist >= 0.1 * radius && Ydist <= 1.3 * radius
                        && Xdist > Ydist))
                  line(pre_processed, ptEnd, ptFar, Scalar(0, 255, 0), 1), no_of_fingers++;
              }
          }
           no_of_fingers = min(5, no_of_fingers);
           cout << "NO OF FINGERS: " << no_of_fingers << endl;

     /*      putText(pre_processed, "NO OF FINGERS: " + to_string(no_of_fingers), Point(30,30),
               FONT_HERSHEY_COMPLEX_SMALL, 0.8, Scalar(200,200,250), 1, CV_AA);
*/

//           addWeighted(pre_processed,1,draw,0,0,pre_processed);

           if(no_of_fingers == 1){
             cout << "NO OF FINGERS: " << no_of_fingers << endl;
             //draw on draw
                        circle(draw, palm_center, 10, Scalar(144, 144, 255), 2);
                        imshow("draw",draw);

//             imshow("Line",frame);
           }
           }
      }

    }

  return pre_processed;
}

int process_video() {

  VideoCapture cap(0); // open the default camera
  if (!cap.isOpened())  // check if we succeeded
    return -1;

  Size s = Size(640,480);
  draw = Mat::zeros(s,CV_8UC3);

//  draw = Scalar(255,255,255,0);

  for (;;) {

    //Capture the Frame and convert it to Grayscale
    cap >> frame; // get a new frame from camera

    Mat foreground;
    Mat pre_processed = pre_processing(frame);
    Mat bg_sub = bg_subtraction(cap, pre_processed);
    absdiff(pre_processed, back, foreground);

    Mat fg_binarized;
    threshold(foreground, fg_binarized, 0, 255, THRESH_BINARY | THRESH_OTSU);

    Mat element = (Mat_<uchar>(3, 3) << 0, 1, 0, 1, 1, 1, 0, 1, 0);
    morphologyEx(frame, frame, MORPH_OPEN, element);

    Mat contour = contouring(fg_binarized,frame);

    imshow("Frame", contour);
//    imshow("FG Mask MOG 2",bg_sub);
//    imshow("Background",back);
    if (waitKey(30) >= 0)
      break;
  }

  return 0;
}

int main(int, char**) {
  //create Background Subtractor objects
  pMOG2 = createBackgroundSubtractorMOG2(); //MOG2 approach
  int res = process_video();
  return 0;
}

<|endoftext|>


<commit_before>/* Copyright 1988 - 1999 by Abacus Research and
 * Development, Inc.  All rights reserved.
 */

/* Forward declarations in SysErr.h (DO NOT DELETE THIS LINE) */

#include <base/common.h>
#include <QuickDraw.h>
#include <CQuickDraw.h>
#include <EventMgr.h>
#include <ToolboxEvent.h>
#include <DialogMgr.h>
#include <OSUtil.h>
#include <SegmentLdr.h>
#include <SysErr.h>
#include <MemoryMgr.h>
#include <BinaryDecimal.h>
#include <LowMem.h>

#include <quickdraw/cquick.h>
#include <quickdraw/quick.h>
#include <rsys/segment.h>
#include <commandline/flags.h>
#include <rsys/version.h>
#include <osevent/osevent.h>
#include <prefs/options.h>
#include <error/syserr.h>

using namespace Executor;

static myalerttab_t myalerttab = {
    8,

#define WELCOME_CODE 0x28
    WELCOME_CODE, /* 1. normally "Welcome to M*cintosh", now copyright stuff */
    10,
    50,
    150,
    31,
    0,
    151,

    50, /* 2. primary text */
    56,
    { 108, 105 },
    "\251 Abacus Research and Development, Inc.  1986-1999",

    31, /* 3. ARDI icon */
    136,
    { 99, 56, 131, 88 },
    { { 0xff, 0xff, 0xff, 0xff },
      { 0x88, 0x88, 0x88, 0x89 },
      { 0x9d, 0xdd, 0xdd, 0xdd },
      { 0x88, 0x88, 0x88, 0x89 },
      { 0x9d, 0xdd, 0xdd, 0xdd },
      { 0x88, 0x88, 0x88, 0x89 },
      { 0xff, 0xff, 0xff, 0xff },
      { 0x88, 0x88, 0x88, 0x89 },
      { 0x88, 0x88, 0x88, 0x89 },
      { 0x88, 0x80, 0x80, 0x89 },
      { 0x88, 0xbc, 0xbc, 0x89 },
      { 0x80, 0xa2, 0x92, 0x81 },
      { 0x88, 0xa2, 0x92, 0x9d },
      { 0x94, 0xa2, 0x92, 0x89 },
      { 0xa2, 0xbc, 0x92, 0x89 },
      { 0xa2, 0xa8, 0x92, 0x89 },
      { 0xa2, 0xa4, 0x92, 0x89 },
      { 0xbe, 0xa2, 0x92, 0x89 },
      { 0xa2, 0xa2, 0x92, 0x89 },
      { 0xa2, 0xa2, 0x92, 0x89 },
      { 0xa2, 0xa2, 0xbc, 0x9d },
      { 0x80, 0x80, 0x80, 0x81 },
      { 0x88, 0x88, 0x88, 0x89 },
      { 0x88, 0x88, 0x88, 0x89 },
      { 0xff, 0xff, 0xff, 0xff } },

    150, /* 4. secondary text */
    50,
    { 122, 125 },
    "Please click on \"Info\" for more information\0\0",

    151, /* 5. the buttons */
    26,
    2,
    153,
    { 150, 50, 170, 100 }, /* OK rect */
    0,
    155,
    { 150, 130, 170, 190 }, /* Abort rect */
    156,

    153, /* 6. OK button */
    4,
    "OK\0",

    155, /* 7. Info button */
    6,
    "Info\0",

    156, /* 8. Info "procedure" */
    4,
    nullptr, /* was mydolicense, which we no longer use */
};

char syserr_msg[256];

static GUEST<INTEGER> *findid(INTEGER);
static void drawtextstring(INTEGER id, INTEGER offsetx, INTEGER offsety);
static void drawicon(INTEGER id, INTEGER offsetx, INTEGER offsety);
static void dobuttons(INTEGER id, INTEGER offsetx, INTEGER offsety);

static GUEST<INTEGER> *findid(INTEGER id)
{
    int i;
    GUEST<INTEGER> *ip;

    for(i = *(GUEST<INTEGER> *)LM(DSAlertTab),
    ip = (GUEST<INTEGER> *)LM(DSAlertTab) + 1;
        i > 0 && *ip != id;
        --i, ip = (GUEST<INTEGER> *)((char *)ip + ip[1] + 2 * sizeof(INTEGER)))
        ;
    return i > 0 ? ip : nullptr;
}

static void drawtextstring(INTEGER id, INTEGER offsetx, INTEGER offsety)
{
    struct tdef *tp;

    if(id && (tp = (struct tdef *)findid(id)))
    {
        MoveTo(tp->loc.h + offsetx, tp->loc.v + offsety);
        DrawText_c_string(tp->text);
    }
}

static void drawicon(INTEGER id, INTEGER offsetx, INTEGER offsety)
{
    struct idef *ip;
    BitMap bm;
    Rect old_loc;

    ip = (struct idef *)findid(id);
    if(id && ip)
    {
        bm.baseAddr = (Ptr)ip->ike;
        bm.rowBytes = 4;
        bm.bounds.left = bm.bounds.top = 0;
        bm.bounds.right = bm.bounds.bottom = 32;
        old_loc = ip->loc;
        C_OffsetRect(&ip->loc, offsetx, offsety);
        CopyBits(&bm, PORT_BITS_FOR_COPY(qdGlobals().thePort),
                 &bm.bounds, &ip->loc, srcCopy, nullptr);
        ip->loc = old_loc;
    }
}

static void dobuttons(INTEGER id, INTEGER offsetx, INTEGER offsety)
{
    struct bdef *bp;
    struct sdef *sp;
    struct pdef *pp;
    int i;
    EventRecord evt;
    int done;
    int tcnt, twid;
    Point p;
#define BILLBUTTONS /*  */
#if defined(BILLBUTTONS)
    INTEGER h, v;
#endif /* BILLBUTTONS */
    char *textp;

    if((bp = (struct bdef *)findid(id)))
    {
        for(i = 0; i < bp->nbut; i++)
        {

            /* Offset buttons; this hack is to center the splash screen
	     * on non-512x342 root windows...yuck!
	     */

            C_OffsetRect(&bp->buts[i].butloc, offsetx, offsety);
            if((sp = (struct sdef *)findid(bp->buts[i].butstrid)))
            {
                textp = sp->text;
                tcnt = strlen(textp);
                twid = TextWidth((Ptr)textp, 0, tcnt);
                MoveTo((bp->buts[i].butloc.left + bp->buts[i].butloc.right - twid) / 2,
                       (bp->buts[i].butloc.top + bp->buts[i].butloc.bottom) / 2 + 4);
                DrawText((Ptr)textp, 0, tcnt);
            }
#if defined(BILLBUTTONS)
            h = bp->buts[i].butloc.right - bp->buts[i].butloc.left;
            v = (bp->buts[i].butloc.bottom - bp->buts[i].butloc.top) / 2;
            if(h > v)
                h = v;
            if(!(ROMlib_options & ROMLIB_RECT_SCREEN_BIT))
                FrameRoundRect(&bp->buts[i].butloc, h, v);
            else
                FrameRect(&bp->buts[i].butloc);
#else /* BILLBUTTONS */
            if(!(ROMlib_options & ROMLIB_RECT_SCREEN_BIT))
                FrameRoundRect(&bp->buts[i].butloc, 10, 10);
            else
                FrameRect(&bp->buts[i].butloc);
#endif /* BILLBUTTONS */
        }

        for(done = 0; !done;)
        {
            C_GetNextEvent(mDownMask | keyDownMask, &evt);
            if(evt.what == mouseDown || evt.what == keyDown)
            {
                p.h = evt.where.h;
                p.v = evt.where.v;
                for(i = 0; !done && i < bp->nbut; i++)
                {
                    if(PtInRect(p, &bp->buts[i].butloc) || ((evt.what == keyDown) && (((evt.message & charCodeMask) == '\r') || ((evt.message & charCodeMask) == NUMPAD_ENTER))))
                    {
                        if((pp = (struct pdef *)
                                findid(bp->buts[i].butprocid)))
                            /* NOTE:  we will have to do a better
				      job here sometime */
                            (*(void (*)(void))pp->proc)();
                        done = 1;
                    }
                }
                if(!done)
                    SysBeep(1);
            }
        }
        if(evt.what == mouseDown)
            while(!C_GetNextEvent(mUpMask, &evt))
                ;

        /* Move all buttons back. */
        for(i = 0; i < bp->nbut; i++)
            C_OffsetRect(&bp->buts[i].butloc, -offsetx, -offsety);
    }
}

/*
 * NOTE: The version of SysError below will only handle natively compiled
 *	 code.  When we want to be able to run arbitrary code we'll need
 *	 to call syn68k appropriately.
 */

void Executor::C_SysError(short errorcode)
{
    GrafPort alertport;
    Region viscliprgn;
    GUEST<RgnPtr> rp;
    Rect r;
    struct adef *ap;
    QDGlobals quickbytes;
    INTEGER offsetx, offsety;
    Rect main_gd_rect;

    LONGINT tmpa5;

    main_gd_rect = PIXMAP_BOUNDS(GD_PMAP(LM(MainDevice)));

    if(!LM(DSAlertTab))
    {
#if defined(CLIFF_CENTERING_ALGORITHM)
        LM(DSAlertTab) = (Ptr)&myalerttab;
        LM(DSAlertRect).top = 64;
        LM(DSAlertRect).left = 32;
        LM(DSAlertRect).bottom = 190;
        LM(DSAlertRect).right = 480;
#else
        INTEGER screen_width = main_gd_rect.right;
        INTEGER screen_height = main_gd_rect.bottom;

        LM(DSAlertTab) = (Ptr)&myalerttab;
        LM(DSAlertRect).top = (screen_height - 126) / 3;
        LM(DSAlertRect).left = (screen_width - 448) / 2;
        LM(DSAlertRect).bottom = LM(DSAlertRect).top + 126;
        LM(DSAlertRect).right = LM(DSAlertRect).left + 448;
#endif

        offsetx = LM(DSAlertRect).left - 32;
        offsety = LM(DSAlertRect).top - 64;
    }
    else
    {
        offsetx = offsety = 0;
    }

    /* IM-362 */
    /* 1. Save registers and Stack Pointer */
    /*	  NOT DONE YET... signal handlers sort of do that anyway */

    /* 2. Store errorcode in LM(DSErrCode) */
    LM(DSErrCode) = errorcode;

    /* 3. If no LM(DSAlertTab), bitch */
    if(!LM(DSAlertTab))
    {
        write(2, "This machine thinks its a sadmac\n",
              sizeof("This machine thinks its a sadmac\n") - 1);
        exit(255);
    }

/* 4. Allocate and re-initialize QuickDraw */
    EM_A5 = US_TO_SYN68K(&tmpa5);
    LM(CurrentA5) = guest_cast<Ptr>(EM_A5);
    InitGraf(&quickbytes.thePort);
    ROMlib_initport(&alertport);
    SetPort(&alertport);
    InitCursor();
    rp = &viscliprgn;
    alertport.visRgn = alertport.clipRgn = &rp;
    viscliprgn.rgnSize = 10;
    viscliprgn.rgnBBox = main_gd_rect;

    /* 5, 6. Draw alert box if the errorcode is >= 0 */

    if(errorcode < 0)
        errorcode = -errorcode;
    else
    {
        r = LM(DSAlertRect);
        FillRect(&r, &qdGlobals().white);
#if defined(OLDSTYLEALERT)
        r.right = r.right - (2);
        r.bottom = r.bottom - (2);
        FrameRect(&r);
        PenSize(2, 2);
        MoveTo(r.left + 2, r.bottom);
        LineTo(r.right, r.bottom);
        LineTo(r.right, r.top + 2);
        PenSize(1, 1);
#else /* OLDSTYLEALERT */
        FrameRect(&r);
        InsetRect(&r, 3, 3);
        PenSize(2, 2);
        FrameRect(&r);
        PenSize(1, 1);
#endif /* OLDSTYLEALERT */
    }

    /* find appropriate entry */

    ap = (struct adef *)findid(errorcode);
    if(!ap)
        ap = (struct adef *)((INTEGER *)LM(DSAlertTab) + 1);

    /* 7. text strings */
    drawtextstring(ap->primetextid, offsetx, offsety);
    drawtextstring(ap->secondtextid, offsetx, offsety);

    /* 8. icon */
    drawicon(ap->iconid, offsetx, offsety);

    /* 9. TODO: figure out what to do with the proc ... */

    /* 10, 11, 12, 13. check for non-zero button id */
    /* #warning We blow off LM(ResumeProc) until we can properly handle it */
    if(ap->buttonid)
        dobuttons(/* LM(ResumeProc) ? ap->buttonid + 1 : */ ap->buttonid,
                  offsetx, offsety);
}
<commit_msg>fputs is good enough for an error message, no need to use write()<commit_after>/* Copyright 1988 - 1999 by Abacus Research and
 * Development, Inc.  All rights reserved.
 */

/* Forward declarations in SysErr.h (DO NOT DELETE THIS LINE) */

#include <base/common.h>
#include <QuickDraw.h>
#include <CQuickDraw.h>
#include <EventMgr.h>
#include <ToolboxEvent.h>
#include <DialogMgr.h>
#include <OSUtil.h>
#include <SegmentLdr.h>
#include <SysErr.h>
#include <MemoryMgr.h>
#include <BinaryDecimal.h>
#include <LowMem.h>

#include <quickdraw/cquick.h>
#include <quickdraw/quick.h>
#include <rsys/segment.h>
#include <commandline/flags.h>
#include <rsys/version.h>
#include <osevent/osevent.h>
#include <prefs/options.h>
#include <error/syserr.h>

using namespace Executor;

static myalerttab_t myalerttab = {
    8,

#define WELCOME_CODE 0x28
    WELCOME_CODE, /* 1. normally "Welcome to M*cintosh", now copyright stuff */
    10,
    50,
    150,
    31,
    0,
    151,

    50, /* 2. primary text */
    56,
    { 108, 105 },
    "\251 Abacus Research and Development, Inc.  1986-1999",

    31, /* 3. ARDI icon */
    136,
    { 99, 56, 131, 88 },
    { { 0xff, 0xff, 0xff, 0xff },
      { 0x88, 0x88, 0x88, 0x89 },
      { 0x9d, 0xdd, 0xdd, 0xdd },
      { 0x88, 0x88, 0x88, 0x89 },
      { 0x9d, 0xdd, 0xdd, 0xdd },
      { 0x88, 0x88, 0x88, 0x89 },
      { 0xff, 0xff, 0xff, 0xff },
      { 0x88, 0x88, 0x88, 0x89 },
      { 0x88, 0x88, 0x88, 0x89 },
      { 0x88, 0x80, 0x80, 0x89 },
      { 0x88, 0xbc, 0xbc, 0x89 },
      { 0x80, 0xa2, 0x92, 0x81 },
      { 0x88, 0xa2, 0x92, 0x9d },
      { 0x94, 0xa2, 0x92, 0x89 },
      { 0xa2, 0xbc, 0x92, 0x89 },
      { 0xa2, 0xa8, 0x92, 0x89 },
      { 0xa2, 0xa4, 0x92, 0x89 },
      { 0xbe, 0xa2, 0x92, 0x89 },
      { 0xa2, 0xa2, 0x92, 0x89 },
      { 0xa2, 0xa2, 0x92, 0x89 },
      { 0xa2, 0xa2, 0xbc, 0x9d },
      { 0x80, 0x80, 0x80, 0x81 },
      { 0x88, 0x88, 0x88, 0x89 },
      { 0x88, 0x88, 0x88, 0x89 },
      { 0xff, 0xff, 0xff, 0xff } },

    150, /* 4. secondary text */
    50,
    { 122, 125 },
    "Please click on \"Info\" for more information\0\0",

    151, /* 5. the buttons */
    26,
    2,
    153,
    { 150, 50, 170, 100 }, /* OK rect */
    0,
    155,
    { 150, 130, 170, 190 }, /* Abort rect */
    156,

    153, /* 6. OK button */
    4,
    "OK\0",

    155, /* 7. Info button */
    6,
    "Info\0",

    156, /* 8. Info "procedure" */
    4,
    nullptr, /* was mydolicense, which we no longer use */
};

char syserr_msg[256];

static GUEST<INTEGER> *findid(INTEGER);
static void drawtextstring(INTEGER id, INTEGER offsetx, INTEGER offsety);
static void drawicon(INTEGER id, INTEGER offsetx, INTEGER offsety);
static void dobuttons(INTEGER id, INTEGER offsetx, INTEGER offsety);

static GUEST<INTEGER> *findid(INTEGER id)
{
    int i;
    GUEST<INTEGER> *ip;

    for(i = *(GUEST<INTEGER> *)LM(DSAlertTab),
    ip = (GUEST<INTEGER> *)LM(DSAlertTab) + 1;
        i > 0 && *ip != id;
        --i, ip = (GUEST<INTEGER> *)((char *)ip + ip[1] + 2 * sizeof(INTEGER)))
        ;
    return i > 0 ? ip : nullptr;
}

static void drawtextstring(INTEGER id, INTEGER offsetx, INTEGER offsety)
{
    struct tdef *tp;

    if(id && (tp = (struct tdef *)findid(id)))
    {
        MoveTo(tp->loc.h + offsetx, tp->loc.v + offsety);
        DrawText_c_string(tp->text);
    }
}

static void drawicon(INTEGER id, INTEGER offsetx, INTEGER offsety)
{
    struct idef *ip;
    BitMap bm;
    Rect old_loc;

    ip = (struct idef *)findid(id);
    if(id && ip)
    {
        bm.baseAddr = (Ptr)ip->ike;
        bm.rowBytes = 4;
        bm.bounds.left = bm.bounds.top = 0;
        bm.bounds.right = bm.bounds.bottom = 32;
        old_loc = ip->loc;
        C_OffsetRect(&ip->loc, offsetx, offsety);
        CopyBits(&bm, PORT_BITS_FOR_COPY(qdGlobals().thePort),
                 &bm.bounds, &ip->loc, srcCopy, nullptr);
        ip->loc = old_loc;
    }
}

static void dobuttons(INTEGER id, INTEGER offsetx, INTEGER offsety)
{
    struct bdef *bp;
    struct sdef *sp;
    struct pdef *pp;
    int i;
    EventRecord evt;
    int done;
    int tcnt, twid;
    Point p;
#define BILLBUTTONS /*  */
#if defined(BILLBUTTONS)
    INTEGER h, v;
#endif /* BILLBUTTONS */
    char *textp;

    if((bp = (struct bdef *)findid(id)))
    {
        for(i = 0; i < bp->nbut; i++)
        {

            /* Offset buttons; this hack is to center the splash screen
	     * on non-512x342 root windows...yuck!
	     */

            C_OffsetRect(&bp->buts[i].butloc, offsetx, offsety);
            if((sp = (struct sdef *)findid(bp->buts[i].butstrid)))
            {
                textp = sp->text;
                tcnt = strlen(textp);
                twid = TextWidth((Ptr)textp, 0, tcnt);
                MoveTo((bp->buts[i].butloc.left + bp->buts[i].butloc.right - twid) / 2,
                       (bp->buts[i].butloc.top + bp->buts[i].butloc.bottom) / 2 + 4);
                DrawText((Ptr)textp, 0, tcnt);
            }
#if defined(BILLBUTTONS)
            h = bp->buts[i].butloc.right - bp->buts[i].butloc.left;
            v = (bp->buts[i].butloc.bottom - bp->buts[i].butloc.top) / 2;
            if(h > v)
                h = v;
            if(!(ROMlib_options & ROMLIB_RECT_SCREEN_BIT))
                FrameRoundRect(&bp->buts[i].butloc, h, v);
            else
                FrameRect(&bp->buts[i].butloc);
#else /* BILLBUTTONS */
            if(!(ROMlib_options & ROMLIB_RECT_SCREEN_BIT))
                FrameRoundRect(&bp->buts[i].butloc, 10, 10);
            else
                FrameRect(&bp->buts[i].butloc);
#endif /* BILLBUTTONS */
        }

        for(done = 0; !done;)
        {
            C_GetNextEvent(mDownMask | keyDownMask, &evt);
            if(evt.what == mouseDown || evt.what == keyDown)
            {
                p.h = evt.where.h;
                p.v = evt.where.v;
                for(i = 0; !done && i < bp->nbut; i++)
                {
                    if(PtInRect(p, &bp->buts[i].butloc) || ((evt.what == keyDown) && (((evt.message & charCodeMask) == '\r') || ((evt.message & charCodeMask) == NUMPAD_ENTER))))
                    {
                        if((pp = (struct pdef *)
                                findid(bp->buts[i].butprocid)))
                            /* NOTE:  we will have to do a better
				      job here sometime */
                            (*(void (*)(void))pp->proc)();
                        done = 1;
                    }
                }
                if(!done)
                    SysBeep(1);
            }
        }
        if(evt.what == mouseDown)
            while(!C_GetNextEvent(mUpMask, &evt))
                ;

        /* Move all buttons back. */
        for(i = 0; i < bp->nbut; i++)
            C_OffsetRect(&bp->buts[i].butloc, -offsetx, -offsety);
    }
}

/*
 * NOTE: The version of SysError below will only handle natively compiled
 *	 code.  When we want to be able to run arbitrary code we'll need
 *	 to call syn68k appropriately.
 */

void Executor::C_SysError(short errorcode)
{
    GrafPort alertport;
    Region viscliprgn;
    GUEST<RgnPtr> rp;
    Rect r;
    struct adef *ap;
    QDGlobals quickbytes;
    INTEGER offsetx, offsety;
    Rect main_gd_rect;

    LONGINT tmpa5;

    main_gd_rect = PIXMAP_BOUNDS(GD_PMAP(LM(MainDevice)));

    if(!LM(DSAlertTab))
    {
#if defined(CLIFF_CENTERING_ALGORITHM)
        LM(DSAlertTab) = (Ptr)&myalerttab;
        LM(DSAlertRect).top = 64;
        LM(DSAlertRect).left = 32;
        LM(DSAlertRect).bottom = 190;
        LM(DSAlertRect).right = 480;
#else
        INTEGER screen_width = main_gd_rect.right;
        INTEGER screen_height = main_gd_rect.bottom;

        LM(DSAlertTab) = (Ptr)&myalerttab;
        LM(DSAlertRect).top = (screen_height - 126) / 3;
        LM(DSAlertRect).left = (screen_width - 448) / 2;
        LM(DSAlertRect).bottom = LM(DSAlertRect).top + 126;
        LM(DSAlertRect).right = LM(DSAlertRect).left + 448;
#endif

        offsetx = LM(DSAlertRect).left - 32;
        offsety = LM(DSAlertRect).top - 64;
    }
    else
    {
        offsetx = offsety = 0;
    }

    /* IM-362 */
    /* 1. Save registers and Stack Pointer */
    /*	  NOT DONE YET... signal handlers sort of do that anyway */

    /* 2. Store errorcode in LM(DSErrCode) */
    LM(DSErrCode) = errorcode;

    /* 3. If no LM(DSAlertTab), bitch */
    if(!LM(DSAlertTab))
    {
        fputs("This machine thinks its a sadmac\n", stderr);
        exit(255);
    }

/* 4. Allocate and re-initialize QuickDraw */
    EM_A5 = US_TO_SYN68K(&tmpa5);
    LM(CurrentA5) = guest_cast<Ptr>(EM_A5);
    InitGraf(&quickbytes.thePort);
    ROMlib_initport(&alertport);
    SetPort(&alertport);
    InitCursor();
    rp = &viscliprgn;
    alertport.visRgn = alertport.clipRgn = &rp;
    viscliprgn.rgnSize = 10;
    viscliprgn.rgnBBox = main_gd_rect;

    /* 5, 6. Draw alert box if the errorcode is >= 0 */

    if(errorcode < 0)
        errorcode = -errorcode;
    else
    {
        r = LM(DSAlertRect);
        FillRect(&r, &qdGlobals().white);
#if defined(OLDSTYLEALERT)
        r.right = r.right - (2);
        r.bottom = r.bottom - (2);
        FrameRect(&r);
        PenSize(2, 2);
        MoveTo(r.left + 2, r.bottom);
        LineTo(r.right, r.bottom);
        LineTo(r.right, r.top + 2);
        PenSize(1, 1);
#else /* OLDSTYLEALERT */
        FrameRect(&r);
        InsetRect(&r, 3, 3);
        PenSize(2, 2);
        FrameRect(&r);
        PenSize(1, 1);
#endif /* OLDSTYLEALERT */
    }

    /* find appropriate entry */

    ap = (struct adef *)findid(errorcode);
    if(!ap)
        ap = (struct adef *)((INTEGER *)LM(DSAlertTab) + 1);

    /* 7. text strings */
    drawtextstring(ap->primetextid, offsetx, offsety);
    drawtextstring(ap->secondtextid, offsetx, offsety);

    /* 8. icon */
    drawicon(ap->iconid, offsetx, offsety);

    /* 9. TODO: figure out what to do with the proc ... */

    /* 10, 11, 12, 13. check for non-zero button id */
    /* #warning We blow off LM(ResumeProc) until we can properly handle it */
    if(ap->buttonid)
        dobuttons(/* LM(ResumeProc) ? ap->buttonid + 1 : */ ap->buttonid,
                  offsetx, offsety);
}
<|endoftext|>


<commit_before>/*
 *  code.cpp
 *
 *  Created on: Oct 30, 2015
 *      Author: Naman, Srishti
 *
 * Play with parameters
 * preprocess - BG Subt -> threshold [OTSU] -> morph -> contour = shows circles in contours
 * Face detect -> remove with flood fill -> skin -> contour
 * Hand Detection with haar -> bounding box -> contouring within box = shows circles in contours
 */

#include <_mingw.h>
#include <core/cvdef.h>
#include <core/cvstd.hpp>
#include <core/mat.hpp>
#include <core/mat.inl.hpp>
#include <core/matx.hpp>
#include <core/ptr.inl.hpp>
#include <core/types.hpp>
#include <core.hpp>
#include <highgui.hpp>
#include <imgproc/types_c.h>
#include <imgproc.hpp>
#include <objdetect.hpp>
#include <video/background_segm.hpp>
#include <videoio.hpp>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

using namespace cv;
using namespace std;

Mat frame;                                      //current frame
Mat fgMaskMOG2;                       //fg mask fg mask generated by MOG2 method
Mat back;                                       //stores the background frame
Ptr<BackgroundSubtractorMOG2> pMOG2;            //MOG2 Background subtractor
vector<pair<Point, double>> palm_centers;       //store last 10 palm centers
Mat draw;                                       //Mat for drawing

String face_cascade_name =
    "../../../data/haarcascades/haarcascade_frontalface_alt.xml";
//String face_cascade_name = "../../../data/haarcascades/aGest.xml";
CascadeClassifier face_cascade;

//This function returns the square of the euclidean distance between 2 points.
double dist(Point x, Point y) {
  return (x.x - y.x) * (x.x - y.x) + (x.y - y.y) * (x.y - y.y);
}

Mat pre_processing(Mat frame) {

  GaussianBlur(frame, frame, Size(7, 7), 10, 10);
  Mat gray_scale;
  cvtColor(frame, gray_scale, COLOR_BGR2GRAY, 1);

  Mat element = (Mat_<uchar>(3, 3) << 0, 1, 0, 1, 1, 1, 0, 1, 0);
  morphologyEx(gray_scale, gray_scale, MORPH_OPEN, element);

  return gray_scale;
}

void bg_subtraction(VideoCapture cap, Mat frame) {

  //update the background model
  pMOG2->apply(frame, fgMaskMOG2);

  //Get background image to display it
  pMOG2->getBackgroundImage(back);
  pMOG2->setDetectShadows(0);
  pMOG2->setNMixtures(3);
}

//This function returns the radius and the center of the circle given 3 points
//If a circle cannot be formed , it returns a zero radius circle centered at (0,0)
pair<Point, double> circleFromPoints(Point p1, Point p2, Point p3) {
  double offset = pow(p2.x, 2) + pow(p2.y, 2);
  double bc = (pow(p1.x, 2) + pow(p1.y, 2) - offset) / 2.0;
  double cd = (offset - pow(p3.x, 2) - pow(p3.y, 2)) / 2.0;
  double det = (p1.x - p2.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p2.y);
  double TOL = 0.0000001;

  if (abs(det) < TOL) {
    cout << "POINTS TOO CLOSE" << endl;
    return make_pair(Point(0, 0), 0);
  }

  double idet = 1 / det;
  double centerx = (bc * (p2.y - p3.y) - cd * (p1.y - p2.y)) * idet;
  double centery = (cd * (p1.x - p2.x) - bc * (p2.x - p3.x)) * idet;
  double radius = sqrt(pow(p2.x - centerx, 2) + pow(p2.y - centery, 2));

  return make_pair(Point(centerx, centery), radius);
}

Mat contouring(Mat binarized, Mat pre_processed) {
  vector<vector<Point>> contours;
  findContours(binarized, contours, CV_RETR_EXTERNAL,
      CV_CHAIN_APPROX_TC89_KCOS);

  for (int i = 0; i < contours.size(); i++)

    //Ignore all small insignificant areas
    if (contourArea(contours[i]) >= 5000) {

      //Draw contour
      vector<vector<Point>> tcontours;
      tcontours.push_back(contours[i]);
      drawContours(pre_processed, tcontours, -1, Scalar(0, 0, 255), 2);

      //Detect Hull in current contour
      vector<vector<Point> > hulls(1);
      vector<vector<int> > hullsI(1);
      convexHull(Mat(tcontours[0]), hulls[0], false);
      convexHull(Mat(tcontours[0]), hullsI[0], false);
      drawContours(pre_processed, hulls, -1, Scalar(0, 255, 0), 2);

      //Find minimum area rectangle to enclose hand
      RotatedRect rect = minAreaRect(Mat(tcontours[0]));

      //Find Convex Defects
      vector<Vec4i> defects;
      if (hullsI[0].size() > 0) {
        Point2f rect_points[4];
        rect.points(rect_points);
        for (int j = 0; j < 4; j++)
          line(pre_processed, rect_points[j], rect_points[(j + 1) % 4],
              Scalar(255, 0, 0), 1, 8);
        Point rough_palm_center;
        convexityDefects(tcontours[0], hullsI[0], defects);
        if (defects.size() >= 3) {
          vector<Point> palm_points;
          for (int j = 0; j < defects.size(); j++) {
            int startidx = defects[j][0];
            Point ptStart(tcontours[0][startidx]);
            int endidx = defects[j][1];
            Point ptEnd(tcontours[0][endidx]);
            int faridx = defects[j][2];
            Point ptFar(tcontours[0][faridx]);

            //Sum up all the hull and defect points to compute average
            rough_palm_center += ptFar + ptStart + ptEnd;
            palm_points.push_back(ptFar);
            palm_points.push_back(ptStart);
            palm_points.push_back(ptEnd);
          }

          //Get palm center by 1st getting the average of all defect points, this is the rough palm center,
          //Then chose the closest 3 points ang get the circle radius and center formed from them which is the palm center.
          rough_palm_center.x /= defects.size() * 3;
          rough_palm_center.y /= defects.size() * 3;
          Point closest_pt = palm_points[0];
          vector<pair<double, int> > distvec;
          for (int i = 0; i < palm_points.size(); i++)
            distvec.push_back(
                make_pair(dist(rough_palm_center, palm_points[i]), i));
          sort(distvec.begin(), distvec.end());

          //Keep choosing 3 points till you find a circle with a valid radius
          //As there is a high chance that the closes points might be in a linear line or too close that it forms a very large circle
          pair<Point, double> soln_circle;
          for (int i = 0; i + 2 < distvec.size(); i++) {
            Point p1 = palm_points[distvec[i + 0].second];
            Point p2 = palm_points[distvec[i + 1].second];
            Point p3 = palm_points[distvec[i + 2].second];
            soln_circle = circleFromPoints(p1, p2, p3); //Final palm center,radius
            if (soln_circle.second != 0)
              break;
          }

          //Find avg palm centers for the last few frames to stabilize its centers, also find the avg radius
          palm_centers.push_back(soln_circle);
          if (palm_centers.size() > 10)
            palm_centers.erase(palm_centers.begin());

          Point palm_center;
          double radius = 0;

          //averaging all palm centres
          for (int i = 0; i < palm_centers.size(); i++) {
            palm_center += palm_centers[i].first;
            radius += palm_centers[i].second;
          }
          palm_center.x /= palm_centers.size();
          palm_center.y /= palm_centers.size();
          radius /= palm_centers.size();

          //Draw the palm center and the palm circle
          //The size of the palm gives the depth of the hand
          circle(pre_processed, palm_center, 5, Scalar(144, 144, 255), 3);
          circle(pre_processed, palm_center, radius, Scalar(144, 144, 255), 2);

          //Detect fingers by finding points that form an almost isosceles triangle with certain thesholds
          int no_of_fingers = 0;
          for (int j = 0; j < defects.size(); j++) {
            int startidx = defects[j][0];
            Point ptStart(tcontours[0][startidx]);
            int endidx = defects[j][1];
            Point ptEnd(tcontours[0][endidx]);
            int faridx = defects[j][2];
            Point ptFar(tcontours[0][faridx]);

            //X o--------------------------o Y

            double Xdist = sqrt(dist(palm_center, ptFar));
            double Ydist = sqrt(dist(palm_center, ptStart));
            double length = sqrt(dist(ptFar, ptStart));
            double retLength = sqrt(dist(ptEnd, ptFar));

            //Play with these thresholds to improve performance
            if (length <= 3 * radius && Ydist >= 0.4 * radius && length >= 10
                && retLength >= 10
                && max(length, retLength) / min(length, retLength) >= 0.8) {
              if (min(Xdist, Ydist) / max(Xdist, Ydist) <= 0.8) {
                if ((Xdist >= 0.1 * radius && Xdist <= 1.3 * radius
                    && Xdist < Ydist)
                    || (Ydist >= 0.1 * radius && Ydist <= 1.3 * radius
                        && Xdist > Ydist)) {
                  line(pre_processed, ptEnd, ptFar, Scalar(0, 255, 0), 1);
                  no_of_fingers++;
                }
              }
            }
          }

          no_of_fingers = min(5, no_of_fingers);
          cout << "NO OF FINGERS: " << no_of_fingers << endl;

          putText(pre_processed, "NO OF FINGERS: " + to_string(no_of_fingers),
              Point(30, 30), FONT_HERSHEY_COMPLEX_SMALL, 0.8,
              Scalar(200, 200, 250), 1, LINE_AA);

          if (no_of_fingers == 1) {
            //draw on draw matrix
            circle(draw, palm_center, 2, Scalar(144, 144, 255), 2);
            imshow("draw", draw);
          }
        }
      }
    }
  return pre_processed;
}

void facedetect(Mat frame) {
  vector<Rect> faces;
  Mat frame_gray;

  if (frame.channels() > 1)
    cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
  else
    frame_gray = frame;

  equalizeHist(frame_gray, frame_gray);

  //Detect faces
  face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2,
      0 | CASCADE_SCALE_IMAGE, Size(30, 30));

  for (size_t i = 0; i < faces.size(); i++) {
    Point center(faces[i].x + faces[i].width / 2,
        faces[i].y + faces[i].height / 2);
    ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0,
        360, Scalar(0, 0, 0), 200, 8, 0);

    Mat faceROI = frame_gray(faces[i]);
  }
}

Mat skin_detect(Mat frame) {

  //blur the image to make segmentation simpler
  blur(frame, frame, Size(10, 10));

  //convert the image from bgr to hsv mode
  Mat hsv;
  cvtColor(frame, hsv, CV_BGR2HSV);

  Mat detected;

  //lower bound - Scalar(0, 10, 60)  and upper bound - Scalar(20, 150, 255) for classifying skin
  //ranged is set to 255 (skin) if hsv is within the specified range and 0 otherwise.
  inRange(hsv, Scalar(0, 10, 60), Scalar(20, 150, 255), detected);

  return detected;
}

int process_video() {

  VideoCapture cap(0); // open the default camera
  if (!cap.isOpened())  // check if we succeeded
    return -1;

  //draw on blackboard
  Size s = Size(640, 480);
  draw = Mat::zeros(s, CV_8UC3);

  for (;;) {
    cap >> frame; // get a new frame from camera

    Mat orig = frame.clone();

    Mat foreground;
    Mat pre_processed = pre_processing(frame); //preprocess and convert to grayscale

    //returns the bg subtracted and stores
    bg_subtraction(cap, pre_processed);

    absdiff(pre_processed, back, foreground);

    Mat fg_binarized_mask;
    threshold(foreground, fg_binarized_mask, 0, 255,
        THRESH_BINARY | THRESH_OTSU);

    GaussianBlur(fg_binarized_mask, fg_binarized_mask, Size(7, 7), 10, 10);

    //morphology to remove noise
    Mat element = (Mat_<uchar>(3, 3) << 0, 1, 0, 1, 1, 1, 0, 1, 0);
    morphologyEx(fg_binarized_mask, fg_binarized_mask, MORPH_OPEN, element);

    imshow("mask", fg_binarized_mask);

    //finally contour
    Mat contour = contouring(fg_binarized_mask, orig);

    imshow("Frame", contour);
    if (waitKey(30) >= 0)
      break;
  }
  return 0;
}

int main(int, char**) {

  //create Background Subtractor objects
  pMOG2 = createBackgroundSubtractorMOG2(); //MOG2 approach
  /*
   //-- 1. Load the cascades
   if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading face cascade\n"); return -1; };
   */

  int res = process_video();
  return 0;
}
<commit_msg>multiply with mask<commit_after>/*
 *  code.cpp
 *
 *  Created on: Oct 30, 2015
 *      Author: Naman, Srishti
 *
 * Play with parameters
 * preprocess - BG Subt -> threshold [OTSU] -> morph -> contour = shows circles in contours
 * Face detect -> remove with flood fill -> skin -> contour
 * Hand Detection with haar -> bounding box -> contouring within box = shows circles in contours
 */

#include <_mingw.h>
#include <core/cvdef.h>
#include <core/cvstd.hpp>
#include <core/mat.hpp>
#include <core/mat.inl.hpp>
#include <core/matx.hpp>
#include <core/ptr.inl.hpp>
#include <core/types.hpp>
#include <core.hpp>
#include <highgui.hpp>
#include <imgproc/types_c.h>
#include <imgproc.hpp>
#include <objdetect.hpp>
#include <video/background_segm.hpp>
#include <videoio.hpp>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

using namespace cv;
using namespace std;

Mat frame;                                      //current frame
Mat fgMaskMOG2;                       //fg mask fg mask generated by MOG2 method
Mat back;                                       //stores the background frame
Ptr<BackgroundSubtractorMOG2> pMOG2;            //MOG2 Background subtractor
vector<pair<Point, double>> palm_centers;       //store last 10 palm centers
Mat draw;                                       //Mat for drawing

String face_cascade_name =
    "../../../data/haarcascades/haarcascade_frontalface_alt.xml";
//String face_cascade_name = "../../../data/haarcascades/aGest.xml";
CascadeClassifier face_cascade;

//This function returns the square of the euclidean distance between 2 points.
double dist(Point x, Point y) {
  return (x.x - y.x) * (x.x - y.x) + (x.y - y.y) * (x.y - y.y);
}

Mat pre_processing(Mat frame) {

  GaussianBlur(frame, frame, Size(7, 7), 10, 10);
  Mat gray_scale;
  cvtColor(frame, gray_scale, COLOR_BGR2GRAY, 1);

  Mat element = (Mat_<uchar>(3, 3) << 0, 1, 0, 1, 1, 1, 0, 1, 0);
  morphologyEx(gray_scale, gray_scale, MORPH_OPEN, element);

  return gray_scale;
}

void bg_subtraction(VideoCapture cap, Mat frame) {

  //update the background model
  pMOG2->apply(frame, fgMaskMOG2);

  //Get background image to display it
  pMOG2->getBackgroundImage(back);
  pMOG2->setDetectShadows(0);
  pMOG2->setNMixtures(3);
}

//This function returns the radius and the center of the circle given 3 points
//If a circle cannot be formed , it returns a zero radius circle centered at (0,0)
pair<Point, double> circleFromPoints(Point p1, Point p2, Point p3) {
  double offset = pow(p2.x, 2) + pow(p2.y, 2);
  double bc = (pow(p1.x, 2) + pow(p1.y, 2) - offset) / 2.0;
  double cd = (offset - pow(p3.x, 2) - pow(p3.y, 2)) / 2.0;
  double det = (p1.x - p2.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p2.y);
  double TOL = 0.0000001;

  if (abs(det) < TOL) {
    cout << "POINTS TOO CLOSE" << endl;
    return make_pair(Point(0, 0), 0);
  }

  double idet = 1 / det;
  double centerx = (bc * (p2.y - p3.y) - cd * (p1.y - p2.y)) * idet;
  double centery = (cd * (p1.x - p2.x) - bc * (p2.x - p3.x)) * idet;
  double radius = sqrt(pow(p2.x - centerx, 2) + pow(p2.y - centery, 2));

  return make_pair(Point(centerx, centery), radius);
}

Mat contouring(Mat binarized, Mat pre_processed) {
  vector<vector<Point>> contours;
  findContours(binarized, contours, CV_RETR_EXTERNAL,
      CV_CHAIN_APPROX_TC89_KCOS);

  for (int i = 0; i < contours.size(); i++)

    //Ignore all small insignificant areas
    if (contourArea(contours[i]) >= 5000) {

      //Draw contour
      vector<vector<Point>> tcontours;
      tcontours.push_back(contours[i]);
      drawContours(pre_processed, tcontours, -1, Scalar(0, 0, 255), 2);

      //Detect Hull in current contour
      vector<vector<Point> > hulls(1);
      vector<vector<int> > hullsI(1);
      convexHull(Mat(tcontours[0]), hulls[0], false);
      convexHull(Mat(tcontours[0]), hullsI[0], false);
      drawContours(pre_processed, hulls, -1, Scalar(0, 255, 0), 2);

      //Find minimum area rectangle to enclose hand
      RotatedRect rect = minAreaRect(Mat(tcontours[0]));

      //Find Convex Defects
      vector<Vec4i> defects;
      if (hullsI[0].size() > 0) {
        Point2f rect_points[4];
        rect.points(rect_points);
        for (int j = 0; j < 4; j++)
          line(pre_processed, rect_points[j], rect_points[(j + 1) % 4],
              Scalar(255, 0, 0), 1, 8);
        Point rough_palm_center;
        convexityDefects(tcontours[0], hullsI[0], defects);
        if (defects.size() >= 3) {
          vector<Point> palm_points;
          for (int j = 0; j < defects.size(); j++) {
            int startidx = defects[j][0];
            Point ptStart(tcontours[0][startidx]);
            int endidx = defects[j][1];
            Point ptEnd(tcontours[0][endidx]);
            int faridx = defects[j][2];
            Point ptFar(tcontours[0][faridx]);

            //Sum up all the hull and defect points to compute average
            rough_palm_center += ptFar + ptStart + ptEnd;
            palm_points.push_back(ptFar);
            palm_points.push_back(ptStart);
            palm_points.push_back(ptEnd);
          }

          //Get palm center by 1st getting the average of all defect points, this is the rough palm center,
          //Then chose the closest 3 points ang get the circle radius and center formed from them which is the palm center.
          rough_palm_center.x /= defects.size() * 3;
          rough_palm_center.y /= defects.size() * 3;
          Point closest_pt = palm_points[0];
          vector<pair<double, int> > distvec;
          for (int i = 0; i < palm_points.size(); i++)
            distvec.push_back(
                make_pair(dist(rough_palm_center, palm_points[i]), i));
          sort(distvec.begin(), distvec.end());

          //Keep choosing 3 points till you find a circle with a valid radius
          //As there is a high chance that the closes points might be in a linear line or too close that it forms a very large circle
          pair<Point, double> soln_circle;
          for (int i = 0; i + 2 < distvec.size(); i++) {
            Point p1 = palm_points[distvec[i + 0].second];
            Point p2 = palm_points[distvec[i + 1].second];
            Point p3 = palm_points[distvec[i + 2].second];
            soln_circle = circleFromPoints(p1, p2, p3); //Final palm center,radius
            if (soln_circle.second != 0)
              break;
          }

          //Find avg palm centers for the last few frames to stabilize its centers, also find the avg radius
          palm_centers.push_back(soln_circle);
          if (palm_centers.size() > 10)
            palm_centers.erase(palm_centers.begin());

          Point palm_center;
          double radius = 0;

          //averaging all palm centres
          for (int i = 0; i < palm_centers.size(); i++) {
            palm_center += palm_centers[i].first;
            radius += palm_centers[i].second;
          }
          palm_center.x /= palm_centers.size();
          palm_center.y /= palm_centers.size();
          radius /= palm_centers.size();

          //Draw the palm center and the palm circle
          //The size of the palm gives the depth of the hand
          circle(pre_processed, palm_center, 5, Scalar(144, 144, 255), 3);
          circle(pre_processed, palm_center, radius, Scalar(144, 144, 255), 2);

          //Detect fingers by finding points that form an almost isosceles triangle with certain thesholds
          int no_of_fingers = 0;
          for (int j = 0; j < defects.size(); j++) {
            int startidx = defects[j][0];
            Point ptStart(tcontours[0][startidx]);
            int endidx = defects[j][1];
            Point ptEnd(tcontours[0][endidx]);
            int faridx = defects[j][2];
            Point ptFar(tcontours[0][faridx]);

            //X o--------------------------o Y

            double Xdist = sqrt(dist(palm_center, ptFar));
            double Ydist = sqrt(dist(palm_center, ptStart));
            double length = sqrt(dist(ptFar, ptStart));
            double retLength = sqrt(dist(ptEnd, ptFar));

            //Play with these thresholds to improve performance
            if (length <= 3 * radius && Ydist >= 0.4 * radius && length >= 10
                && retLength >= 10
                && max(length, retLength) / min(length, retLength) >= 0.8) {
              if (min(Xdist, Ydist) / max(Xdist, Ydist) <= 0.8) {
                if ((Xdist >= 0.1 * radius && Xdist <= 1.3 * radius
                    && Xdist < Ydist)
                    || (Ydist >= 0.1 * radius && Ydist <= 1.3 * radius
                        && Xdist > Ydist)) {
                  line(pre_processed, ptEnd, ptFar, Scalar(0, 255, 0), 1);
                  no_of_fingers++;
                }
              }
            }
          }

          no_of_fingers = min(5, no_of_fingers);
          cout << "NO OF FINGERS: " << no_of_fingers << endl;

          putText(pre_processed, "NO OF FINGERS: " + to_string(no_of_fingers),
              Point(30, 30), FONT_HERSHEY_COMPLEX_SMALL, 0.8,
              Scalar(200, 200, 250), 1, LINE_AA);

          if (no_of_fingers == 1) {
            //draw on draw matrix
            circle(draw, palm_center, 2, Scalar(144, 144, 255), 2);
            imshow("draw", draw);
          }
        }
      }
    }
  return pre_processed;
}

void facedetect(Mat frame) {
  vector<Rect> faces;
  Mat frame_gray;

  if (frame.channels() > 1)
    cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
  else
    frame_gray = frame;

  equalizeHist(frame_gray, frame_gray);

  //Detect faces
  face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2,
      0 | CASCADE_SCALE_IMAGE, Size(30, 30));

  for (size_t i = 0; i < faces.size(); i++) {
    Point center(faces[i].x + faces[i].width / 2,
        faces[i].y + faces[i].height / 2);
    ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0,
        360, Scalar(0, 0, 0), 200, 8, 0);

    Mat faceROI = frame_gray(faces[i]);
  }
}

Mat skin_detect(Mat frame) {

  //blur the image to make segmentation simpler
  blur(frame, frame, Size(10, 10));

  //convert the image from bgr to hsv mode
  Mat hsv;
  cvtColor(frame, hsv, CV_BGR2HSV);

  Mat detected;

  //lower bound - Scalar(0, 10, 60)  and upper bound - Scalar(20, 150, 255) for classifying skin
  //ranged is set to 255 (skin) if hsv is within the specified range and 0 otherwise.
  inRange(hsv, Scalar(0, 10, 60), Scalar(20, 150, 255), detected);

  return detected;
}

int process_video() {

  VideoCapture cap(0); // open the default camera
  if (!cap.isOpened())  // check if we succeeded
    return -1;

  //draw on blackboard
  Size s = Size(640, 480);
  draw = Mat::zeros(s, CV_8UC3);

  for (;;) {
    cap >> frame; // get a new frame from camera
    Mat orig = frame.clone();

    Mat foreground;
    Mat pre_processed = pre_processing(frame); //preprocess and convert to grayscale

    //returns the bg subtracted and stores
    bg_subtraction(cap, pre_processed);

    absdiff(pre_processed, back, foreground);

    Mat fg_binarized_mask;
    threshold(foreground, fg_binarized_mask, 0, 255,
        THRESH_BINARY | THRESH_OTSU);

    GaussianBlur(fg_binarized_mask, fg_binarized_mask, Size(7, 7), 10, 10);

    //morphology to remove noise
    Mat element = (Mat_<uchar>(3, 3) << 0, 1, 0, 1, 1, 1, 0, 1, 0);
    morphologyEx(fg_binarized_mask, fg_binarized_mask, MORPH_OPEN, element);

    imshow("mask", fg_binarized_mask);

    Mat bg_removed;
    orig.copyTo(bg_removed,fg_binarized_mask);
    imshow("BG Removed", bg_removed);

    //finally contour
    Mat contour = contouring(fg_binarized_mask, bg_removed);

    imshow("Frame", contour);
    if (waitKey(30) >= 0)
      break;
  }
  return 0;
}

int main(int, char**) {

  //create Background Subtractor objects
  pMOG2 = createBackgroundSubtractorMOG2(); //MOG2 approach
  /*
   //-- 1. Load the cascades
   if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading face cascade\n"); return -1; };
   */

  int res = process_video();
  return 0;
}
<|endoftext|>


<commit_before><commit_msg>Delete ApeSphereGeometryImpl.cpp<commit_after><|endoftext|>


<commit_before>#include "ImageShapeSegmentation.hpp"

#include <opencv2/opencv.hpp>
#include <iostream>

int main(int argc, char** argv)
{
	ImageShapeSegmentation iss_(1, "../../../resources/Video_2/output-%04d.jpg");

	cv::Mat frame_;
	cv::Size size_(640, 480);
	iss_.process(frame_);

	while (iss_.process(frame_))
	{
		std::cout << "Processing frame...\n";
	    cv::Mat color_resized_;
	    resize(frame_, color_resized_, size_);
	    cv::namedWindow("ShapeSegmentation", cv::WINDOW_NORMAL);
	    cv::imshow("ShapeSegmentation", color_resized_);
			cv::waitKey(0);
	}

  cv::waitKey(0);

	return 0;
}
<commit_msg>add image processing to main<commit_after>#include "ImageShapeSegmentation.hpp"

#include <opencv2/opencv.hpp>
#include <iostream>

int main(int argc, char** argv)
{
	ImageShapeSegmentation iss_(1, "../../../resources/Video_2/output-%04d.jpg");
	//ImageShapeSegmentation iss_(0, "../../../resources/Picture_21.jpg");

	cv::Mat frame_;
	cv::Size size_(640, 480);
	iss_.process(frame_);

	while (iss_.process(frame_))
	{
		std::cout << "Processing frame...\n";
	    cv::Mat color_resized_;
	    resize(frame_, color_resized_, size_);
	    cv::namedWindow("ShapeSegmentation", cv::WINDOW_NORMAL);
	    cv::imshow("ShapeSegmentation", color_resized_);
			cv::waitKey(0);
	}

  cv::waitKey(0);

	return 0;
}
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////
// comp.hpp -- Compile Routines
// Date: Fri Nov 29 20:31:11 2013   (C) datablocks.net
///////////////////////////////////////////////////////////////////////

#ifndef COMP_HPP
#define COMP_HPP

#include <fstream>
#include <vector>

enum e_ntype {
	None = 0,
	Token,		// Lexical token (.ltoken)
	Ident,		// Identifier
	Constant,	// Constant
	StringLit,	// String literal
	Typedef,	// Typedef
	Type,		// Type name
	Struct,		// struct
	Union,		// union
	ArrayRef,	// [ ] ref
	List		// List
};

struct s_node {
	e_ntype		type;		// Node type
	int		symbol;		// Symbol ref
	int		ltoken;		// Lexical token or 0
	unsigned	ptr;		// Pointer levels

	std::vector<int> list;		// List

	int		next;		// Next node in chain
	int		next2;
	int		next3;

	s_node() {
		type = None;
		symbol = 0;
		ltoken = 0;
		next = next2 = next3 = 0;
		ptr = 0;
	}
};

extern std::string yytarget;
extern int yytarget_struct;

unsigned lex_lineno();
int lex_token();
void register_builtin(const std::string& type);
void register_type(int symid);
void lexer_reset();
const std::string& lex_revsym(int symid);

void parser_reset();
s_node& Get(int nno);

bool gcc_open(std::fstream& fs,int genset,const std::string& suffix=".c");
bool lex_open(int genset,const std::string& suffix);

bool gcc_compile(std::fstream& fs,int genset);
bool gcc_precompile(std::fstream& fs,int genset,const std::string& variation="");
bool gcc_precomplex(int genset,const std::string& variation="");

void parse(std::vector<std::string>& svec,const std::string s,const std::string delim="|");

extern int yyparse();

#endif // COMP_HPP

// End comp.hpp
<commit_msg>Added to_ada_name()<commit_after>//////////////////////////////////////////////////////////////////////
// comp.hpp -- Compile Routines
// Date: Fri Nov 29 20:31:11 2013   (C) datablocks.net
///////////////////////////////////////////////////////////////////////

#ifndef COMP_HPP
#define COMP_HPP

#include <fstream>
#include <vector>

enum e_ntype {
	None = 0,
	Token,		// Lexical token (.ltoken)
	Ident,		// Identifier
	Constant,	// Constant
	StringLit,	// String literal
	Typedef,	// Typedef
	Type,		// Type name
	Struct,		// struct
	Union,		// union
	ArrayRef,	// [ ] ref
	List		// List
};

struct s_node {
	e_ntype		type;		// Node type
	int		symbol;		// Symbol ref
	int		ltoken;		// Lexical token or 0
	unsigned	ptr;		// Pointer levels

	std::vector<int> list;		// List

	int		next;		// Next node in chain
	int		next2;
	int		next3;

	s_node() {
		type = None;
		symbol = 0;
		ltoken = 0;
		next = next2 = next3 = 0;
		ptr = 0;
	}
};

extern std::string yytarget;
extern int yytarget_struct;

unsigned lex_lineno();
int lex_token();
void register_builtin(const std::string& type);
void register_type(int symid);
void lexer_reset();
const std::string& lex_revsym(int symid);

void parser_reset();
s_node& Get(int nno);

bool gcc_open(std::fstream& fs,int genset,const std::string& suffix=".c");
bool lex_open(int genset,const std::string& suffix);

bool gcc_compile(std::fstream& fs,int genset);
bool gcc_precompile(std::fstream& fs,int genset,const std::string& variation="");
bool gcc_precomplex(int genset,const std::string& variation="");

void parse(std::vector<std::string>& svec,const std::string s,const std::string delim="|");

const std::string to_ada_name(const std::string& c_name);

extern int yyparse();

#endif // COMP_HPP

// End comp.hpp
<|endoftext|>


<commit_before>#include <algorithm>
#include <unordered_map>
#include <string>
#include <thread>

#include "message.h"
#include "message_pipe.h"
#include "registry.h"
#include "plugin_loader.h"
#include "required_messages.h"

using namespace std;

static unordered_map<string, message_pipe> out_pipes;
static unordered_map<string, registry> message_registrations;
static message_pipe in_pipe;

void to_plugin(message m)
{
	if (message_registrations.count(m.gettype())==0)
		//This message type has no registration, so discard it
		return;
	auto plugin=message_registrations[m.gettype()].get(m.getpriority());
	if (plugin.second=="")
		return;
	if (out_pipes.count(plugin.second)==0)
		//This type does not exist
		return;
	//Change the message priority to the registered priority
	out_pipes[plugin.second].write(m.change_priority(plugin.first));
}

void add_plugin(const message &m)
{
	auto pa=dynamic_cast<plugin_adder *>(m.getdata());
	if (!pa)
		//The message wasn't a plugin_adder
		return;
	if (out_pipes.count(pa->name)!=0)
		//There's already a plugin with this name
		return;
	message_pipe mp;
	thread t1(load_plugin, pa->filename, plugin_pipe(bidirectional_message_pipe(mp, in_pipe)));
	t1.detach();
	out_pipes[pa->name]=mp;
	mp.write(hello_message::create(pa->name));
}

void remove_plugin(const message &m)
{
	auto d=dynamic_cast<done_message *>(m.getdata());
	if (!d)
		return;
	for (auto &i : message_registrations)
		i.second.removeall(d->name);
	decltype(message_registrations.begin()) i;
	//Who says C++ is verbose?
	while ((i=std::find_if(message_registrations.begin(), message_registrations.end(), [](decltype(*i) &p) {return p.second.empty();}))!=message_registrations.end())
			message_registrations.erase(i);
	out_pipes.erase(d->name);
}

void add_registration(const message &m)
{
	auto r=dynamic_cast<registration_message *>(m.getdata());
	if (!r)
		return;
	if (out_pipes.count(r->getname())==0)
		//We can't talk to this plugin, so ignore its request
		return;

	bool b=message_registrations[r->getmessage()].add(r->getpriority(), r->getname());
	//Tell the plugin whether it failed or not
	out_pipes[r->getname()].write(registration_status::create(b, r->getpriority(), r->getmessage()));
}

void process(const message &m)
{
	if (m.gettype()=="add_plugin")
		add_plugin(m);
	else if (m.gettype()=="register")
		add_registration(m);
	else if (m.type=="done")
		remove_plugin(m);
	else
		to_plugin(m);
}

void run_core(const vector<message> &vm)
{
	for (auto m : vm)
		process(m);
	while (!out_pipes.empty())
	{
		process(in_pipe.blocking_read());
	}
}

int main(int argc, char *argv[])
{
	vector<message> vm;
	for (int i=1; i<argc-1; i+=2)
		vm.push_back(plugin_adder::create(argv[i],argv[i+1]));
	run_core(vm);
}
<commit_msg>Added debugging to the core<commit_after>#include <algorithm>
#include <unordered_map>
#include <string>
#include <thread>
#include <iostream>

#include "message.h"
#include "message_pipe.h"
#include "registry.h"
#include "plugin_loader.h"
#include "required_messages.h"

using namespace std;

static unordered_map<string, message_pipe> out_pipes;
static unordered_map<string, registry> message_registrations;
static message_pipe in_pipe;

static bool verbose;

void to_plugin(message m)
{
	if (message_registrations.count(m.gettype())==0)
	{
		//This message type has no registration, so discard it
		if (verbose)
			cerr << " was not registered" << endl;
		return;
	}
	auto plugin=message_registrations[m.gettype()].get(m.getpriority());
	if (plugin.second=="")
	{
		if (verbose)
			cerr << " has no more registered plugins" << endl;
		return;
	}
	if (out_pipes.count(plugin.second)==0)
	{
		//This type does not exist
		if (verbose)
			cerr << " is registered to the non-existent plugin " << plugin.second << endl;
		return;
	}
	if (verbose)
		cerr << " was sent to " << plugin.second << endl;
	//Change the message priority to the registered priority
	out_pipes[plugin.second].write(m.change_priority(plugin.first));
}

void add_plugin(const message &m)
{
	auto pa=dynamic_cast<plugin_adder *>(m.getdata());
	if (!pa)
		//The message wasn't a plugin_adder
		return;
	if (out_pipes.count(pa->name)!=0)
		//There's already a plugin with this name
		return;
	message_pipe mp;
	thread t1(load_plugin, pa->filename, plugin_pipe(bidirectional_message_pipe(mp, in_pipe)));
	t1.detach();
	out_pipes[pa->name]=mp;
	mp.write(hello_message::create(pa->name));
	if (verbose)
		cerr << " loaded plugin " << pa->name << " from " << pa->filename << endl;
}

void remove_plugin(const message &m)
{
	auto d=dynamic_cast<done_message *>(m.getdata());
	if (!d)
		return;
	for (auto &i : message_registrations)
		i.second.removeall(d->name);
	decltype(message_registrations.begin()) i;
	//Who says C++ is verbose?
	while ((i=std::find_if(message_registrations.begin(), message_registrations.end(), [](decltype(*i) &p) {return p.second.empty();}))!=message_registrations.end())
			message_registrations.erase(i);
	out_pipes.erase(d->name);
	if (verbose)
		cerr << " removed plugin " << d->name << endl;
}

void add_registration(const message &m)
{
	auto r=dynamic_cast<registration_message *>(m.getdata());
	if (!r)
		return;
	if (out_pipes.count(r->getname())==0)
		//We can't talk to this plugin, so ignore its request
		return;

	bool b=message_registrations[r->getmessage()].add(r->getpriority(), r->getname());
	//Tell the plugin whether it failed or not
	out_pipes[r->getname()].write(registration_status::create(b, r->getpriority(), r->getmessage()));
	if (verbose)
		cerr << " registered " << r->message_type << " to " << r->plugin_name << endl;
}

void process(const message &m)
{
	if (verbose)
		cerr << "Message ( " << m.type << " , " << m.priority << " , " << m.getdata() << " )";
	if (m.gettype()=="add_plugin")
		add_plugin(m);
	else if (m.gettype()=="register")
		add_registration(m);
	else if (m.type=="done")
		remove_plugin(m);
	else
		to_plugin(m);
}

void run_core(const vector<message> &vm)
{
	for (auto m : vm)
		process(m);
	while (!out_pipes.empty())
	{
		process(in_pipe.blocking_read());
	}
}

int main(int argc, char *argv[])
{
	vector<message> vm;
	for (int i=1; i<argc-1; i+=2)
	{
		if (argv[i]==string("-v") || argv[i]==string("--verbose"))
		{
			verbose=true;
			--i;
		}
		else
			vm.push_back(plugin_adder::create(argv[i],argv[i+1]));
	}
	run_core(vm);
}
<|endoftext|>


<commit_before>#ifndef FIXED_ALLOCATOR_HPP
#define FIXED_ALLOCATOR_HPP

#include "macros.hpp"

#include "third_party/boost/boost/aligned_storage.hpp"

#include <memory>
#include <vector>

namespace cass {

// This is an allocator that starts using a fixed size buffer that only
// uses the heap when exceeded. The allocator can be
// copied so the vector itself needs to hold on to the fixed buffer.

template <class T, size_t N>
class FixedAllocator : public std::allocator<T> {
public:
  typedef typename std::allocator<T>::pointer pointer;
  typedef typename std::allocator<T>::const_pointer const_pointer;
  typedef typename std::allocator<T>::size_type size_type;

  struct Fixed {
    Fixed()
      : is_used(false) {}

    typedef boost::aligned_storage<N * sizeof(T),
                                   boost::alignment_of<T>::value> Storage;

    bool is_used;
    Storage data;
  };

  FixedAllocator()
    : fixed_(NULL) {}

  FixedAllocator(Fixed* buffer)
    : fixed_(buffer) {}

  FixedAllocator(const FixedAllocator<T, N>& allocator)
    : std::allocator<T>()
    , fixed_(allocator.fixed_) {}

  FixedAllocator(const std::allocator<T>& allocator)
    : std::allocator<T>(allocator)
    , fixed_(NULL) {}

  pointer allocate(size_type n, const_pointer hint = 0) {
    if(fixed_ != NULL && !fixed_->is_used && n <= N) {
      fixed_->is_used = true; // Don't reuse the buffer
      return static_cast<T*>(fixed_->data.address());
    } else {
      return std::allocator<T>::allocate(n, hint);
    }
  }

  void deallocate(pointer p, size_type n) {
    if(fixed_ != NULL && fixed_->data.address() == p) {
      fixed_->is_used = false; // It's safe to reuse the buffer
    } else {
      std::allocator<T>::deallocate(p, n);
    }
  }

private:
  Fixed* fixed_;
};

// This vector uses the fixed buffer as long as it doesn't exceed N items.
// This can help to avoid heap allocation in the common cases while also
// handling the cases that do exceed the fixed buffer.

template<class T, size_t N>
class FixedVector : public std::vector<T, FixedAllocator<T, N> > {
public:
  FixedVector()
    : std::vector<T, FixedAllocator<T, N> >(FixedAllocator<T, N>(&fixed_)) {
    this->reserve(N);
  }

  FixedVector(size_t inital_size)
    : std::vector<T, FixedAllocator<T, N> >(FixedAllocator<T, N>(&fixed_)) {
    this->resize(inital_size);
  }

  const typename FixedAllocator<T, N>::Fixed& fixed() const { return fixed_; }

private:
  typename FixedAllocator<T, N>::Fixed fixed_;

private:
  DISALLOW_COPY_AND_ASSIGN(FixedVector);
};

} // namespace cass

#endif // FIXED_ALLOCATOR_HPP
<commit_msg>Fixed allocator, not inherting std::alloc anymore<commit_after>#ifndef FIXED_ALLOCATOR_HPP
#define FIXED_ALLOCATOR_HPP

#include "macros.hpp"

#include "third_party/boost/boost/aligned_storage.hpp"

#include <limits>
#include <memory>
#include <vector>

namespace cass {

// This is an allocator that starts using a fixed size buffer that only
// uses the heap when exceeded. The allocator can be
// copied so the vector itself needs to hold on to the fixed buffer.

template <class T, size_t N>
class FixedAllocator {
public:
  typedef size_t size_type;
  typedef ptrdiff_t difference_type;
  typedef T value_type;
  typedef T* pointer;
  typedef const T* const_pointer;
  typedef T& reference;
  typedef const T& const_reference;

  template <class U> struct rebind { typedef FixedAllocator<U, N> other; };

  struct Fixed {
    Fixed()
      : is_used(false) {}

    typedef boost::aligned_storage<N * sizeof(T),
                                   boost::alignment_of<T>::value> Storage;

    bool is_used;
    Storage data;
  };

  FixedAllocator()
    : fixed_(NULL) {}

  FixedAllocator(Fixed* fixed)
    : fixed_(fixed) {}

  FixedAllocator(const FixedAllocator<T, N>& allocator)
    : fixed_(allocator.fixed_) {}

  template<class U, size_t M>
  FixedAllocator(const FixedAllocator<U, N>& allocator)
    : fixed_(NULL) {}

  FixedAllocator(const std::allocator<T>& allocator)
    : fixed_(NULL) {}

  pointer address(reference x) const {
    return &x;
  }

  const_pointer address(const_reference x) const {
    return &x;
  }

  pointer allocate(size_type n, const_pointer hint = NULL) {
    if(fixed_ != NULL && !fixed_->is_used && n <= N) {
      fixed_->is_used = true; // Don't reuse the buffer
      return static_cast<T*>(fixed_->data.address());
    } else {
      return static_cast<T*>(::operator new(sizeof(T) * n));
    }
  }

  void deallocate(pointer p, size_type n) {
    if(fixed_ != NULL && fixed_->data.address() == p) {
      fixed_->is_used = false; // It's safe to reuse the buffer
    } else {
      ::operator delete(p);
    }
  }

  void construct(pointer p, const_reference x) {
    new (p) value_type(x);
  }

  void destroy(pointer p) {
    p->~value_type();
  }

  size_type max_size() const throw() {
    return std::numeric_limits<size_type>::max();
  }

private:
  Fixed* fixed_;
};

// This vector uses the fixed buffer as long as it doesn't exceed N items.
// This can help to avoid heap allocation in the common cases while also
// handling the cases that do exceed the fixed buffer.

template<class T, size_t N>
class FixedVector : public std::vector<T, FixedAllocator<T, N> > {
public:
  FixedVector()
    : std::vector<T, FixedAllocator<T, N> >(FixedAllocator<T, N>(&fixed_)) {
    this->reserve(N);
  }

  FixedVector(size_t inital_size)
    : std::vector<T, FixedAllocator<T, N> >(FixedAllocator<T, N>(&fixed_)) {
    this->resize(inital_size);
  }

  const typename FixedAllocator<T, N>::Fixed& fixed() const { return fixed_; }

private:
  typename FixedAllocator<T, N>::Fixed fixed_;

private:
  DISALLOW_COPY_AND_ASSIGN(FixedVector);
};

} // namespace cass

#endif // FIXED_ALLOCATOR_HPP
<|endoftext|>


<commit_before>#include "graphi.hpp"
#include <algorithm>
#include <queue>

bool GraphI::find_path(int node1, int node2, std::vector<int> *path) const
{
    int vnum = vertex_num();
    std::vector<bool> visited(vnum, false);
    std::vector<int> prev(vnum, -1);
    std::vector<int> dist(vnum, vnum + 1);
    for (auto i = 0; i < vnum; ++i) {
        visited[i] = false;
        prev[i] = -1;
        dist[i] = vnum + 1;
    }

    std::queue<int> queue;

    bool path_found = false;

    queue.push(node1);
    dist[node1] = 0;

    while (!path_found && !queue.empty()) {
        int u = queue.front();
        queue.pop();
        visited[u] = true;

        for (auto v = 0; v < vnum; ++v) {
            if (is_edge(u, v) && !visited[v]) {
                int alt = dist[u] + 1;
                if (alt < dist[v]) {
                    dist[v] = alt;
                    prev[v] = u;
                }

                queue.push(v);
                if (v == node2) {
                    path_found = true;
                    break;
                }
            }
        }
    }

    if (path_found) {
        int v = node2;
        do {
            path->push_back(v);
            v = prev[v];
        } while (v != -1);
        std::reverse(path->begin(), path->end());
    }

    return path_found;
}
<commit_msg>Add fixme comment<commit_after>#include "graphi.hpp"
#include <algorithm>
#include <queue>

bool GraphI::find_path(int node1, int node2, std::vector<int> *path) const
{
    int vnum = vertex_num();
    std::vector<bool> visited(vnum, false);
    std::vector<int> prev(vnum, -1);
    std::vector<int> dist(vnum, vnum + 1);
    for (auto i = 0; i < vnum; ++i) {
        visited[i] = false;
        prev[i] = -1;
        dist[i] = vnum + 1;
    }

    std::queue<int> queue;

    bool path_found = false;

    queue.push(node1);
    dist[node1] = 0;

    while (!path_found && !queue.empty()) {
        int u = queue.front();
        queue.pop();
        visited[u] = true;

        for (auto v = 0; v < vnum; ++v) {
            if (is_edge(u, v) && !visited[v]) {
                int alt = dist[u] + 1;
                if (alt < dist[v]) {
                    dist[v] = alt;
                    prev[v] = u;
                }

                queue.push(v);
                if (v == node2) {
                    path_found = true;
                    break;
                }
            }
        }
    }

    if (path_found) {
        int v = node2;
        do {
            path->push_back(v);
            v = prev[v];
        } while (v != -1);
        // FIXME
        std::reverse(path->begin(), path->end());
    }

    return path_found;
}
<|endoftext|>


<commit_before>#include <stdlib.h>

#include <boost/thread/thread.hpp>
#include <boost/thread/locks.hpp>
#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/atomic.hpp>
#include <boost/make_shared.hpp>
#include <boost/thread.hpp>
#include <boost/function.hpp>
#include <boost/shared_array.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/lexical_cast.hpp>
//this quiets a deprecated warning
#define BOOST_NO_HASH
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/topological_sort.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/foreach.hpp>

#include <iostream>
#include <deque>

boost::atomic<unsigned> nsimultaneous, noutstanding;

namespace asio = boost::asio;
asio::io_service io_service;
boost::thread_group tgroup;

struct data {
  float value;
  typedef boost::shared_ptr<data> ptr;
  typedef boost::shared_ptr<const data> const_ptr;
};

typedef std::deque<data::const_ptr> datadeque;

struct module : boost::enable_shared_from_this<module> , boost::noncopyable
{
  typedef boost::shared_ptr<module> ptr;
  typedef std::map<std::string, datadeque> inputs_t;
  inputs_t inputs;

  typedef std::map<std::string, std::pair<ptr, std::string> > outputs_t;
  outputs_t outputs;

  boost::mutex mtx;

  bool inputs_ready()
  {
    boost::unique_lock<boost::mutex> lock(mtx);
    if (inputs.size() == 0)
      {
        std::cout << this << " READY CAUSE NO INPUTS\n";
        return true;
      }
    for (inputs_t::iterator it = inputs.begin(), end = inputs.end();
         it != end;
         ++it)
      {
        if (it->second.size() == 0)
          return false;
      }
    return true;
  }

  void push(const std::string& port, data::const_ptr newdata)
  {
    boost::unique_lock<boost::mutex> lock(mtx);
    inputs[port].push_back(newdata);
  }

  void doit(boost::asio::io_service& serv)
  {
    data::ptr newdata(new data);
    newdata->value = 1;
    {
      boost::unique_lock<boost::mutex> lock(mtx);
      for (inputs_t::iterator it = inputs.begin(), end = inputs.end();
           it != end;
           ++it)
        {
          newdata->value += it->second.front()->value;
          it->second.pop_front();
        }
    }
    std::cout << this << " new value = " << newdata->value << "\n";
    std::cout << this << " pushing to " << outputs.size() << " outputs" << std::endl;
    // spend some time working
    unsigned ms_work = rand() % 3000;
    boost::asio::io_service inner_serv;
    boost::asio::deadline_timer dt(inner_serv);
    dt.expires_from_now(boost::posix_time::milliseconds(ms_work));
    dt.wait();

    for (outputs_t::iterator it = outputs.begin(), end = outputs.end();
         it != end;
         ++it)
      {
        module::ptr downstream_module = it->second.first;
        const std::string& downstream_port = it->second.second;

        std::cout << this << " => " << downstream_port << "\n";
        downstream_module->push(downstream_port, newdata);
      }

    run(serv);
  }

  static void
  async_waitforinput(boost::asio::io_service& serv,
                     module::ptr m)
  {
    std::cout << m.get() << " waiting..." << std::endl;
    boost::asio::io_service inner_serv;
    boost::asio::deadline_timer dt(inner_serv);
    boost::asio::io_service::work work(serv);

    assert(m.get());

    for (;;) {
      if (m->inputs_ready())
        {
          serv.post(boost::bind(&module::doit, m.get(), boost::ref(serv)));
          std::cout << m.get() << " inputs ready! " << m->inputs.size() << std::endl;
          return;
        }
      dt.expires_from_now(boost::posix_time::milliseconds(3));
      dt.wait();
    }
  }

  boost::scoped_ptr<boost::thread> input_watcher;

  void run(boost::asio::io_service& serv)
  {
    if (input_watcher)
      input_watcher->join();
    input_watcher.reset(new boost::thread(boost::bind(&async_waitforinput,
                                                      boost::ref(serv),
                                                      shared_from_this())));
  }
};

module::ptr
make_graph(boost::asio::io_service& serv, unsigned N)
{
  module::ptr root(new module);
  root->run(serv);
  module::ptr prev = root;
  module::ptr next;

  for (unsigned n=0; n<N; ++n)
    {
      next.reset(new module);
      next->inputs["in"];
      prev->outputs["out"] = make_pair(next, std::string("in"));
      next->run(serv);
      prev = next;
    }
  return root;
}

using boost::vertex_property_tag;
using boost::adjacency_list;
using boost::vecS;
using boost::setS;
using boost::bidirectionalS;
using boost::property;
using boost::property_map;
using boost::graph_traits;

struct edge
{
  std::string from_port, to_port;
  std::deque<boost::any> deque;
  typedef boost::shared_ptr<edge> ptr;
  typedef boost::shared_ptr<const edge> const_ptr;
};

typedef adjacency_list<setS, // OutEdgeList
                       vecS, // VertexList
                       bidirectionalS, // Directed
                       module::ptr, // vertex property
                       edge::ptr> // edge property
graph_t;

int main()
{
  using boost::bind;
  namespace asio = boost::asio;

  std::cout << "start..." << std::endl;
  /*

  module::ptr graph = make_graph(io_service, 30);

  graph->run(io_service);

  {
    for (unsigned j=0; j<1; ++j)
      {
        tgroup.create_thread(bind(&asio::io_service::run, &io_service));
      }
  }

  tgroup.join_all();
  */
  std::cout << "exit." << std::endl;
}
<commit_msg>whee parallel edgeses<commit_after>#include <stdlib.h>

#include <boost/thread/thread.hpp>
#include <boost/thread/locks.hpp>
#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/atomic.hpp>
#include <boost/make_shared.hpp>
#include <boost/thread.hpp>
#include <boost/function.hpp>
#include <boost/shared_array.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/lexical_cast.hpp>
//this quiets a deprecated warning
#define BOOST_NO_HASH
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/topological_sort.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/foreach.hpp>

#include <iostream>
#include <deque>

boost::atomic<unsigned> nsimultaneous, noutstanding;

namespace asio = boost::asio;
asio::io_service io_service;
boost::thread_group tgroup;

struct data {
  float value;
  typedef boost::shared_ptr<data> ptr;
  typedef boost::shared_ptr<const data> const_ptr;
};

typedef std::deque<data::const_ptr> datadeque;

struct module : boost::enable_shared_from_this<module> , boost::noncopyable
{
  typedef boost::shared_ptr<module> ptr;
  typedef std::map<std::string, datadeque> inputs_t;
  inputs_t inputs;

  typedef std::map<std::string, std::pair<ptr, std::string> > outputs_t;
  outputs_t outputs;

  boost::mutex mtx;

  bool inputs_ready()
  {
    boost::unique_lock<boost::mutex> lock(mtx);
    if (inputs.size() == 0)
      {
        std::cout << this << " READY CAUSE NO INPUTS\n";
        return true;
      }
    for (inputs_t::iterator it = inputs.begin(), end = inputs.end();
         it != end;
         ++it)
      {
        if (it->second.size() == 0)
          return false;
      }
    return true;
  }

  void push(const std::string& port, data::const_ptr newdata)
  {
    boost::unique_lock<boost::mutex> lock(mtx);
    inputs[port].push_back(newdata);
  }

  void doit(boost::asio::io_service& serv)
  {
    data::ptr newdata(new data);
    newdata->value = 1;
    {
      boost::unique_lock<boost::mutex> lock(mtx);
      for (inputs_t::iterator it = inputs.begin(), end = inputs.end();
           it != end;
           ++it)
        {
          newdata->value += it->second.front()->value;
          it->second.pop_front();
        }
    }
    std::cout << this << " new value = " << newdata->value << "\n";
    std::cout << this << " pushing to " << outputs.size() << " outputs" << std::endl;
    // spend some time working
    unsigned ms_work = rand() % 3000;
    boost::asio::io_service inner_serv;
    boost::asio::deadline_timer dt(inner_serv);
    dt.expires_from_now(boost::posix_time::milliseconds(ms_work));
    dt.wait();

    for (outputs_t::iterator it = outputs.begin(), end = outputs.end();
         it != end;
         ++it)
      {
        module::ptr downstream_module = it->second.first;
        const std::string& downstream_port = it->second.second;

        std::cout << this << " => " << downstream_port << "\n";
        downstream_module->push(downstream_port, newdata);
      }

    run(serv);
  }

  static void
  async_waitforinput(boost::asio::io_service& serv,
                     module::ptr m)
  {
    std::cout << m.get() << " waiting..." << std::endl;
    boost::asio::io_service inner_serv;
    boost::asio::deadline_timer dt(inner_serv);
    boost::asio::io_service::work work(serv);

    assert(m.get());

    for (;;) {
      if (m->inputs_ready())
        {
          serv.post(boost::bind(&module::doit, m.get(), boost::ref(serv)));
          std::cout << m.get() << " inputs ready! " << m->inputs.size() << std::endl;
          return;
        }
      dt.expires_from_now(boost::posix_time::milliseconds(3));
      dt.wait();
    }
  }

  boost::scoped_ptr<boost::thread> input_watcher;

  void run(boost::asio::io_service& serv)
  {
    if (input_watcher)
      input_watcher->join();
    input_watcher.reset(new boost::thread(boost::bind(&async_waitforinput,
                                                      boost::ref(serv),
                                                      shared_from_this())));
  }
};

module::ptr
make_graph(boost::asio::io_service& serv, unsigned N)
{
  module::ptr root(new module);
  root->run(serv);
  module::ptr prev = root;
  module::ptr next;

  for (unsigned n=0; n<N; ++n)
    {
      next.reset(new module);
      next->inputs["in"];
      prev->outputs["out"] = make_pair(next, std::string("in"));
      next->run(serv);
      prev = next;
    }
  return root;
}

using boost::vertex_property_tag;
using boost::adjacency_list;
using boost::vecS;
using boost::setS;
using boost::bidirectionalS;
using boost::property;
using boost::property_map;
using boost::graph_traits;

struct edge
{
  std::string from_port, to_port;
  std::deque<boost::any> deque;
  typedef boost::shared_ptr<edge> ptr;
  typedef boost::shared_ptr<const edge> const_ptr;
};

typedef adjacency_list<vecS, // OutEdgeList
                       vecS, // VertexList
                       bidirectionalS, // Directed
                       module::ptr, // vertex property
                       edge::ptr> // edge property
graph_t;

int main()
{
  using boost::bind;
  namespace asio = boost::asio;

  std::cout << "start..." << std::endl;

  graph_t g;

  module::ptr m1(new module), m2(new module);
  edge::ptr e1(new edge), e2(new edge);

  graph_t::vertex_descriptor vd1 = add_vertex(m1, g),
    vd2 = add_vertex(m2, g);

  bool added;
  graph_t::edge_descriptor ed1, ed2;
  tie(ed1, added) = add_edge(vd1, vd2, e1, g);
  assert(added);
  tie(ed2, added) = add_edge(vd1, vd2, e2, g);
  assert(added);

  std::ofstream gviz_str("graph.dot");
  boost::write_graphviz(gviz_str, g);

  /*

  module::ptr graph = make_graph(io_service, 30);

  graph->run(io_service);

  {
    for (unsigned j=0; j<1; ++j)
      {
        tgroup.create_thread(bind(&asio::io_service::run, &io_service));
      }
  }

  tgroup.join_all();
  */
  std::cout << "exit." << std::endl;
}
<|endoftext|>


<commit_before>#include "ManuHX.h"

registerMooseObject("MoltresApp", ManuHX);

InputParameters
ManuHX::validParams()
{
  InputParameters params = Kernel::validParams();
  params.addClassDescription("A uniformly applied heat removal proportional to a difference"
                             "from a nominal temperature. A global heat exchanger.");
  params.addRequiredParam<Real>("htc", "heat transfer coefficient for q'=h*(T-T_ref)");
  params.addRequiredParam<Real>("tref", "reference temperature");
  return params;
}

ManuHX::ManuHX(const InputParameters & parameters)
  : Kernel(parameters),
    _htc(getParam<Real>("htc")),
    _tref(getParam<Real>("tref"))
{
}

Real
ManuHX::computeQpResidual()
{
  // positive -> heat removal
  return _test[_i][_qp] * _htc * (_u[_qp] - _tref);
}

Real
ManuHX::computeQpJacobian()
{
  return _test[_i][_qp] * _htc;
}
<commit_msg>Fix ManuHX Jacobian term<commit_after>#include "ManuHX.h"

registerMooseObject("MoltresApp", ManuHX);

InputParameters
ManuHX::validParams()
{
  InputParameters params = Kernel::validParams();
  params.addClassDescription("A uniformly applied heat removal proportional to a difference"
                             "from a nominal temperature. A global heat exchanger.");
  params.addRequiredParam<Real>("htc", "heat transfer coefficient for q'=h*(T-T_ref)");
  params.addRequiredParam<Real>("tref", "reference temperature");
  return params;
}

ManuHX::ManuHX(const InputParameters & parameters)
  : Kernel(parameters),
    _htc(getParam<Real>("htc")),
    _tref(getParam<Real>("tref"))
{
}

Real
ManuHX::computeQpResidual()
{
  // positive -> heat removal
  return _test[_i][_qp] * _htc * (_u[_qp] - _tref);
}

Real
ManuHX::computeQpJacobian()
{
  return _test[_i][_qp] * _htc * _phi[_j][_qp];
}
<|endoftext|>