[chronojump] RInside for predict points
- From: Xavier de Blas <xaviblas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] RInside for predict points
- Date: Mon, 26 Apr 2010 11:10:24 +0000 (UTC)
commit 57e5da7a82bf6b938a4d3cb01a0eeee61f03e43f
Author: Xavier de Blas <xaviblas gmail com>
Date: Mon Apr 26 19:09:48 2010 +0800
RInside for predict points
src/angle/kneeAngle.cpp | 98 +++++++++++++++++++++----
src/angle/kneeAngleFunctions.cpp | 33 +++++---
src/angle/kneeAngleGlobal.cpp | 9 ++
src/angle/kneeAngleRInside.cpp | 150 ++++++++++++++++++++++++++++++++++++++
src/angle/kneeAngleUtil.cpp | 10 +-
5 files changed, 267 insertions(+), 33 deletions(-)
---
diff --git a/src/angle/kneeAngle.cpp b/src/angle/kneeAngle.cpp
index d7fa7fa..0027835 100644
--- a/src/angle/kneeAngle.cpp
+++ b/src/angle/kneeAngle.cpp
@@ -138,19 +138,23 @@
#include "opencv/cv.h"
#include "opencv/highgui.h"
-#include <opencv/cxcore.h>
+//#include <opencv/cxcore.h>
#include "stdio.h"
#include "math.h"
-#include<iostream>
-#include<fstream>
-#include<vector>
+//#include<iostream>
+//#include<fstream>
+//#include<vector>
#include <string>
+#include <RInside.h>
+
#include "kneeAngleGlobal.cpp"
#include "kneeAngleUtil.cpp"
#include "kneeAngleFunctions.cpp"
+#include "kneeAngleSystemCalls.cpp"
+
-using namespace std;
+//using namespace std;
int menu(IplImage *, CvFont);
@@ -162,7 +166,7 @@ int main(int argc,char **argv)
char *startMessage = new char[300];
sprintf(startMessage, "\nkneeAngle HELP.\n\nProvide file location as a first argument...\nOptional: as 2nd argument provide a fraction of video to start at that frame, or a concrete frame.\nOptional: as 3rd argument provide mode you want to execute (avoiding main menu).\n\t%d: validation; %d: blackWithoutMarkers; %d: skinOnlyMarkers; %d: blackOnlyMarkers.\n\nEg: Start at frame 5375:\n\tkneeAngle myfile.mov 5375\nEg:start at 80 percent of video and directly as blackOnlyMarkers:\n\tkneeAngle myFile.mov .8 %d\n",
validation, blackWithoutMarkers, skinOnlyMarkers, blackOnlyMarkers, blackOnlyMarkers);
- cout<< startMessage <<endl;
+ std::cout<< startMessage <<std::endl;
exit(1);
}
@@ -246,7 +250,8 @@ int main(int argc,char **argv)
double knee2Hip,knee2Toe,hip2Toe;
double thetaExpected, thetaMarked;
- string text,angle;
+ //string text,angle;
+ std::string text;
double minThetaExpected = 360;
double minThetaMarked = 360;
double minThetaRealFlex = 360;
@@ -259,12 +264,16 @@ int main(int argc,char **argv)
FILE *fdatapre; //each line: 'current box height; current angle'
FILE *fdatapost; //each line: 'current box height percent; current angle' (percent comes from fheader)
+ //file for smoothing and predictions
+// FILE *fpointsdump; //contains X,Y of three points each frame
+
char header[] = "_header.txt";
char txt[] = ".txt";
char csv[] = ".csv";
char fheaderName [strlen(fileName) + strlen(header)];
char fdatapreName [strlen(fileName) + strlen(txt)];
char fdatapostName [strlen(fileName) + strlen(csv)];
+// char fpointsdumpName[] = "pointsDump.csv";
if(programMode == validation) {
// cvNamedWindow("Holes_on_contour",1);
@@ -306,9 +315,19 @@ int main(int argc,char **argv)
}
else if (programMode == blackWithoutMarkers)
cvNamedWindow("result",1);
-
-
+ /*
+ //put headers on pointsDump file
+ if((fpointsdump=fopen(fpointsdumpName,"w"))==NULL){
+ printf("Error, no se puede escribir en el fichero %s\n",fpointsdumpName);
+ fclose(fpointsdump);
+ exit(0);
+ } else {
+ fprintf(fpointsdump, "hipX;hipY;kneeX;kneeY;toeX;toeY\n");
+ fclose(fpointsdump);
+ }
+ */
+
int kneePointWidth = -1;
int toePointWidth = -1;
@@ -365,7 +384,13 @@ int main(int argc,char **argv)
CvPoint hipOldWorked = pointToZero();
CvPoint kneeOldWorked = pointToZero();
CvPoint toeOldWorked = pointToZero();
+
+ CvSeq* seqPredicted;
+ CvPoint hipPredicted = pointToZero();
+ CvPoint kneePredicted = pointToZero();
+ CvPoint toePredicted = pointToZero();
+
/*
int upLegMarkedDist = 0;
int upLegMarkedDistMax = 0;
@@ -469,6 +494,7 @@ int main(int argc,char **argv)
while(!shouldEnd)
{
+
/*
* 1
* GET FRAME AND FLOW CONTROL
@@ -584,15 +610,28 @@ int main(int argc,char **argv)
* FIND THREE MARKER POINTS
*/
+
+
+ //predict where will be the points now
+ seqPredicted = predictPointsRInside();
+ hipPredicted = *CV_GET_SEQ_ELEM( CvPoint, seqPredicted, 0);
+ kneePredicted = *CV_GET_SEQ_ELEM( CvPoint, seqPredicted, 1);
+ toePredicted = *CV_GET_SEQ_ELEM( CvPoint, seqPredicted, 2);
+
+// printf("%d;%d;%d;%d;%d;%d\n", hipPredicted.x, hipPredicted.y,
+// kneePredicted.x, kneePredicted.y, toePredicted.x, toePredicted.y);
+
if(programMode == skinOnlyMarkers || programMode == blackOnlyMarkers || programMode == validation)
{
/* kalman */
+ /*
const CvMat* prediction = cvKalmanPredict(kalman, 0);
CvPoint prediction_pt = cvPoint(
cvRound(prediction->data.fl[0]),
cvRound(prediction->data.fl[1]));
+ */
/* /kalman */
@@ -622,7 +661,7 @@ int main(int argc,char **argv)
CvSeq* seqHolesEnd;
if(programMode == skinOnlyMarkers) {
- seqHolesEnd = findHolesSkin(output, frame_copy, hipMarked, kneeMarked, toeMarked, font);
+ seqHolesEnd = findHolesSkin(output, frame_copy, hipMarked, kneeMarked, toeMarked, hipPredicted, kneePredicted, toePredicted, font);
}
else { //if(programMode == blackOnlyMarkers || programMode == validation)
//this segmented is to find the contour (threshold is lot little)
@@ -640,7 +679,7 @@ int main(int argc,char **argv)
cvCopy(frame_copy,frame_copyTemp);
seqHolesEnd = findHoles(
outputTemp, segmented, foundHoles, frame_copy,
- maxrect, hipOld, kneeOld, toeOld, font);
+ maxrect, hipOld, kneeOld, toeOld, hipPredicted, kneePredicted, toePredicted, font);
//if hip or toe is touching a border of the image
//then will not be included in largest contour
@@ -673,7 +712,7 @@ imageGuiResult(gui, "going", font);
//printf("threshold :%d\n", threshold);
//printf("thresholdLC :%d\n", thresholdLargestContour);
//cvWaitKey(500); //to allow messages be shown
- seqHolesEnd = findHolesSkin(output, frame_copy, hipMarked, kneeMarked, toeMarked, font);
+ seqHolesEnd = findHolesSkin(output, frame_copy, hipMarked, kneeMarked, toeMarked, hipPredicted, kneePredicted, toePredicted, font);
imageGuiResult(gui, "returned", font);
//cvWaitKey(500); //to allow gui image be shown
}
@@ -684,7 +723,29 @@ imageGuiResult(gui, "returned", font);
hipMarked = *CV_GET_SEQ_ELEM( CvPoint, seqHolesEnd, 0);
kneeMarked = *CV_GET_SEQ_ELEM( CvPoint, seqHolesEnd, 1 );
toeMarked = *CV_GET_SEQ_ELEM( CvPoint, seqHolesEnd, 2 );
-
+
+
+ //if all the points are ok, the dump in pointsDump file to smooth and predict
+ if( ! pointIsNull(hipMarked) && ! pointIsNull(kneeMarked) && ! pointIsNull(toeMarked) ) {
+ /*
+ if((fpointsdump=fopen(fpointsdumpName,"a"))==NULL){
+ printf("Error, no se puede añadir en el fichero %s\n",fpointsdumpName);
+ } else {
+ fprintf(fpointsdump, "%d;%d;%d;%d;%d;%d\n", hipMarked.x, hipMarked.y,
+ kneeMarked.x, kneeMarked.y, toeMarked.x, toeMarked.y);
+ }
+ fclose(fpointsdump);
+ */
+
+ hipXVector.push_back(hipMarked.x);
+ hipYVector.push_back(hipMarked.y);
+ kneeXVector.push_back(kneeMarked.x);
+ kneeYVector.push_back(kneeMarked.y);
+ toeXVector.push_back(toeMarked.x);
+ toeYVector.push_back(toeMarked.y);
+ }
+
+
// kalman
@@ -1638,10 +1699,17 @@ imageGuiResult(gui, "returned", font);
cvThreshold(gray,segmented,thresholdLargestContour,thresholdMax,CV_THRESH_BINARY_INV);
maxrect = findLargestContour(segmented, outputTemp, showContour);
- //frame_copyTemp = cvCreateImage( cvSize(frame->width,frame->height),IPL_DEPTH_8U, frame->nChannels );
+
+ //predict where will be the points now
+ seqPredicted = predictPointsRInside();
+ hipPredicted = *CV_GET_SEQ_ELEM( CvPoint, seqPredicted, 0);
+ kneePredicted = *CV_GET_SEQ_ELEM( CvPoint, seqPredicted, 1);
+ toePredicted = *CV_GET_SEQ_ELEM( CvPoint, seqPredicted, 2);
+
+
findHoles(
outputTemp, segmented, foundHoles, frame_copyTemp,
- maxrect, hipOld, kneeOld, toeOld, font);
+ maxrect, hipOld, kneeOld, toeOld, hipPredicted, kneePredicted, toePredicted, font);
cvCopy(segmentedValidationHoles, output);
cvShowImage("threshold", output);
diff --git a/src/angle/kneeAngleFunctions.cpp b/src/angle/kneeAngleFunctions.cpp
index a831996..1de7b6f 100644
--- a/src/angle/kneeAngleFunctions.cpp
+++ b/src/angle/kneeAngleFunctions.cpp
@@ -24,12 +24,12 @@
#include "opencv/cv.h"
#include "opencv/highgui.h"
-#include <opencv/cxcore.h>
+//#include <opencv/cxcore.h>
#include "stdio.h"
#include "math.h"
-#include<iostream>
-#include<fstream>
-#include<vector>
+//#include<iostream>
+//#include<fstream>
+//#include<vector>
#include <string>
@@ -345,7 +345,10 @@ CvPoint findToePoint(IplImage *img,CvRect roirect,int startx,int starty, int toe
* imgH (image Holes)
*/
CvSeq* findHoles(IplImage *imgC, IplImage *imgH, IplImage *foundHoles, IplImage *imgMain,
- CvRect roirect, CvPoint hipOld, CvPoint kneeOld, CvPoint toeOld, CvFont font)
+ CvRect roirect,
+ CvPoint hipOld, CvPoint kneeOld, CvPoint toeOld,
+ CvPoint hipPredicted, CvPoint kneePredicted, CvPoint toePredicted,
+ CvFont font)
{
CvPoint pt;
pt.x =0;pt.y=0;
@@ -518,16 +521,17 @@ CvSeq* findHoles(IplImage *imgC, IplImage *imgH, IplImage *foundHoles, IplImage
if(size == sizeBig1 || size == sizeBig2 || size == sizeBig3)
validSure = true;
}
- //if found a point before, and this point is inside before point (ok at 300 fps)
+ //if found a point before, and this point is where it's predicted, or inside the before point (ok at 300 fps)
//a point is also ok, if we come from a user forward (then, there's not need to be inside old point)
- else if (pointInside(hipOld, sp1, sp2) || pointInside(kneeOld, sp1,sp2) || pointInside(toeOld, sp1,sp2))
+ else if (pointInside(hipPredicted, sp1, sp2) || pointInside(kneePredicted, sp1,sp2) || pointInside(toePredicted, sp1,sp2)
+ || (pointInside(hipOld, sp1, sp2) || pointInside(kneeOld, sp1,sp2) || pointInside(toeOld, sp1,sp2)))
validSure = true;
}
if(validSure) {
CvPoint center = *CV_GET_SEQ_ELEM( CvPoint, seqHolesCenter, i );
- //the point will be hip knee or toe depending on the distance betwee old hipe, knee & toe
+ //the point will be hip knee or toe depending on the distance betwee old hip, knee & toe
//but give preference to the top (<=) because will be the first to be found (top to bottom)
int pointIs = TOGGLENOTHING;
if(!pointIsNull(hipOld) && !pointIsNull(kneeOld) && !pointIsNull(toeOld)) {
@@ -635,7 +639,10 @@ CvSeq* findHoles(IplImage *imgC, IplImage *imgH, IplImage *foundHoles, IplImage
* this function is realy similiar to findHoles
* try to do only a function
*/
-CvSeq* findHolesSkin(IplImage *imgThresh, IplImage *imgColor, CvPoint hipOld, CvPoint kneeOld, CvPoint toeOld, CvFont font)
+CvSeq* findHolesSkin(IplImage *imgThresh, IplImage *imgColor,
+ CvPoint hipOld, CvPoint kneeOld, CvPoint toeOld,
+ CvPoint hipPredicted, CvPoint kneePredicted, CvPoint toePredicted,
+ CvFont font)
{
CvPoint pt;
pt.x =0;pt.y=0;
@@ -827,23 +834,23 @@ CvSeq* findHolesSkin(IplImage *imgThresh, IplImage *imgColor, CvPoint hipOld, Cv
}
}
}
- //if found a point before, and this point is inside before point (ok at 300 fps)
+ //if found a point before, and this point is where it's predicted, or inside the before point (ok at 300 fps)
//a point is also ok, if we come from a user forward (then, there's not need to be inside old point)
else {
validSure = true;
- if(pointInside(hipOld, sp1, sp2)) {
+ if(pointInside(hipPredicted, sp1, sp2) || pointInside(hipOld, sp1, sp2)) {
hipPoint.x = center.x;
hipPoint.y = center.y;
color = RED;
sprintf(labelShort,"H");
}
- else if(pointInside(kneeOld, sp1,sp2)) {
+ else if(pointInside(kneePredicted, sp1, sp2) || pointInside(kneeOld, sp1, sp2)) {
kneePoint.x = center.x;
kneePoint.y = center.y;
color = GREEN;
sprintf(labelShort,"K");
}
- else if(pointInside(toeOld, sp1,sp2)) {
+ else if(pointInside(toePredicted, sp1, sp2) || pointInside(toeOld, sp1, sp2)) {
toePoint.x = center.x;
toePoint.y = center.y;
color = BLUE;
diff --git a/src/angle/kneeAngleGlobal.cpp b/src/angle/kneeAngleGlobal.cpp
index 12073e6..4f3bed6 100644
--- a/src/angle/kneeAngleGlobal.cpp
+++ b/src/angle/kneeAngleGlobal.cpp
@@ -114,4 +114,13 @@ bool mouseMultiplier = false; //using shift key
bool zoomed = false;
double zoomScale = 2;
+//predictions stuff
+RInside R = RInside(); // create an embedded R instance
+
+std::vector<int> hipXVector;
+std::vector<int> hipYVector;
+std::vector<int> kneeXVector;
+std::vector<int> kneeYVector;
+std::vector<int> toeXVector;
+std::vector<int> toeYVector;
diff --git a/src/angle/kneeAngleRInside.cpp b/src/angle/kneeAngleRInside.cpp
new file mode 100644
index 0000000..1062818
--- /dev/null
+++ b/src/angle/kneeAngleRInside.cpp
@@ -0,0 +1,150 @@
+/*
+ * This file is part of ChronoJump
+ *
+ * Chronojump is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Chronojump is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+# Copyright (C) 2010 Xavier de Blas <xaviblas gmail com> , Carlos J. Gil Bellosta <cgb datanalytics com>
+ *
+ */
+
+
+#include "stdio.h"
+#include <sys/wait.h>
+#include <string>
+
+
+CvSeq* predictPointsRInside()
+{
+ /* TESTING:
+
+ R.assign(hipXVector, "d1");
+ R.assign(hipYVector, "d2");
+ R.assign(kneeXVector, "d3");
+ R.assign(kneeYVector, "d4");
+ R.assign(toeXVector, "d5");
+ R.assign(toeYVector, "d6");
+ std::string prova = // now access in R
+ "cat('\nd1=', d1, '\n');"
+ "cat('\nd2=', d2, '\n');"
+ "cat('\nd3=', d3, '\n');"
+ "cat('\nd4=', d4, '\n');"
+ "cat('\nd5=', d5, '\n');"
+ "cat('\nd6=', d6, '\n');";
+ R.parseEvalQ(prova);
+ */
+
+ CvMemStorage* storage = cvCreateMemStorage(0);
+ CvSeq* seqPoints = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage );
+ CvPoint hip;
+ hip.x =0; hip.y=0;
+ CvPoint knee;
+ knee.x =0; knee.y=0;
+ CvPoint toe;
+ toe.x =0; toe.y=0;
+
+ SEXP ans;
+ std::string txt = " \
+ span = 30; \
+ threshold = 3; \
+ discard = 10; \
+ \
+ maxX = 512; \
+ maxY = 384; \
+ #cat('(', length(x), '): ', x[length(x)]); \
+ \
+ if( length(x) < discard || sd(x) == 0) { \
+ n<- x[ length( x ) ]; \
+ } else { \
+ which.predict <- max( 1, length(x) - span):length(x); \
+ time.1 <- 1:length( which.predict ); \
+ x.1 <- x[ which.predict ]; \
+ \
+ resid <- x.1 - predict( lm( x.1 ~ time.1 ), data.frame( time.1 = time.1 ) ); \
+ x.outlier <- abs( resid ) > threshold * sd( resid ); \
+ \
+ time.1 <- time.1[!x.outlier]; \
+ x.1 <- x.1 [!x.outlier]; \
+ \
+ if( is.na( sd(x.1) ) ) { \
+ n<- x[ length( x ) ]; \
+ } else { \
+ n<- round ( \
+ predict( lm( x.1 ~ time.1 ), newdata = data.frame( time.1 = length( time.1 ) + 1 ) ) \
+ ); \
+ } \
+ } \
+ ";
+
+ R.assign( txt, "txt");
+
+ //HIP
+ if(hipXVector.empty())
+ hip.x = -1;
+ else {
+ R.assign(hipXVector, "x");
+ R.parseEval(txt, ans);
+ hip.x = Rcpp::as< int >(ans);
+ }
+
+ if(hipYVector.empty())
+ hip.y = -1;
+ else {
+ R.assign(hipYVector, "x");
+ R.parseEval(txt, ans);
+ hip.y = Rcpp::as< int >(ans);
+ }
+
+ //KNEE
+ if(kneeXVector.empty())
+ knee.x = -1;
+ else {
+ R.assign(kneeXVector, "x");
+ R.parseEval(txt, ans);
+ knee.x = Rcpp::as< int >(ans);
+ }
+
+ if(kneeYVector.empty())
+ knee.y = -1;
+ else {
+ R.assign(kneeYVector, "x");
+ R.parseEval(txt, ans);
+ knee.y = Rcpp::as< int >(ans);
+ }
+
+ //TOE
+ if(toeXVector.empty())
+ toe.x = -1;
+ else {
+ R.assign(toeXVector, "x");
+ R.parseEval(txt, ans);
+ toe.x = Rcpp::as< int >(ans);
+ }
+
+ if(toeYVector.empty())
+ toe.y = -1;
+ else {
+ R.assign(toeYVector, "x");
+ R.parseEval(txt, ans);
+ toe.y = Rcpp::as< int >(ans);
+ }
+
+ //PASS to cvSeq
+ cvSeqPush( seqPoints, &hip );
+ cvSeqPush( seqPoints, &knee );
+ cvSeqPush( seqPoints, &toe );
+
+ return seqPoints;
+}
+
diff --git a/src/angle/kneeAngleUtil.cpp b/src/angle/kneeAngleUtil.cpp
index 03e2b35..f06d597 100644
--- a/src/angle/kneeAngleUtil.cpp
+++ b/src/angle/kneeAngleUtil.cpp
@@ -23,14 +23,14 @@
#include "opencv/cv.h"
#include "opencv/highgui.h"
-#include <opencv/cxcore.h>
+//#include <opencv/cxcore.h>
#include "stdio.h"
#include "math.h"
-#include<iostream>
-#include<fstream>
-#include<vector>
+//#include<iostream>
+//#include<fstream>
+//#include<vector>
#include <string>
-using namespace std;
+//using namespace std;
CvPoint findMiddle(CvPoint pt1, CvPoint pt2)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]