chronojump r425 - trunk/src/angle
- From: xaviblas svn gnome org
- To: svn-commits-list gnome org
- Subject: chronojump r425 - trunk/src/angle
- Date: Mon, 3 Nov 2008 17:24:17 +0000 (UTC)
Author: xaviblas
Date: Mon Nov 3 17:24:17 2008
New Revision: 425
URL: http://svn.gnome.org/viewvc/chronojump?rev=425&view=rev
Log:
kneeAngle 1.5.1
-working on opencv1.1 and ubuntu 8.10 (Intrepid)
-zoom done
-threshold can be modified manually always
-can jump forward and backward
-on skin, at start or after forward or jump, ask if points are ok
-forward, jump is possible also when a skin marker failed
-code lot cleaner
-code of kneeabduction done
Modified:
trunk/src/angle/kneeAngle.cpp
trunk/src/angle/kneeAngleFunctions.cpp
trunk/src/angle/kneeAngleUtil.cpp
Modified: trunk/src/angle/kneeAngle.cpp
==============================================================================
--- trunk/src/angle/kneeAngle.cpp (original)
+++ trunk/src/angle/kneeAngle.cpp Mon Nov 3 17:24:17 2008
@@ -23,7 +23,7 @@
* Xavier de Blas
* xaviblas gmail com
*
- * version: 1.4 (Oct, 28, 2008)
+ * version: 1.5.1 (Nov, 3, 2008)
*
*/
@@ -86,10 +86,14 @@
*
* g++ -lcv -lcxcore -lhighgui -L(path to opencv library) kneeAngle.cpp -o kneeAngle
*
- * for example
+ * for example:
*
+ * Ubuntu Hoary (8.04) with opencv 1.0
* g++ -lcv -lcxcore -lhighgui -L/usr/local/lib kneeAngle.cpp -o kneeAngle
*
+ * Ubuntu Intrepid (8.10) with opencv 1.1
+ * g++ `pkg-config --cflags opencv` kneeAngle.cpp -o kneeAngle `pkg-config --libs opencv`
+ *
* command to run the file
* ./kneeAngle "path to video file"
*
@@ -118,10 +122,13 @@
using namespace std;
+
+int menu(void);
+
//config variables
bool showContour = true;
bool debug = false;
-int playDelay = 5; //milliseconds between photogrammes wen playing. Used as a waitkey.
+int playDelay = 10; //milliseconds between photogrammes wen playing. Used as a waitkey.
//not put values lower than 5 or the enter when executing will be the first pause
//eg: 5 (fast) 1000 (one second each photogramme)
//int playDelayFoundAngle = 150; //as above, but used when angle is found.
@@ -144,14 +151,10 @@
bool showStickTheLinesBetweenSamePoints = true;
bool showStickTheLinesBetweenDifferentPoints = true;
bool showStickOnlyStartMinEnd = true;
-
bool mixStickWithMinAngleWindow = true;
-//if true, don't analyse the pants angle, only the validation points on black pants
-bool onlyValidationBlack = false;
-
-bool onlyValidationSkin = false;
-
+int startAt = 1;
+enum { blackAndMarkers = 0, blackOnlyMarkers = 1, skinOnlyMarkers = 2 };
int main(int argc,char **argv)
{
@@ -161,33 +164,22 @@
exit(1);
}
- //printf("argc: %d\n",argc);
- int startAt = -1;
- if(argc >= 3)
- startAt = atoi(argv[2]);
- if(argc == 4 && *argv[3] == 'b') {
- onlyValidationBlack = true;
- printf("only validation black!!\n");
- }
- if(argc == 4 && *argv[3] == 's') {
- onlyValidationSkin = true;
- printf("only validation skin!!\n");
- }
-
CvCapture* capture = NULL;
capture = cvCaptureFromAVI(argv[1]);
if(!capture)
{
exit(0);
}
-
//int framesNumber = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
//printf("--%d--\n", framesNumber);
-
+
+
+ int programMode = menu();
+
+ /* initialization variables */
IplImage *frame=0,*frame_copy=0,*gray=0,*segmented=0,*edge=0,*temp=0,*output=0;
IplImage *segmentedValidationHoles=0;
IplImage *foundHoles=0;
- //IplImage *foundHolesContour=0;
IplImage *result=0;
IplImage *resultStick=0;
int minwidth = 0;
@@ -196,17 +188,20 @@
bool foundAngleOneTime = false; //found angle at least one time on the video
double knee2Hip,knee2Toe,hip2Toe;
- double theta, thetaHoles;
+ double thetaExpected, thetaMarked;
string text,angle;
- double minTheta = 360;
- double minThetaHoles = 360;
+ double minThetaExpected = 360;
+ double minThetaMarked = 360;
char buffer[15];
- cvNamedWindow("result",1);
-// cvNamedWindow("gray",1);//meu
- cvNamedWindow("holes",1); //meu
-// cvNamedWindow("foundHoles",1); //meu
-// cvNamedWindow("output",1);
+ if(programMode == skinOnlyMarkers)
+ cvNamedWindow("skinOutput",1);
+ else {
+ cvNamedWindow("holes",1);
+ cvNamedWindow("result",1);
+ }
+
+
int kneePointWidth = -1;
int toePointWidth = -1;
@@ -223,7 +218,6 @@
double fontSize = .4;
cvInitFont(&font, CV_FONT_HERSHEY_COMPLEX, fontSize, fontSize, 0.0, 1, fontLineType);
- char key;
bool shouldEnd = false;
//stick storage
@@ -232,8 +226,8 @@
CvSeq* kneeSeq = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), stickStorage );
CvSeq* toeSeq = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), stickStorage );
- if(! onlyValidationBlack && ! onlyValidationSkin) {
- sprintf(label, " fps a_black a_holes [ diff diff(%)] kneeDif a_supD a_infD");
+ if(programMode == blackAndMarkers) {
+ sprintf(label, " fps a_black a_holes [ diff diff(%%)] kneeDif a_supD a_infD");
printf("%s\n" ,label);
}
@@ -251,22 +245,36 @@
int forwardSuperSpeed = 200;
int forwardCount = 0;
- CvPoint hipHolesPoint = pointToZero();
- CvPoint kneeHolesPoint = pointToZero();
- CvPoint toeHolesPoint = pointToZero();
+ CvPoint hipMarked = pointToZero();
+ CvPoint kneeMarked = pointToZero();
+ CvPoint toeMarked = pointToZero();
CvPoint hipOld = pointToZero();
CvPoint kneeOld = pointToZero();
CvPoint toeOld = pointToZero();
- int legHolesDist = 0;
- int legHolesDistMax = 0;
+ int upLegMarkedDist = 0;
+ int upLegMarkedDistMax = 0;
+ int downLegMarkedDist = 0;
+ int downLegMarkedDistMax = 0;
+
+ int threshold;
+ int thresholdMax = 255;
+ int thresholdInc = 1;
+
+ int key;
+ bool jumpedFrames = false;
+ bool jumping = false;
- int brightness = -1;
while(!shouldEnd)
{
framesCount ++;
+ /*
+ * 1
+ * GET FRAME AND FLOW CONTROL
+ */
+
frame = cvQueryFrame(capture);
if(!frame)
break;
@@ -292,6 +300,19 @@
toeOld = pointToZero();
}
}
+ if(jumping) {
+ hipOld = pointToZero();
+ kneeOld = pointToZero();
+ toeOld = pointToZero();
+ jumping = false;
+ }
+
+
+ /*
+ * 2
+ * CREATE IMAGES
+ */
+
if( !frame_copy )
frame_copy = cvCreateImage( cvSize(frame->width,frame->height),IPL_DEPTH_8U, frame->nChannels );
@@ -301,170 +322,252 @@
else
cvFlip( frame, frame_copy, 0 );
+
if(!gray)
{
gray = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1);
segmented = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1);
segmentedValidationHoles = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1); //meu
foundHoles = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,3); //meu
- //foundHolesContour = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1); //meu
edge = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1);
temp = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1);
output = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1);
result = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,3);
resultStick = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,3);
+
+ if(programMode == skinOnlyMarkers)
+ threshold = 150;
+ else {
+ cvCvtColor(frame_copy,gray,CV_BGR2GRAY);
+ threshold = calculateThresholdStart(gray);
+ }
}
cvSmooth(frame_copy,frame_copy,2,5,5);
cvCvtColor(frame_copy,gray,CV_BGR2GRAY);
+ CvRect maxrect;
+
- // detect brightness
- if(brightness == -1) {
- brightness = calculateBrightness(gray);
- printf("brightness: %d\n", brightness);
- }
+ /*
+ * 3
+ * FIND THREE MARKER POINTS
+ */
- //created image like the contour but with holes and more (stores on segmentedValidationHoles)
- //recommended 25,255
- //high threshold (40-60) detects more black things (useful to not confuse a hole when is close to the border)
- //low threshold (5-10) detects less black things
- //if the image is bright, a hight threshold is perfect to nice detect the shapes without detecting shadows
- //int threshold = 35;
- //put threshold min depending on brightnesss
- //eg: nora: brightness 85 -> threshold 30
- //eg: 44_lluis_puerta_salt6_m.MOV: brightness 73 -> threshold 10
-
- //adjust better, because:
- //12_carles_tejedor_salt3_m.MOV
- //is bright:0, but if put thresh to 1 then detects bad. and to 10 is ok
- //
- //on the other side, 2_roger_miralles_salt3_m.MOV
- //is really dark and it needs a thresh of 1 to work
- //
- //also it could be nice to have a thresh that detects three objects
- //another option, could be to have the thresh 10 as really minimum and darker images are unsupported!
- int threshold;
- int briMax = 85;
- int briMin = 65;
-// int briZero = 50;
- int thresMax = 30;
- int thresMin = 10;
- if(brightness >= briMax)
- threshold = thresMax;
-// else if(brightness <= briZero)
-// threshold = 10;
- else if(brightness <= briMin)
- threshold = thresMin;
- else
- threshold = brightness - briMin + thresMin;
- int thresholdMax = 255;
+ if(programMode == skinOnlyMarkers)
+ {
+ cvCvtColor(frame_copy,output,CV_BGR2GRAY);
+ cvThreshold(gray, output, threshold, thresholdMax,CV_THRESH_BINARY_INV);
+
+ /*
+ hipOld = hipMarked;
+ kneeOld = kneeMarked;
+ toeOld = toeMarked;
+ */
+
+ CvSeq* seqHolesEnd = findHolesSkin(output, frame_copy, hipMarked, kneeMarked, toeMarked);
- CvRect maxrect;
- int thresholdInc = 1;
+ hipMarked = *CV_GET_SEQ_ELEM( CvPoint, seqHolesEnd, 0);
+ kneeMarked = *CV_GET_SEQ_ELEM( CvPoint, seqHolesEnd, 1 );
+ toeMarked = *CV_GET_SEQ_ELEM( CvPoint, seqHolesEnd, 2 );
+
+ cvCircle(frame_copy,hipMarked,2, CV_RGB(128,128,128),1,8,0);
+ cvCircle(frame_copy,kneeMarked,2, CV_RGB(128,128,128),1,8,0);
+ cvCircle(frame_copy,toeMarked,2, CV_RGB(128,128,128),1,8,0);
- //at first photogram if onlyValidationSkin, ask user for the points
- //don't do like this, go to another method and have the flow there
- //also the same for onlyValidationBlack
- if(onlyValidationSkin) {
- if(hipSkin.x == 0 ) {
+ //if frame before nothing was detected (maybe first frame or after a forward or jump
+ //OR a point in this frame was not detected
+ if(
+ (pointIsNull(hipOld) && pointIsNull(kneeOld) && pointIsNull(toeOld)) ||
+ (pointIsNull(hipMarked) || pointIsNull(kneeMarked) || pointIsNull(toeMarked)) )
+ {
+ hipMouse = hipMarked;
+ kneeMouse = kneeMarked;
+ toeMouse = toeMarked;
+
cvNamedWindow( "toClick", 1 );
- cvShowImage("toClick", gray);
+ cvShowImage("toClick", frame_copy);
+ mouseCanMark = true;
cvSetMouseCallback( "toClick", on_mouse, 0 );
- printf("Please, mark hip point, then knee, then toe, and finally press any key\n");
- int c = cvWaitKey(0);
- printf("hip: (%d,%d), knee: (%d,%d), toe:(%d,%d)\n",
- hipSkin.x, hipSkin.y, kneeSkin.x, kneeSkin.y, toeSkin.x, toeSkin.y);
+
+ cvCvtColor(frame_copy,output,CV_BGR2GRAY);
+ cvThreshold(gray, output, threshold, thresholdMax,CV_THRESH_BINARY_INV);
+ cvShowImage("skinOutput", output);
+
+ printf("\nFrame: %d H(%d,%d), K(%d,%d), T(%d,%d)\n", framesCount, hipMarked.x, hipMarked.y,
+ kneeMarked.x, kneeMarked.y, toeMarked.x, toeMarked.y);
+
+
+ if(pointIsNull(hipMarked) || pointIsNull(kneeMarked) || pointIsNull(toeMarked)) {
+ printf("** Please mark:");
+ if(pointIsNull(hipMarked))
+ printf(" HIP ");
+ if(pointIsNull(kneeMarked))
+ printf(" KNEE ");
+ if(pointIsNull(toeMarked))
+ printf(" TOE ");
+ printf("on 'toClick' window **\n");
+ }
+
+ printf("Press 'p' when done.\n");
+ printf("Optionally:\n");
+ printf("\tReMark hip 'h', knee 'k', toe 't'\n");
+ printf("\tChange threshold: %d ('+' increase, '-' decrease)\n", threshold);
+ printf("\tOthers: Zoom 'z', forward 'f', Forward 'F', jump 'j', quit program 'q'\n\n");
- cvNamedWindow( "HolesBri", 1 );
- int thresholdSkin = 150;
bool done = false;
+ IplImage* imgZoom;
do {
- cvThreshold(gray,segmentedValidationHoles, thresholdSkin, thresholdMax,CV_THRESH_BINARY_INV);
- cvShowImage("HolesBri", segmentedValidationHoles);
- printf("threshold: %d ('+' increase, '-' decrease, 'q' done)\n", thresholdSkin);
+ cvCvtColor(frame_copy,output,CV_BGR2GRAY);
+ cvThreshold(gray, output, threshold, thresholdMax,CV_THRESH_BINARY_INV);
+
key = (char) cvWaitKey(0);
- if(key == 'q' || key == 'Q' )
+ if(key == 'p' )
done = true;
- else if(key == '+')
- thresholdSkin ++;
+ else if(key == 'q') {
+ done = true;
+ shouldEnd = true;
+ } else if(key == 'z') {
+ if(zoomed) {
+ cvDestroyWindow("zoomed");
+ cvReleaseImage(&imgZoom);
+ zoomed = false;
+ cvSetMouseCallback( "toClick", on_mouse, 0 );
+ } else {
+ imgZoom = zoomImage(frame_copy);
+ cvNamedWindow( "zoomed", 1 );
+ cvShowImage("zoomed", imgZoom);
+ zoomed = true;
+ cvSetMouseCallback( "zoomed", on_mouse, 0 );
+ }
+ }
+ else if(key == 'h') {
+ forceMouseHip = true;
+ printf("Remark Hip: ");
+ } else if(key == 'k') {
+ forceMouseKnee = true;
+ printf("Remark Knee: ");
+ } else if(key == 't') {
+ forceMouseToe = true;
+ printf("Remark Toe: ");
+ } else if(key == '+')
+ threshold ++;
else if(key == '-')
- thresholdSkin --;
- } while(! done);
-
- //backward doesn't work:
- //cvSetCaptureProperty( capture, CV_CAP_PROP_POS_FRAMES, 600.0 );
- //cvSetCaptureProperty( capture, CV_CAP_PROP_POS_AVI_RATIO, .7 );
- //http://opencv.willowgarage.com/wiki/HighGui
+ threshold --;
+ else if (key == 'f') {// 'FORWARD'
+ forward = true;
+ printf("forwarding ...\n");
+ done = true;
+ } else if (key == 'F') { // 'FORWARD SUPER'
+ forwardSuper = true;
+ done = true;
+ printf("super forwarding ...\n");
+ }
+ else if (key == 'j' || key == 'J') {
+ //jump frames
+ printf("current frame: %d. Jump to: ", framesCount);
+ int jump;
+ scanf("%d", &jump);
+
+ //works with opencv1.1!!
+ //now we can go back and forth
+ cvSetCaptureProperty( capture, CV_CAP_PROP_POS_FRAMES, jump-1 );
+
+ framesCount = jump;
+ hipOld = pointToZero();
+ kneeOld = pointToZero();
+ toeOld = pointToZero();
+
+ //when jumper is extending legs after maximal flexion, jump ends
+ //this jumped makes it didn't work, avoiding ending a jump
+ //when we have gone ('j') from a maximal flexion to the 1st frame again (extension)
+ jumpedFrames = true;
+ printf("jumping ...\n");
+ }
+
+ cvThreshold(gray, output, threshold, thresholdMax,CV_THRESH_BINARY_INV);
+ sprintf(label, "frame: %d", framesCount);
+ cvPutText(output, label, cvPoint(10,frame->height-40),&font,CV_RGB(0,0,0));
- } else {
- cvThreshold(gray,segmentedValidationHoles, 150, thresholdMax,CV_THRESH_BINARY_INV);
- cvCircle(segmentedValidationHoles,hipSkin,2, CV_RGB(255,0,0),1,8,0);
- cvCircle(segmentedValidationHoles,kneeSkin,2, CV_RGB(255,0,0),1,8,0);
- cvCircle(segmentedValidationHoles,toeSkin,2, CV_RGB(255,0,0),1,8,0);
- cvShowImage("HolesBri", segmentedValidationHoles);
- cvWaitKey(10);
- }
+ sprintf(label, "threshold: %d", threshold);
+ cvPutText(output, label, cvPoint(10,frame->height-20),&font,CV_RGB(0,0,0));
- continue;
- //exit(0);
- }
-
- do {
- cvThreshold(gray,segmentedValidationHoles, threshold, thresholdMax,CV_THRESH_BINARY_INV);
+ cvShowImage("skinOutput", output);
+ } while(! done);
+
+ hipMarked = hipMouse;
+ kneeMarked = kneeMouse;
+ toeMarked = toeMouse;
+
+ if(zoomed) {
+ cvDestroyWindow("zoomed");
+ cvReleaseImage(&imgZoom);
+ zoomed = false;
+ }
+ mouseCanMark = false;
+ }
+
+ }
+ else {
+ do {
+ cvThreshold(gray,segmentedValidationHoles, threshold, thresholdMax,CV_THRESH_BINARY_INV);
- //create the largest contour image (stored on temp)
- cvThreshold(gray,segmented,threshold,thresholdMax,CV_THRESH_BINARY_INV);
- maxrect = findLargestContour(segmented, output, showContour);
+ //create the largest contour image (stored on temp)
+ cvThreshold(gray,segmented,threshold,thresholdMax,CV_THRESH_BINARY_INV);
+ maxrect = findLargestContour(segmented, output, showContour);
+
+ //search in output all the black places (pants) and
+ //see if there's a hole in that pixel on segmentedValidationHoles
+ //if(programMode == blackAndMarkers || programMode == blackOnlyMarkers) {
+ CvSeq* seqHolesEnd = findHoles(
+ output, segmentedValidationHoles, foundHoles, frame_copy,
+ maxrect, hipOld, kneeOld, toeOld);
+
+ hipMarked = *CV_GET_SEQ_ELEM( CvPoint, seqHolesEnd, 0);
+ kneeMarked = *CV_GET_SEQ_ELEM( CvPoint, seqHolesEnd, 1 );
+ toeMarked = *CV_GET_SEQ_ELEM( CvPoint, seqHolesEnd, 2 );
+ //}
+ threshold += thresholdInc;
+ } while(
+ (pointIsNull(hipMarked) || pointIsNull(kneeMarked) || pointIsNull(toeMarked))
+ && threshold < 100);
- //search in output all the black places (pants) and
- //see if there's a hole in that pixel on segmentedValidationHoles
- if(onlyValidationSkin)
- ;
- else {
- CvSeq* seqHolesEnd = findHoles(
- output, segmentedValidationHoles, foundHoles, frame_copy,
- maxrect, hipOld, kneeOld, toeOld);
+ threshold -= thresholdInc;
+ }
- hipHolesPoint = *CV_GET_SEQ_ELEM( CvPoint, seqHolesEnd, 0);
- kneeHolesPoint = *CV_GET_SEQ_ELEM( CvPoint, seqHolesEnd, 1 );
- toeHolesPoint = *CV_GET_SEQ_ELEM( CvPoint, seqHolesEnd, 2 );
- }
- threshold += thresholdInc;
- } while(
- (pointIsNull(hipHolesPoint) || pointIsNull(kneeHolesPoint) || pointIsNull(toeHolesPoint))
- && threshold < 100);
-
- threshold -= thresholdInc;
- hipOld = hipHolesPoint;
- kneeOld = kneeHolesPoint;
- toeOld = toeHolesPoint;
-
-
- CvPoint hipPointBack;
- CvPoint hipPoint;
- CvPoint kneePointBack;
- CvPoint kneePointFront;
- CvPoint kneePoint;
- CvPoint toePoint;
+ hipOld = hipMarked;
+ kneeOld = kneeMarked;
+ toeOld = toeMarked;
+
+
+ CvPoint hipExpected;
+ CvPoint kneeExpected;
+ CvPoint toeExpected;
//int area;
+ /*
+ * 4
+ * FIND POINTS ON BLACKANDMARKERS
+ */
+
+ if(programMode == blackAndMarkers) {
+ CvPoint hipPointBack;
+ CvPoint kneePointBack;
+ CvPoint kneePointFront;
- if( ! onlyValidationBlack) {
hipPointBack = findHipPoint(output,maxrect);
//provisionally ubicate hipPoint at horizontal 1/2
- CvPoint hipPoint;
- hipPoint.x = hipPointBack.x + (findWidth(output, hipPointBack, true) /2);
- hipPoint.y = hipPointBack.y;
+ hipExpected.x = hipPointBack.x + (findWidth(output, hipPointBack, true) /2);
+ hipExpected.y = hipPointBack.y;
//knee
kneePointFront = findKneePointFront(output,maxrect,hipPointBack.y);
kneePointBack = findKneePointBack(output,maxrect,hipPointBack.y, kneePointFront.x); //hueco popliteo
//toe
- CvPoint toePoint = findToePoint(output,maxrect,kneePointFront.x,kneePointFront.y);
+ CvPoint toeExpected = findToePoint(output,maxrect,kneePointFront.x,kneePointFront.y);
foundAngle = false;
@@ -473,9 +576,9 @@
else {
if((double)(kneePointFront.x- hipPointBack.x) > 1.15*minwidth
&&
- upperSimilarThanLower(hipPoint, kneePointFront, toePoint)
- && !pointIsNull(hipHolesPoint) && !pointIsNull(kneeHolesPoint) &&
- !pointIsNull(toeHolesPoint)
+ upperSimilarThanLower(hipExpected, kneePointFront, toeExpected)
+ && !pointIsNull(hipMarked) && !pointIsNull(kneeMarked) &&
+ !pointIsNull(toeMarked)
)
/* get lower this 1.25 because now we use mid leg to solve the hand problem and width is lower*/
/*1.25 again, because we use hip y again*/
@@ -492,12 +595,12 @@
if(kneePointWidth == -1)
kneePointWidth = findWidth(output, kneePointFront, false);
- kneePoint = kneePointInNearMiddleOfFrontAndBack(
+ kneeExpected = kneePointInNearMiddleOfFrontAndBack(
kneePointBack, kneePointFront, kneePointWidth, frame_copy);
cvCircle(frame_copy,kneePointBack,2, CV_RGB(128,128,128),1,8,0);
cvCircle(frame_copy,kneePointFront,2, CV_RGB(128,128,128),1,8,0);
cvLine(frame_copy,kneePointFront,kneePointBack,CV_RGB(128,128,128),1,1);
- cvCircle(frame_copy,kneePoint,3, CV_RGB(255,255,0),1,8,0);
+ cvCircle(frame_copy,kneeExpected,3, CV_RGB(255,255,0),1,8,0);
// ------------ toe stuff ----------
@@ -509,53 +612,53 @@
*/
if(toePointWidth == -1)
- toePointWidth = findWidth(output, toePoint, false);
- cvCircle(frame_copy,toePoint,2, CV_RGB(128,128,128),1,8,0);
+ toePointWidth = findWidth(output, toeExpected, false);
+ cvCircle(frame_copy,toeExpected,2, CV_RGB(128,128,128),1,8,0);
- theta = findAngle(hipPoint, toePoint, kneePoint);
+ thetaExpected = findAngle2D(hipExpected, toeExpected, kneeExpected);
- //fix toepoint.x at the 1/2 of the toe width
+ //fix toeExpected.x at the 1/2 of the toe width
//depending on kneeAngle
- toePoint.x = fixToePointX(toePoint.x, toePointWidth, theta);
- cvCircle(frame_copy,toePoint,3, CV_RGB(255,0,0),1,8,0);
+ toeExpected.x = fixToePointX(toeExpected.x, toePointWidth, thetaExpected);
+ cvCircle(frame_copy,toeExpected,3, CV_RGB(255,0,0),1,8,0);
// ------------ hip stuff ----------
- //fix hipPoint ...
+ //fix hipExpected ...
cvCircle(frame_copy,hipPointBack,2, CV_RGB(128,128,128),1,8,0);
//... find at 3/2 of hip (surely under the hand) ...
- //theta = findAngle(hipPoint, toePoint, kneePoint);
- hipPoint = fixHipPoint1(output, hipPointBack.y, kneePoint, theta);
- cvCircle(frame_copy,hipPoint,2, CV_RGB(128,128,128),1,8,0);
+ //thetaExpected = findAngle2D(hipExpected, toeExpected, kneeExpected);
+ hipExpected = fixHipPoint1(output, hipPointBack.y, kneeExpected, thetaExpected);
+ cvCircle(frame_copy,hipExpected,2, CV_RGB(128,128,128),1,8,0);
//... cross first hippoint with the knee-hippoint line to find real hippoint
- hipPoint = fixHipPoint2(output, hipPointBack.y, kneePoint, hipPoint);
- cvCircle(frame_copy,hipPoint,3, CV_RGB(255,0,0),1,8,0);
+ hipExpected = fixHipPoint2(output, hipPointBack.y, kneeExpected, hipExpected);
+ cvCircle(frame_copy,hipExpected,3, CV_RGB(255,0,0),1,8,0);
// ------------ flexion angle ----------
//find flexion angle
- theta = findAngle(hipPoint, toePoint, kneePoint);
- //double thetaBack = findAngle(hipPoint, toePoint, kneePointBack);
+ thetaExpected = findAngle2D(hipExpected, toeExpected, kneeExpected);
+ //double thetaBack = findAngle2D(hipExpected, toeExpected, kneePointBack);
//draw 2 main lines
- cvLine(frame_copy,kneePoint,hipPoint,CV_RGB(255,0,0),1,1);
- cvLine(frame_copy,kneePoint,toePoint,CV_RGB(255,0,0),1,1);
+ cvLine(frame_copy,kneeExpected,hipExpected,CV_RGB(255,0,0),1,1);
+ cvLine(frame_copy,kneeExpected,toeExpected,CV_RGB(255,0,0),1,1);
- cvSeqPush( hipSeq, &hipPoint );
- cvSeqPush( kneeSeq, &kneePoint );
- cvSeqPush( toeSeq, &toePoint );
+ cvSeqPush( hipSeq, &hipExpected );
+ cvSeqPush( kneeSeq, &kneeExpected );
+ cvSeqPush( toeSeq, &toeExpected );
//find total area
//area = findTotalArea(gray, maxrect);
- if(theta < minTheta)
+ if(thetaExpected < minThetaExpected)
{
- minTheta = theta;
+ minThetaExpected = thetaExpected;
cvCopy(frame_copy,result);
lowestAngleFrame = framesCount;
}
@@ -569,137 +672,236 @@
}
- if(pointIsNull(hipHolesPoint) || pointIsNull(kneeHolesPoint) || pointIsNull(toeHolesPoint))
- thetaHoles = -1;
+ /*
+ * 5
+ * PRINT MARKERS RELATED INFO AND DO CALCULATIONS LIKE ANGLE
+ */
+
+
+ if(pointIsNull(hipMarked) || pointIsNull(kneeMarked) || pointIsNull(toeMarked))
+ thetaMarked = -1;
else {
- thetaHoles = findAngle(hipHolesPoint, toeHolesPoint, kneeHolesPoint);
- if(thetaHoles < minThetaHoles)
- minThetaHoles = thetaHoles;
+ thetaMarked = findAngle2D(hipMarked, toeMarked, kneeMarked);
+ if(thetaMarked < minThetaMarked)
+ minThetaMarked = thetaMarked;
- cvRectangle(frame_copy,
- cvPoint(maxrect.x,maxrect.y),
- cvPoint(maxrect.x + maxrect.width, maxrect.y + maxrect.height),
- CV_RGB(255,0,0),1,1);
+ if(programMode == blackAndMarkers)
+ cvRectangle(frame_copy,
+ cvPoint(maxrect.x,maxrect.y),
+ cvPoint(maxrect.x + maxrect.width, maxrect.y + maxrect.height),
+ CV_RGB(255,0,0),1,1);
+
+ /*
//print frame variation of distances of leg
//soon find abduction, and then real flexion angle
- legHolesDist = getDistance(hipHolesPoint, kneeHolesPoint) + getDistance(toeHolesPoint, kneeHolesPoint);
- if(legHolesDist > legHolesDistMax)
- legHolesDistMax = legHolesDist;
-
- sprintf(label, "legSize: %d(%.1f\%)", legHolesDist, relError(legHolesDistMax, legHolesDist));
- cvPutText(frame_copy, label, cvPoint(frame->width-150, frame->height-20),&font,CV_RGB(255,255,255));
-
-
- sprintf(label, "frame: %d", framesCount);
- cvPutText(frame_copy, label, cvPoint(10,frame->height-80),&font,CV_RGB(255,255,255));
+ */
+ upLegMarkedDist = getDistance(hipMarked, kneeMarked);
+ if(upLegMarkedDist > upLegMarkedDistMax)
+ upLegMarkedDistMax = upLegMarkedDist;
+ downLegMarkedDist = getDistance(toeMarked, kneeMarked);
+ if(downLegMarkedDist > downLegMarkedDistMax)
+ downLegMarkedDistMax = downLegMarkedDist;
+
+ CvPoint HT;
+ HT.y = kneeMarked.y;
+ double verticalKVersusHT = (kneeMarked.y - toeMarked.y) / (double) (hipMarked.y-toeMarked.y) ;
+ HT.x = ((hipMarked.x - toeMarked.x) * verticalKVersusHT ) + toeMarked.x;
+
+ double kneeZetaSide = sqrt( pow(upLegMarkedDistMax,2) - pow(upLegMarkedDist,2) );
+ double htKneeMarked = getDistance (HT, kneeMarked);
+
+ double thetaABD = (180.0/M_PI)*atan( kneeZetaSide / (double) htKneeMarked );
+
+ double thetaRealFlex = findAngle3D(hipMarked, toeMarked, kneeMarked, 0, 0, -kneeZetaSide);
+
+
+ if(programMode == skinOnlyMarkers) {
+ printOnScreen(output, font, CV_RGB(0,0,0),
+ upLegMarkedDist + downLegMarkedDist,
+ relError(upLegMarkedDistMax + downLegMarkedDistMax, upLegMarkedDist + downLegMarkedDist),
+ framesCount, threshold, thetaMarked, minThetaMarked);
+ cvShowImage("toClick", frame_copy);
+ cvShowImage("skinOutput",output);
+ }
- //print holes angle detection data
- sprintf(label, "threshold: %d", threshold);
- cvPutText(frame_copy, label, cvPoint(10,frame->height-60),&font,CV_RGB(255,255,255));
- sprintf(label, "H angle: %.2f", thetaHoles);
- cvPutText(frame_copy, label, cvPoint(10,frame->height-40),&font,CV_RGB(255,255,255));
- sprintf(label, "min H angle: %.2f", minThetaHoles);
- cvPutText(frame_copy, label, cvPoint(10,frame->height-20),&font,CV_RGB(255,255,255));
+ printOnScreen(frame_copy, font, CV_RGB(255,255,255),
+ upLegMarkedDist + downLegMarkedDist,
+ relError(upLegMarkedDistMax + downLegMarkedDistMax, upLegMarkedDist + downLegMarkedDist),
+ framesCount, threshold, thetaMarked, minThetaMarked);
+
+ printOnScreenRight(frame_copy, font, CV_RGB(255,255,255),
+ upLegMarkedDist, downLegMarkedDist,
+ upLegMarkedDistMax, downLegMarkedDistMax,
+ kneeZetaSide, htKneeMarked,
+ thetaABD, thetaRealFlex);
- if(foundAngle) {
+ if(programMode == blackAndMarkers && foundAngle) {
+ /*
//print data
- double thetaSup = findAngle(hipPoint, cvPoint(0,kneePoint.y), kneePoint);
- double thetaHolesSup = findAngle(hipHolesPoint, cvPoint(0, kneeHolesPoint.y), kneeHolesPoint);
+ double thetaSup = findAngle2D(hipExpected, cvPoint(0,kneeExpected.y), kneeExpected);
+ double thetaMarkedSup = findAngle2D(hipMarked, cvPoint(0, kneeMarked.y), kneeMarked);
- double thetaInf = findAngle(cvPoint(0,kneePoint.y), toePoint, kneePoint);
- double thetaHolesInf = findAngle(cvPoint(0,kneeHolesPoint.y), toeHolesPoint, kneeHolesPoint);
+ double thetaInf = findAngle2D(cvPoint(0,kneeExpected.y), toeExpected, kneeExpected);
+ double thetaMarkedInf = findAngle2D(cvPoint(0,kneeMarked.y), toeMarked, kneeMarked);
- printf("%7d %7.2f %7.2f [%7.2f %7.2f] %7.2f %7.2f %7.2f [%7.2f %7.2f] [%7.2f] [%7.2f]\n", framesCount, theta, thetaHoles,
- thetaHoles-theta, relError(theta, thetaHoles),
- getDistance(kneePoint, kneeHolesPoint),
- thetaSup-thetaHolesSup, thetaInf-thetaHolesInf
- , getDistance(kneeHolesPoint, hipHolesPoint), getDistance(kneePoint, hipPoint)
- , getDistance(kneePoint, hipPointBack)
- , getDistance(kneePointBack, hipPointBack)
- //, area
- );
-
- avgThetaDiff += abs(thetaHoles-theta);
- avgThetaDiffPercent += abs(relError(theta, thetaHoles));
- avgKneeDistance += getDistance(kneePoint, kneeHolesPoint);
+ printf("%7d %7.2f %7.2f [%7.2f %7.2f] %7.2f %7.2f %7.2f [%7.2f %7.2f] [%7.2f] [%7.2f]\n", framesCount, thetaExpected, thetaMarked,
+ thetaMarked-thetaExpected, relError(thetaExpected, thetaMarked),
+ getDistance(kneeExpected, kneeMarked),
+ thetaSup-thetaMarkedSup, thetaInf-thetaMarkedInf
+ , getDistance(kneeMarked, hipMarked), getDistance(kneeExpected, hipExpected)
+ , getDistance(kneeExpected, hipPointBack)
+ , getDistance(kneePointBack, hipPointBack)
+ //, area
+ );
+
+ avgThetaDiff += abs(thetaMarked-thetaExpected);
+ avgThetaDiffPercent += abs(relError(thetaExpected, thetaMarked));
+ avgKneeDistance += getDistance(kneePoint, kneeMarked);
+ */
framesDetected ++;
}
- cvShowImage("result",frame_copy);
+
+ if(programMode == blackAndMarkers || programMode == blackOnlyMarkers)
+ cvShowImage("result",frame_copy);
//Finds the minimum angle between Hip to Knee line and Knee to Toe line
- if(thetaHoles == minThetaHoles) {
- if(onlyValidationBlack) {
+ if(thetaMarked == minThetaMarked) {
+// if(programMode == blackOnlyMarkers || programMode == skinOnlyMarkers) {
/*
* if only process validation points, then minimum angle should be obtained
* by the validation points
*/
-
+
cvCopy(frame_copy,result);
//lowestAngleFrame = hipSeq->total -1;
lowestAngleFrame = framesCount;
- }
+// }
}
//exit if we are going up and soon jumping.
//toe will be lost
- //detected if minThetaHoles is littler than thetaHoles, when thetaHoles is big
- if(thetaHoles > 140 && minThetaHoles +10 < thetaHoles)
+ //detected if minThetaMarked is littler than thetaMarked, when thetaMarked is big
+ if(thetaMarked > 140 &&
+ minThetaMarked +10 < thetaMarked &&
+ ! jumpedFrames)
+ {
+ printf("\ntm: %f, mtm: %f, frame: %d\n", thetaMarked, minThetaMarked, framesCount);
shouldEnd = true;
+ }
}
- /* wait key for pause
- * if ESC, q, Q then exit
+ /*
+ * 6
+ * WAIT FOR KEYS
*/
int myDelay = playDelay;
+ //if(programMode != blackAndMarkers || foundAngle)
if(foundAngle)
myDelay = playDelayFoundAngle;
key = (char) cvWaitKey(myDelay);
- if(key == 27 || key == 'q' || key == 'Q' ) // 'ESC'
+ if(key == 27 || key == 'q') // 'ESC'
shouldEnd = true;
- else if(key == 'f') // 'FORWARD'
+ else if (key == '+')
+ threshold += thresholdInc;
+ else if (key == '-')
+ threshold -= thresholdInc;
+ else if (key == 'f') {
forward = true;
- else if(key =='F') // 'FORWARD SUPER'
+ printf("forwarding ...\n");
+ } else if (key == 'F') {
forwardSuper = true;
- else if (key >0)
+ printf("super forwarding ...\n");
+ } else if (key == 'j' || key == 'J') {
+ //jump frames
+ printf("current frame: %d. Jump to: ", framesCount);
+ int jump;
+ scanf("%d", &jump);
+
+ //works with opencv1.1!!
+ //now we can go back and forth
+ cvSetCaptureProperty( capture, CV_CAP_PROP_POS_FRAMES, jump-1 );
+
+ framesCount = jump;
+
+ //when jumper is extending legs after maximal flexion, jump ends
+ //this jumped makes it didn't work, avoiding ending a jump
+ //when we have gone ('j') from a maximal flexion to the 1st frame again (extension)
+ jumpedFrames = true;
+
+ //hlps to know when we jumped and we have to initialize hipOld, kneeOld, toOld
+ jumping = true;
+ printf("jumping ...\n");
+ }
+ else if (key == 'p')
{
//if paused, print "pause"
sprintf(label,"Pause");
- cvPutText(frame_copy, label,cvPoint(frame->width -100,25),&font,cvScalar(0,0,255));
- cvShowImage("result",frame_copy);
-
- key = (char) cvWaitKey(0);
- if(key == 27 || key == 'q' || key == 'Q' ) // 'ESC'
- shouldEnd = true;
- }
+ if(programMode == skinOnlyMarkers) {
+ cvPutText(output, label,cvPoint(10, 25),&font,cvScalar(128,128,128));
+ cvShowImage("skinOutput",output);
+ } else {
+ cvPutText(frame_copy, label,cvPoint(10, 25),&font,cvScalar(0,0,255));
+ cvShowImage("result",frame_copy);
+ }
- //cvShowImage("gray",gray);
+ bool done = false;
+ do{
+ key = (char) cvWaitKey(0);
+ if(key == 27 || key == 'q') {
+ shouldEnd = true;
+ done = true;
+ }
+ else if(key =='p') {
+ threshold -= thresholdInc;
+ done = true;
+ }
+ else if(key =='+' || key == '-') {
+ if(key =='+')
+ threshold += thresholdInc;
+ else if(key =='-')
+ threshold -= thresholdInc;
+
+ if(programMode == skinOnlyMarkers) {
+ cvThreshold(gray, output, threshold, thresholdMax,CV_THRESH_BINARY_INV);
+ sprintf(label,"Pause");
+ cvPutText(output, label,cvPoint(10, 25),&font,cvScalar(128,128,128));
+ sprintf(label, "frame: %d", framesCount);
+ cvPutText(output, label, cvPoint(10,frame->height-40),&font,CV_RGB(0,0,0));
+ sprintf(label, "threshold: %d", threshold);
+ cvPutText(output, label, cvPoint(10,frame->height-20),&font,CV_RGB(0,0,0));
+ cvShowImage("skinOutput", output);
+ }
+ else {
+ cvThreshold(gray,segmentedValidationHoles, threshold, thresholdMax,CV_THRESH_BINARY_INV);
+ //create the largest contour image (stored on temp)
+ cvThreshold(gray,segmented,threshold,thresholdMax,CV_THRESH_BINARY_INV);
+ maxrect = findLargestContour(segmented, output, showContour);
- //cvShowImage("segmentedValidationHoles",segmentedValidationHoles);
- double scale = 4;
- IplImage* tempSmall = cvCreateImage( cvSize( cvRound (segmentedValidationHoles->width/scale), cvRound (segmentedValidationHoles->height/scale)), 8, 1 );
- cvResize( segmentedValidationHoles, tempSmall, CV_INTER_LINEAR );
- cvShowImage("holes",tempSmall);
+ updateHolesWin(segmentedValidationHoles);
+ }
+ }
+ } while (! done);
+ }
- //cvShowImage("foundHoles",foundHoles);
- //cvShowImage("output",output);
+ if(programMode == blackAndMarkers || programMode == blackOnlyMarkers) {
+ updateHolesWin(segmentedValidationHoles);
+ }
}
- if(onlyValidationBlack) {
- printf("*** Result ***\nMin angle: %.2f, lowest angle frame: %d\n", minThetaHoles, lowestAngleFrame);
- cvNamedWindow("Minimum Frame",1);
- cvShowImage("Minimum Frame", result);
- cvWaitKey(0);
- }
- else if(foundAngleOneTime) {
+ /*
+ * END OF MAIN LOOP
+ */
+
+ if(programMode == blackAndMarkers && foundAngleOneTime) {
avgThetaDiff = (double) avgThetaDiff / framesDetected;
avgThetaDiffPercent = (double) avgThetaDiffPercent / framesDetected;
@@ -707,6 +909,8 @@
printf("\n[%f %f] %f\n", avgThetaDiff, avgThetaDiffPercent, avgKneeDistance);
+ // do this on R
+ /*
if(showStickThePoints ||
showStickTheLinesBetweenDifferentPoints ||
showStickTheLinesBetweenSamePoints) {
@@ -737,15 +941,25 @@
cvShowImage("Stick Figure", resultStick);
}
}
+ */
+
+ cvNamedWindow("Minimum Frame",1);
+ cvShowImage("Minimum Frame", result);
printf("Minimum Frame\n");
- sprintf(label, "minblack minholes diff diff(%)");
- sprintf(label, "%8.2f %8.2f [%7.2f %7.2f]", minTheta, minThetaHoles,
- minThetaHoles-minTheta, relError(minTheta, minThetaHoles));
+ sprintf(label, "minblack minholes diff diff(%%)");
+ sprintf(label, "%8.2f %8.2f [%7.2f %7.2f]", minThetaExpected, minThetaMarked,
+ minThetaMarked-minThetaExpected, relError(minThetaExpected, minThetaMarked));
printf("%s\n" ,label);
cvWaitKey(0);
}
+ else {
+ printf("*** Result ***\nMin angle: %.2f, lowest angle frame: %d\n", minThetaMarked, lowestAngleFrame);
+ cvNamedWindow("Minimum Frame",1);
+ cvShowImage("Minimum Frame", result);
+ cvWaitKey(0);
+ }
/* show all windows*/
/*
@@ -779,3 +993,58 @@
}
+int menu()
+{
+ /* initial menu */
+ printf( "Use: \n"
+ "\tq - quit the program\n"
+ "\tb - change mode to black long pants and marker validation\n"
+ "\tB - change mode to Black long pants (only markers)\n"
+ "\ts - change mode to Skin (short pants) (only markers)\n"
+ "\tj - Jump at selected frame\n"
+ "\ti - Init the program\n"
+ );
+
+ int key;
+ int programMode = blackAndMarkers;
+ char option;
+
+ bool menuDone = false;
+ do{
+ printf("Current options:\n");
+ if(programMode == blackAndMarkers)
+ printf("\t- Black long pants and marker validation\n");
+ else if(programMode == blackOnlyMarkers)
+ printf("\t- Black long pants (only markers)\n");
+ else
+ printf("\t- Skin (short pants) (only markers)\n");
+ printf("\t- start at frame: %d\n", startAt);
+
+ scanf("%c", &option);
+ switch( option ) {
+ case 'q':
+ printf("Exiting ...\n");
+ menuDone = true;
+ case 'b':
+ programMode = blackAndMarkers;
+ break;
+ case 'B':
+ programMode = blackOnlyMarkers;
+ break;
+ case 's':
+ programMode = skinOnlyMarkers;
+ break;
+ case 'j':
+ printf("Jump at frame: ");
+ scanf("%d", &startAt);
+ break;
+ case 'i':
+ printf("Starting...\n");
+ menuDone = true;
+ break;
+ }
+ } while (! menuDone);
+
+ return programMode;
+}
+
Modified: trunk/src/angle/kneeAngleFunctions.cpp
==============================================================================
--- trunk/src/angle/kneeAngleFunctions.cpp (original)
+++ trunk/src/angle/kneeAngleFunctions.cpp Mon Nov 3 17:24:17 2008
@@ -354,7 +354,8 @@
if(srcdataptrC[x] > 0)
{
if(srcdataptrH[x] == 0) {
- pt.x =x;pt.y=y;
+ pt.x=x;
+ pt.y=y;
//cvCircle(foundHoles,pt,1, CV_RGB(128,128,128),1,8,0);
cvSeqPush( seqPoints, &pt );
@@ -554,6 +555,251 @@
return seqHolesEnd;
}
+/*
+ * 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)
+{
+ CvPoint pt;
+ pt.x =0;pt.y=0;
+
+ CvMat *srcmat,src_stub;
+ srcmat = cvGetMat(imgThresh, &src_stub);
+ uchar *srcdata = srcmat->data.ptr;
+
+ int width = imgThresh->width;
+ int minx = imgThresh->width;
+ int endy = imgThresh->height;
+
+ //stick storage
+ CvMemStorage* storage = cvCreateMemStorage(0);
+
+ CvSeq* seqPoints = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage );
+ CvSeq* seqGroups = cvCreateSeq( 0, sizeof(CvSeq), sizeof(0), storage );
+
+//exit(0); //desp
+ //put all hole points on seqAllHoles
+ for(int y=0;y<endy;y++)
+ {
+ uchar *srcdataptr = srcdata + y*imgThresh->width;
+ for(int x=0;x<width;x++)
+ {
+ if(srcdataptr[x] == 0)
+ {
+ pt.x=x;
+ pt.y=y;
+ //cvCircle(foundHoles,pt,1, CV_RGB(128,128,128),1,8,0);
+ cvSeqPush( seqPoints, &pt );
+ }
+ }
+ }
+
+ //assign each point to a group (a hole)
+ for( int i = 0; i < seqPoints->total; i++ ) {
+ CvPoint pt = *CV_GET_SEQ_ELEM( CvPoint, seqPoints, i );
+ int group = getGroup(i, pt, seqPoints,seqGroups);
+ cvSeqPush( seqGroups, &group );
+ }
+
+
+ CvPoint pt1; CvPoint pt2; CvPoint pt3;
+
+ CvSeq* seqHolesUpLeft = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage );
+ CvSeq* seqHolesDownRight = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage );
+ CvSeq* seqHolesCenter = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage );
+ CvSeq* seqHolesSize = cvCreateSeq( 0, sizeof(CvSeq), sizeof(0), storage );
+
+
+
+ for( int i = 0; i <= getMaxValue(seqGroups); i++ ) {
+ int maxX = -1;
+ int minX = 10000;
+ int maxY = -1;
+ int minY = 10000;
+ int pointsInGroup = 0;
+ for( int j = 0; j < seqGroups->total; j++ ) {
+ int group = *CV_GET_SEQ_ELEM( int, seqGroups, j );
+ if(group==i) {
+ CvPoint pt = *CV_GET_SEQ_ELEM( CvPoint, seqPoints, j );
+ if(pt.x > maxX)
+ maxX = pt.x;
+ if(pt.x < minX)
+ minX = pt.x;
+ if(pt.y > maxY)
+ maxY = pt.y;
+ if(pt.y < minY)
+ minY = pt.y;
+ pointsInGroup++;
+ }
+ }
+ if(maxX != -1) { //ripoff empty groups (appear when there are fusions between groups)
+ pt1.x = minX;
+ pt1.y = minY;
+ pt2.x = maxX;
+ pt2.y = maxY;
+ pt3 = findCenter(pt1, pt2);
+ cvSeqPush( seqHolesUpLeft, &pt1 );
+ cvSeqPush( seqHolesDownRight, &pt2 );
+ cvSeqPush( seqHolesCenter, &pt3);
+ cvSeqPush( seqHolesSize, &pointsInGroup );
+ //printf("%d(%d,%d)-(%d,%d)-(%d,%d): %d\n", i, pt1.x, pt1.y, pt2.x, pt2.y, pt3.x, pt3.y, pointsInGroup);
+ }
+ }
+
+ CvSeq* seqIsValidSize = cvCreateSeq( 0, sizeof(CvSeq), sizeof(0), storage ); //'1' if is valid
+
+ int minSide = 6;
+ int maxSize = 200;
+ int validValue = 1;
+ int nonValidValue = 0;
+ for( int i = 0; i < seqHolesUpLeft->total; i++ ) {
+ CvPoint sp1 = *CV_GET_SEQ_ELEM( CvPoint, seqHolesUpLeft, i );
+ CvPoint sp2 = *CV_GET_SEQ_ELEM( CvPoint, seqHolesDownRight, i );
+ int size = *CV_GET_SEQ_ELEM( int, seqHolesSize, i );
+
+ if(
+ size >= minSide && //size is higher than minSide (obvious)
+ size <= maxSize && //size is lowerr than maxSize (obvious)
+ // sp2.x-sp1.x > minSide && sp2.y-sp1.y > minSide && //every side is bigger or equal to minSide
+ ! (sp2.x-sp1.x > 3*(sp2.y-sp1.y)) && ! (3*(sp2.x-sp1.x) < (sp2.y-sp1.y)) //a side is not 3 times bigger than other (helps to delete shoes if appear)
+ ) {
+ cvSeqPush( seqIsValidSize, &validValue);
+ } else {
+ cvSeqPush( seqIsValidSize, &nonValidValue );
+ }
+ }
+
+ int sizeBig1 = 0;
+ int sizeBig2 = 0;
+ int sizeBig3 = 0;
+ for( int i = 0; i < seqHolesSize->total; i++ ) {
+ int validSize = *CV_GET_SEQ_ELEM( int, seqIsValidSize, i );
+ int size = *CV_GET_SEQ_ELEM( int, seqHolesSize, i );
+ if (validSize == 1) {
+ if(size > sizeBig1) {
+ sizeBig3 = sizeBig2;
+ sizeBig2 = sizeBig1;
+ sizeBig1 = size;
+ } else if (size > sizeBig2) {
+ sizeBig3 = sizeBig2;
+ sizeBig2 = size;
+ } else if (size > sizeBig3) {
+ sizeBig3 = size;
+ }
+ }
+ }
+
+ CvPoint hipPoint;
+ CvPoint kneePoint;
+ CvPoint toePoint;
+ hipPoint.x=0; kneePoint.x=0; toePoint.x=0;
+
+ for( int i = 0; i < seqHolesSize->total; i++ )
+ {
+ int validSize = *CV_GET_SEQ_ELEM( int, seqIsValidSize, i );
+ int size = *CV_GET_SEQ_ELEM( int, seqHolesSize, i );
+ CvPoint sp1 = *CV_GET_SEQ_ELEM( CvPoint, seqHolesUpLeft, i );
+ CvPoint sp2 = *CV_GET_SEQ_ELEM( CvPoint, seqHolesDownRight, i );
+
+ bool validSure = false;
+ CvPoint center;
+
+ CvScalar color = CV_RGB(128, 128, 128 ); //paint rectangles in not-valid (or not big) holes.
+
+ //if size is valid
+ if (validSize) {
+ center = *CV_GET_SEQ_ELEM( CvPoint, seqHolesCenter, i );
+ //if never found a point before, and this are the biggest points found
+ if(pointIsNull(hipOld) && pointIsNull(kneeOld) && pointIsNull(toeOld)) {
+ if(size == sizeBig1 || size == sizeBig2 || size == sizeBig3) {
+ validSure = true;
+
+ if(hipPoint.x == 0) {
+ hipPoint.x = center.x;
+ hipPoint.y = center.y;
+ color = CV_RGB(255, 0, 0 );
+
+ } else if(kneePoint.x == 0) {
+ kneePoint.x = center.x;
+ kneePoint.y = center.y;
+ color = CV_RGB(0, 255, 0 );
+
+ } else {
+ toePoint.x = center.x;
+ toePoint.y = center.y;
+ color = CV_RGB(0, 0, 255 );
+
+ }
+ }
+ }
+ //if found a point before, and this point is inside 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)) {
+ hipPoint.x = center.x;
+ hipPoint.y = center.y;
+ color = CV_RGB(255, 0, 0 );
+
+ } else if(pointInside(kneeOld, sp1,sp2)) {
+ kneePoint.x = center.x;
+ kneePoint.y = center.y;
+ color = CV_RGB(0, 255, 0 );
+
+ } else if(pointInside(toeOld, sp1,sp2)) {
+ toePoint.x = center.x;
+ toePoint.y = center.y;
+ color = CV_RGB(0, 0, 255);
+
+ }else
+ validSure = false;
+ }
+ }
+
+ cvRectangle(imgThresh,
+ cvPoint(sp1.x-1,sp1.y-1),
+ cvPoint(sp2.x+1, sp2.y+1),
+ color,1,1);
+ cvRectangle(imgColor,
+ cvPoint(sp1.x-1,sp1.y-1),
+ cvPoint(sp2.x+1, sp2.y+1),
+ color,1,1);
+ }
+
+ if(kneePoint.x > 0) {
+ if(hipPoint.x > 0) {
+ cvLine(imgThresh,hipPoint,kneePoint,CV_RGB(0,255,0),1,1);
+ cvLine(imgColor,hipPoint,kneePoint,CV_RGB(0,255,0),1,1);
+ } if(toePoint.x > 0) {
+ cvLine(imgThresh,toePoint,kneePoint,CV_RGB(0,255,0),1,1);
+ cvLine(imgColor,toePoint,kneePoint,CV_RGB(0,255,0),1,1);
+ }
+ }
+
+ CvPoint notFoundPoint;
+ notFoundPoint.x = 0; notFoundPoint.y = 0;
+
+ CvSeq* seqHolesEnd = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage );
+
+ if(hipPoint.x > 0)
+ cvSeqPush( seqHolesEnd, &hipPoint );
+ else
+ cvSeqPush( seqHolesEnd, ¬FoundPoint );
+
+ if(kneePoint.x > 0)
+ cvSeqPush( seqHolesEnd, &kneePoint );
+ else
+ cvSeqPush( seqHolesEnd, ¬FoundPoint );
+
+ if(toePoint.x > 0)
+ cvSeqPush( seqHolesEnd, &toePoint );
+ else
+ cvSeqPush( seqHolesEnd, ¬FoundPoint );
+
+ return seqHolesEnd;
+}
+
/*
* takes input argument as the gray form of input frame and a temp image
@@ -864,26 +1110,179 @@
return (int) 100 * countBlack/(countWhite + countBlack);
}
-CvPoint hipSkin;
-CvPoint kneeSkin;
-CvPoint toeSkin;
+int calculateThresholdStart(IplImage * gray)
+{
+ int brightness = calculateBrightness(gray);
+ printf("brightness: %d\n", brightness);
+
+ //created image like the contour but with holes and more (stores on segmentedValidationHoles)
+ //recommended 25,255
+ //high threshold (40-60) detects more black things (useful to not confuse a hole when is close to the border)
+ //low threshold (5-10) detects less black things
+ //if the image is bright, a hight threshold is perfect to nice detect the shapes without detecting shadows
+ //int threshold = 35;
+ //put threshold min depending on brightnesss
+ //eg: nora: brightness 85 -> threshold 30
+ //eg: 44_lluis_puerta_salt6_m.MOV: brightness 73 -> threshold 10
+
+ //adjust better, because:
+ //12_carles_tejedor_salt3_m.MOV
+ //is bright:0, but if put thresh to 1 then detects bad. and to 10 is ok
+ //
+ //on the other side, 2_roger_miralles_salt3_m.MOV
+ //is really dark and it needs a thresh of 1 to work
+ //
+ //also it could be nice to have a thresh that detects three objects
+ //another option, could be to have the thresh 10 as really minimum and darker images are unsupported!
+ int thresholdStart;
+ int briMax = 85;
+ int briMin = 65;
+ //int briZero = 50;
+ int thresMax = 30;
+ int thresMin = 10;
+
+ if(brightness >= briMax)
+ thresholdStart = thresMax;
+ //else if(brightness <= briZero)
+ // thresholdStart = 10;
+ else if(brightness <= briMin)
+ thresholdStart = thresMin;
+ else
+ thresholdStart = brightness - briMin + thresMin;
+
+ return thresholdStart;
+}
+
+double zoomScale = 2;
+
+IplImage * zoomImage(IplImage *img) {
+ IplImage* imgZoom = cvCreateImage( cvSize( cvRound (img->width*zoomScale),
+ cvRound (img->height*zoomScale)), 8, 3 );
+ cvResize( img, imgZoom, CV_INTER_LINEAR );
+ return imgZoom;
+}
+
+CvPoint hipMouse;
+CvPoint kneeMouse;
+CvPoint toeMouse;
+
+bool forceMouseHip = false;
+bool forceMouseKnee = false;
+bool forceMouseToe = false;
+
+bool zoomed = false;
+
+bool mouseCanMark = false;
void on_mouse( int event, int x, int y, int flags, void* param )
{
- switch( event )
- {
+ if(! mouseCanMark)
+ return;
+
+ if(zoomed) {
+ x = x / zoomScale;
+ y = y / zoomScale;
+ }
+
+ switch( event ) {
case CV_EVENT_LBUTTONDOWN:
{
- if(hipSkin.x == 0)
- hipSkin = cvPoint(x,y);
- else if(kneeSkin.x == 0)
- kneeSkin = cvPoint(x,y);
+ if(forceMouseHip)
+ {
+ hipMouse = cvPoint(x,y);
+ forceMouseHip = false;
+ printf("H x:%d, y:%d\n", x, y);
+ }
+ else if(forceMouseKnee)
+ {
+ kneeMouse = cvPoint(x,y);
+ forceMouseKnee = false;
+ printf("K x:%d, y:%d\n", x, y);
+ }
+ else if(forceMouseToe)
+ {
+ toeMouse = cvPoint(x,y);
+ forceMouseToe = false;
+ printf("T x:%d, y:%d\n", x, y);
+ }
+ else if(hipMouse.x == 0)
+ {
+ hipMouse = cvPoint(x,y);
+ printf("H x:%d, y:%d\n", x, y);
+ }
+ else if(kneeMouse.x == 0)
+ {
+ kneeMouse = cvPoint(x,y);
+ printf("K x:%d, y:%d\n", x, y);
+ }
else
- toeSkin = cvPoint(x,y);
- //printf("x:%d, y:%d\n", x, y);
- //
+ {
+ toeMouse = cvPoint(x,y);
+ printf("T x:%d, y:%d\n", x, y);
+ }
}
break;
}
}
+void updateHolesWin(IplImage *segmentedValidationHoles) {
+ double scale = 4;
+ IplImage* tempSmall = cvCreateImage( cvSize( cvRound (segmentedValidationHoles->width/scale),
+ cvRound (segmentedValidationHoles->height/scale)), 8, 1 );
+ cvResize( segmentedValidationHoles, tempSmall, CV_INTER_LINEAR );
+ cvShowImage("holes",tempSmall);
+}
+
+void printOnScreen(IplImage * img, CvFont font, CvScalar color, int legMarkedDist, double legError, int framesCount,
+ int threshold, double thetaMarked, double minThetaMarked)
+{
+ char *label = new char[150];
+ int width = img->width;
+ int height = img->height;
+
+ sprintf(label, "legSize: %d(%.1f%%)", legMarkedDist, legError);
+ cvPutText(img, label, cvPoint(10, height-100),&font,color);
+
+ sprintf(label, "M angle obs: %.2fÂ", thetaMarked);
+ cvPutText(img, label, cvPoint(10,height-80),&font,color);
+
+ sprintf(label, "min M angle obs: %.2fÂ", minThetaMarked);
+ cvPutText(img, label, cvPoint(10,height-60),&font,color);
+
+ sprintf(label, "frame: %d", framesCount);
+ cvPutText(img, label, cvPoint(10,height-40),&font,color);
+
+ sprintf(label, "threshold: %d", threshold);
+ cvPutText(img, label, cvPoint(10,height-20),&font,color);
+
+}
+
+void printOnScreenRight(IplImage * img, CvFont font, CvScalar color,
+ double upLegMarkedDist, double downLegMarkedDist,
+ double upLegMarkedDistMax, double downLegMarkedDistMax,
+ double kneeZetaSide, double htKneeMarked,
+ double thetaABD, double thetaRealFlex)
+{
+ char *label = new char[150];
+ int width = img->width;
+ int height = img->height;
+
+ sprintf(label, "legUp/Down: %.1f/%.1f", upLegMarkedDist, downLegMarkedDist);
+ cvPutText(img, label, cvPoint(width-200, height-120),&font,color);
+
+ sprintf(label, "legMaxUp/Down: %.1f/%.1f", upLegMarkedDistMax, downLegMarkedDistMax);
+ cvPutText(img, label, cvPoint(width-200, height-100),&font,color);
+
+ sprintf(label, "kneeZetaSide: %.1f", kneeZetaSide);
+ cvPutText(img, label, cvPoint(width-200, height-80),&font,color);
+
+ sprintf(label, "htKneeMarked: %.2f", htKneeMarked);
+ cvPutText(img, label, cvPoint(width-200, height-40),&font,color);
+
+ sprintf(label, "sideMove: %.2fÂ", thetaABD);
+ cvPutText(img, label, cvPoint(width-200, height-60),&font,color);
+
+ sprintf(label, "real Flex: %.2fÂ", thetaRealFlex);
+ cvPutText(img, label, cvPoint(width-200, height-20),&font,color);
+}
+
Modified: trunk/src/angle/kneeAngleUtil.cpp
==============================================================================
--- trunk/src/angle/kneeAngleUtil.cpp (original)
+++ trunk/src/angle/kneeAngleUtil.cpp Mon Nov 3 17:24:17 2008
@@ -172,7 +172,12 @@
double getDistance(CvPoint p1, CvPoint p2)
{
- return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
+ return sqrt( pow(p1.x-p2.x, 2) + pow(p1.y-p2.y, 2) );
+}
+
+double getDistance3D(CvPoint p1, CvPoint p2, int p1z, int p2z)
+{
+ return sqrt( pow(p1.x-p2.x, 2) + pow(p1.y-p2.y, 2) + pow(p1z-p2z, 2) );
}
int checkItsOk(int val, int min, int max)
@@ -230,18 +235,32 @@
return false;
}
-double findAngle(CvPoint p1, CvPoint p2, CvPoint pc) //pc is center point
+double findAngle2D(CvPoint p1, CvPoint p2, CvPoint pa) //pa is the point at the angle
{
CvPoint d1, d2;
- d1.x = p1.x - pc.x;
- d1.y = p1.y - pc.y;
- d2.x = p2.x - pc.x;
- d2.y = p2.y - pc.y;
- double dist1 = getDistance(p1, pc);
- double dist2 = getDistance(p2, pc);
+ d1.x = p1.x - pa.x;
+ d1.y = p1.y - pa.y;
+ d2.x = p2.x - pa.x;
+ d2.y = p2.y - pa.y;
+ double dist1 = getDistance(p1, pa);
+ double dist2 = getDistance(p2, pa);
return (180.0/M_PI)*acos(((d1.x*d2.x + d1.y*d2.y))/(double)(dist1*dist2));
}
+double findAngle3D(CvPoint p1, CvPoint p2, CvPoint pa, int p1z, int p2z, int paz) //pa is the point at the angle
+{
+ CvPoint d1, d2;
+ d1.x = p1.x - pa.x;
+ d1.y = p1.y - pa.y;
+ int d1z = p1z - paz;
+ d2.x = p2.x - pa.x;
+ d2.y = p2.y - pa.y;
+ int d2z = p2z - paz;
+ double dist1 = getDistance3D(p1, pa, p1z, paz);
+ double dist2 = getDistance3D(p2, pa, p2z, paz);
+ return (180.0/M_PI)*acos(((d1.x*d2.x + d1.y*d2.y + d1z*d2z))/(double)(dist1*dist2));
+}
+
double relError(double val1, double val2)
{
if(val2-val1 == 0 || val2 == 0)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]