From 0944dd461b920e97b6a5213e3b487f71f55c061a Mon Sep 17 00:00:00 2001 From: mutantturkey Date: Wed, 24 Oct 2012 09:46:36 -0400 Subject: fixed bug in background deriver when input files have a space. Using getline instead of the >> operator solves the problem --- fly-tools/background/main.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/fly-tools/background/main.cpp b/fly-tools/background/main.cpp index b01305e..7504ab2 100644 --- a/fly-tools/background/main.cpp +++ b/fly-tools/background/main.cpp @@ -9,9 +9,13 @@ #define array(i,j,k,l) (array[height*width*i + width*j + k + l]) int nImages; + unsigned long height = 0; unsigned long width = 0; +using namespace std; +using namespace cv; + int findmax(long *p, int n) { int mx = 0, v = p[0]; for (int i = 1; i < n; i++) { @@ -23,8 +27,6 @@ int findmax(long *p, int n) { return mx; } -using namespace std; -using namespace cv; int main(int argc, char **argv ) { @@ -59,9 +61,9 @@ int main(int argc, char **argv ) { IplImage *first_image = NULL; IplImage *output_image = NULL; - int i,j, k; - int height = 0; - int width = 0; + unsigned int i = 0; + unsigned int j = 0; + unsigned int k = 0; string filename; @@ -75,11 +77,12 @@ int main(int argc, char **argv ) { // Read first line for our first image and rewind - input_file>>filename; + getline(input_file, filename); first_image = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_UNCHANGED); if(!first_image) { + cerr << "couldn't read first image" << endl; exit(1); } @@ -100,7 +103,7 @@ int main(int argc, char **argv ) { input_file.clear(); input_file.seekg(0); - while(input_file>>filename) { + while (!getline(input_file, filename).eof()) { nImages++; } @@ -116,7 +119,7 @@ int main(int argc, char **argv ) { input_file.clear(); input_file.seekg(0); - while (input_file>>filename) { + while (!getline(input_file, filename).eof()) { IplImage *input_image = NULL; input_image = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_UNCHANGED); -- cgit v1.2.1 From ade7d29b7158fb83517fd254265b866a6992efb4 Mon Sep 17 00:00:00 2001 From: mutantturkey Date: Wed, 24 Oct 2012 09:52:45 -0400 Subject: swap our output columns to fit our feature vector (mean first, std-dev second) --- fly-tools/std-deviation/StandardDeviation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fly-tools/std-deviation/StandardDeviation.cpp b/fly-tools/std-deviation/StandardDeviation.cpp index 1d29d91..f2668ba 100644 --- a/fly-tools/std-deviation/StandardDeviation.cpp +++ b/fly-tools/std-deviation/StandardDeviation.cpp @@ -58,7 +58,7 @@ int main(int argc, char* argv[]) { exit(0); } - outputFile << left << setw(30) << "File Name" << left << setw(20) << "Standard deviation" << left << setw(20) << "Mean" << endl; + outputFile << left << setw(20) << "File Name" << left << setw(20) << "Mean" << left << setw(20) << "Standard Deviation" << endl; while( inputFileNames >> currentFileName ) { @@ -103,7 +103,7 @@ int main(int argc, char* argv[]) { standardDev = sumSquaredResults/(N-1); standardDev = sqrt(standardDev); - outputFile< Date: Wed, 24 Oct 2012 09:58:56 -0400 Subject: remove a misc test file, left over from Reza import --- fly-tools/misc/makeimage.cpp | 51 -------------------------------------------- 1 file changed, 51 deletions(-) delete mode 100644 fly-tools/misc/makeimage.cpp diff --git a/fly-tools/misc/makeimage.cpp b/fly-tools/misc/makeimage.cpp deleted file mode 100644 index 06e2897..0000000 --- a/fly-tools/misc/makeimage.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include -using namespace std; -using namespace Magick; - -int main(int argc,char **argv) - -{ - // Construct the image object. Seperating image construction from the - // the read operation ensures that a failure to read the image file - // doesn't render the image object useless. - - Image* img; - char buffer[100]; - sprintf(buffer,"%ix%i",7,7); - - // residual image is initialized with black representing not visited. - //residual = new Image(buffer, "black"); - - img = new Image(buffer, "white"); - - for (int j=0; j<=3;j++) { - for (int i=0; i<=3-j; i++) { - img->pixelColor(i,j, "black"); - img->pixelColor(6-i,j, "black"); - } - } - - int k; - for (int j=4; j<=6;j++) { - for (int i=0; i<=j-3; i++) { - img->pixelColor(i,j, "black"); - img->pixelColor(6-i,j, "black"); - } - } - - - //img->pixelColor(0,3, "red"); - - - string namei = "7x7.png"; - img->write(namei.c_str()); - - delete img; - - return 0; - -} - -- cgit v1.2.1 From fb645ae8efa9f9df252857d5a5cb0f6ce8f7074b Mon Sep 17 00:00:00 2001 From: mutantturkey Date: Wed, 24 Oct 2012 10:01:42 -0400 Subject: don't say we're adding work --- fly-tools/mask/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fly-tools/mask/main.c b/fly-tools/mask/main.c index 804f07f..6adf5e8 100644 --- a/fly-tools/mask/main.c +++ b/fly-tools/mask/main.c @@ -83,7 +83,7 @@ int main( int argc, char **argv){ } thpool_t* threadpool; - threadpool=thpool_init(4); + threadpool=thpool_init(2); char filename[256]; char *temp; @@ -94,7 +94,6 @@ int main( int argc, char **argv){ if (temp != NULL) *temp = '\0'; char *filename_r = malloc(256); strncpy(filename_r, filename, sizeof(filename)); - printf("add work: %s \n", filename); thpool_add_work(threadpool, (void*)convert_image, (void*)filename_r); } -- cgit v1.2.1 From 36a6028d34e8481ac3078d1351eb4116082a152a Mon Sep 17 00:00:00 2001 From: mutantturkey Date: Wed, 24 Oct 2012 10:05:39 -0400 Subject: Frame Info spacing fixes --- fly-tools/FrameInfo.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/fly-tools/FrameInfo.cpp b/fly-tools/FrameInfo.cpp index c97b651..c02e3f7 100644 --- a/fly-tools/FrameInfo.cpp +++ b/fly-tools/FrameInfo.cpp @@ -14,18 +14,22 @@ FrameInfo::FrameInfo(int frameNo, vector fOVector, bool isSingleBlob this->isSingleBlob = isSingleBlob; } + FrameInfo::FrameInfo(const FrameInfo &f) { this->frameNo = f.getFrameNo(); this->fOVector = f.getFOVector(); this->isSingleBlob = f.getIsSingleBlob(); } + int FrameInfo::getFrameNo() const { return frameNo; } + bool FrameInfo::getIsSingleBlob() const { return isSingleBlob; } + vector FrameInfo::getFOVector() const{ return fOVector; } @@ -33,12 +37,15 @@ vector FrameInfo::getFOVector() const{ void FrameInfo::setFrameNo(int fn) { this->frameNo = fn; } + void FrameInfo::setIsSingleBlob(bool isSingleBlob) { this->isSingleBlob = isSingleBlob; } + void FrameInfo::setFOVector(vector fov) { this->fOVector = fov; } + void FrameInfo ::swapTheFlyObject() { if (fOVector.size() > 1) { cout << "swapping\n"; @@ -47,13 +54,12 @@ void FrameInfo ::swapTheFlyObject() { fOVector[1] = a; } } + void FrameInfo::output(ostream &out) { out<<"FrameNo : "< Date: Wed, 24 Oct 2012 10:06:35 -0400 Subject: remove unused, commented, functions --- fly-tools/FlyObject.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/fly-tools/FlyObject.h b/fly-tools/FlyObject.h index 10dbd4f..e7c0b82 100644 --- a/fly-tools/FlyObject.h +++ b/fly-tools/FlyObject.h @@ -1,6 +1,5 @@ /* * FlyObject.h - * * * Created by Md. Alimoor Reza on 6/26/10. * Copyright 2010 Drexel University. All rights reserved. @@ -14,7 +13,6 @@ using namespace std; class FlyObject { public: - //FlyObject(int area, pair centroid, pair majorAxisEV, pair velocityV, vector > areaCoord); FlyObject(int area, pair centroid, pair majorAxisEV, pair velocityV,bool headIsInDirectionMAEV, pair head, double speed); FlyObject(const FlyObject &f); int getArea() const; @@ -24,7 +22,6 @@ public: bool getHeadIsInDirectionMAEV() const; pair getHead() const; double getSpeed() const; - //vector > getAreaCoord() const; void setArea(int area); void setCentroid(pair); void setMajorAxisEV(pair); @@ -33,13 +30,11 @@ public: void setHeadIsInDirectionMAEV(bool); void setHead(pair head); void setSpeed(double speed); - //void setAreaCoord(vector >); void output(ostream &out); private: int area; - //vector > areaCoord; pair centroid; pair majorAxisEV; pair velocityV; -- cgit v1.2.1 From dd3b350d2eb06012f3d5ee08e2f4060536b57621 Mon Sep 17 00:00:00 2001 From: mutantturkey Date: Wed, 24 Oct 2012 10:07:44 -0400 Subject: update README to include preliminary information about k-means clustering --- README.markdown | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index fcb8026..9a95eba 100644 --- a/README.markdown +++ b/README.markdown @@ -150,5 +150,11 @@ pngs to make sure that the fly tracking was performed correctly. ### Into the Beyond ### Now that we've done the hard work of image processing the rest is up to you! The -data is all there, now you need to do manually generate the feature vectors. +data is all there, now you need to do manually generate the feature vectors, and +you need to run our simple k-means clustering. + +The K-Means clustering requires Java to run and our Least Squares Solution CCI +calculator was written in Matlab and requires it to run. + + -- cgit v1.2.1 From 765cbbb01e06a5e5cd913b04d467e80ec8cd5bc7 Mon Sep 17 00:00:00 2001 From: mutantturkey Date: Wed, 31 Oct 2012 17:27:38 -0400 Subject: Output CCI's into a seperate txt file from all the folds --- fly-tools/cci-calculator/LeastSquareSolution.m | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/fly-tools/cci-calculator/LeastSquareSolution.m b/fly-tools/cci-calculator/LeastSquareSolution.m index 85d1326..1e4d822 100644 --- a/fly-tools/cci-calculator/LeastSquareSolution.m +++ b/fly-tools/cci-calculator/LeastSquareSolution.m @@ -17,6 +17,8 @@ function [x, e] = LeastSquareSolution(fileNameA, fileNameB, output) solution=[]; + cci_output_file = strcat(output, '/CCIs_combined.txt'); + for i=0:(total_folds-1) % debug @@ -84,26 +86,20 @@ function [x, e] = LeastSquareSolution(fileNameA, fileNameB, output) %saving the calculated cis CI = [CI; ci]; % store the ci values - - %fid_debug = fopen(debug_file,'w'); - %fprintf(fid_debug, '%s\n','Train data'); - %fprintf(fid_debug, '%8.6f\t%8.6f\t%8.6f\t%8.6f\t%8.6f\t%8.6f\t%8.6f\t%8.6f', A_); -% fprintf(fid_debug, '%s\n','Test data'); -% fprintf(fid_debug, '%8.6f\t%8.6f\t%8.6f\t%8.6f\t%8.6f\t%8.6f\t%8.6f\t%8.6f', test_data); fid_debug = fopen(debug_file,'w'); -% fprintf(fid_debug, '%s\n\n','Test data'); - fprintf(fid_debug, '%s\n\n','new CI'); fprintf(fid_debug, '%8.6f\n', ci); + %output our cci's A.K.A. "new CI" into a seperate file as well. + fprintf(cci_output_file, '%8.6f\n', ci); + fprintf(fid_debug, '%s\n\n','actual CI'); actual_ci = b(test,:); fprintf(fid_debug, '%8.6f\n', actual_ci); fprintf(fid_debug, '%s\n\n','error'); fprintf(fid_debug, '%8.6f\n', (ci-actual_ci)); -% fprintf(fid_debug, '%s\n\n','Train data'); fclose(fid_debug); @@ -119,8 +115,6 @@ function [x, e] = LeastSquareSolution(fileNameA, fileNameB, output) fprintf(fid_ci, '%8.6f\n', CI); fclose(fid_ci); - %fid_solution_vectors = fopen('Solution_vectors.txt', 'w'); dlmwrite('Solution_vectors.txt', solution, 'delimiter', '\t'); - %fclose(fid_solution_vectors); -- cgit v1.2.1 From 039ef3345967fe291b1487a9a588a37909531af0 Mon Sep 17 00:00:00 2001 From: mutantturkey Date: Wed, 31 Oct 2012 17:29:05 -0400 Subject: add a note to the README about the ordering --- fly-tools/cci-calculator/README.markdown | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fly-tools/cci-calculator/README.markdown b/fly-tools/cci-calculator/README.markdown index 065563c..1578fc2 100644 --- a/fly-tools/cci-calculator/README.markdown +++ b/fly-tools/cci-calculator/README.markdown @@ -28,3 +28,8 @@ If we have 21 specimen per fold, use number of folds + 2 for the head argument, and the number of folds for the tail. This will give you proper results! for i in Fold_*.txt; do head $i -n 23 | tail -n 21 >> output.txt; echo $i; done; + +The output of the file is in the order of your input, so just copy your data +back into whatever spreadsheet you are using and it be good. If you notice +that the numbers don't match up, make sure your ordering correctly! + -- cgit v1.2.1 From 754edf136d1020462f65d60c963aeea4da5df1a6 Mon Sep 17 00:00:00 2001 From: mutantturkey Date: Wed, 31 Oct 2012 17:37:29 -0400 Subject: add basic explaination of how some of the tools work, and set line wrapping to 80 lines. --- fly-tools/README.markdown | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/fly-tools/README.markdown b/fly-tools/README.markdown index ac94d8c..60e2b98 100644 --- a/fly-tools/README.markdown +++ b/fly-tools/README.markdown @@ -1,6 +1,8 @@ fly-tools ========= +These are the programs that do all the hard work! + FlyTracking ------------ @@ -13,7 +15,8 @@ Usage: FilterFlyMask ------------ -FilterFlyMask runs some filtering operations on masks to ensure that the FlyTracking tool processes the information correctly. +FilterFlyMask runs some filtering operations on masks to ensure that the +FlyTracking tool processes the information correctly. Usage: @@ -22,8 +25,12 @@ Usage: filter-mask ----------- -filter-mask is an alternative fly filter that works much faster. It utilizes the OpenCV and CvBlob libraries. +filter-mask is an alternative fly filter that works much faster. It utilizes +the OpenCV and CvBlob libraries. +The filter works simply, it counts the number of blobs and grabs the largest +two. Anything else is discarded and the two blobs are written to a new image. + Usage: filter-mask -i -o -r @@ -31,7 +38,17 @@ Usage: mask-generator ------------- -This tool creates masks from cropped video frames, which the need to be filtered by the FilterFlyMask tool. +This tool creates binary masks from cropped video frames, which the need to be +filtered by the FilterFlyMask tool. + +The program works by doing 3 specific image manipulations to the input images. + +1. subtract the background image from the input image +2. auto-level the image. This operation sets the lightest pixel to white and +then normalizes the rest of the image accordingly. This step is important to +ensure that the mask output is relatively similar when ligt conditions are +changing during a sequence. +3. Threshold the image, anything over 30% is marked as white, the rest is black Usage: @@ -44,7 +61,12 @@ Todo: derive-background ----------------- -This tool will generate a common background image of a set of video frames (PNGs), based on the statistical mode of each pixel. +This tool will generate a common background image of a set of video frames +(PNGs), based on the statistical mode of each pixel. + +The program works by iterating through each image, through each pixel, adding +them to a histogram and then calculates each pixel's mode and spews out the +resulting image. Usage: -- cgit v1.2.1 From 2ee9cae7ae0bb7a556910d0f8dcc6a14ba7ba7ee Mon Sep 17 00:00:00 2001 From: mutantturkey Date: Mon, 19 Nov 2012 10:01:18 -0500 Subject: use unsigned int --- fly-tools/FlyTrackingMain.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fly-tools/FlyTrackingMain.cpp b/fly-tools/FlyTrackingMain.cpp index c68fe3c..5dd94f7 100644 --- a/fly-tools/FlyTrackingMain.cpp +++ b/fly-tools/FlyTrackingMain.cpp @@ -111,8 +111,8 @@ ostream &operator<<(ostream &out, FrameInfo & fI) { } void bubbleSort(vector & fov) { - for(int i=1; i > veloci int flag = false; int maxSeqSize = 0; int st = 0; - for (int j=0; j prevVel = velocityDirs[j]; pair currVel = velocityDirs[j+1]; -- cgit v1.2.1 From 25ba5b17f86b76c1c99f6d09942362b13dcb18f8 Mon Sep 17 00:00:00 2001 From: mutantturkey Date: Mon, 19 Nov 2012 14:23:44 -0500 Subject: Clean ups left and right, Use proper exit codes, remove a useless header, alphabetize the function lists, concat declarations and more --- fly-tools/FlyTrackingMain.cpp | 258 ++++++++++++++++++------------------------ 1 file changed, 107 insertions(+), 151 deletions(-) diff --git a/fly-tools/FlyTrackingMain.cpp b/fly-tools/FlyTrackingMain.cpp index 5dd94f7..30dc3db 100644 --- a/fly-tools/FlyTrackingMain.cpp +++ b/fly-tools/FlyTrackingMain.cpp @@ -1,4 +1,3 @@ -#include #include #include #include @@ -21,14 +20,28 @@ using namespace Magick; using namespace std; +// One of these output streams will be used. If directed towards null, nothing happens, towards output, it will be printed ofstream nullLog; ostream* output; +// Our output files for debugging and information +ofstream foutLPS; +ofstream foutSt; +ofstream foutDebugCen; +ofstream foutDebugSpeed; + + const double PI = atan(1.0)*4.0; const double FACTOR_EIGEN = 100; const int STUCKING_TO_A_SINGLE_BLOB = 1; const int SEPARATING_FROM_SINGLE_BLOB = 2; +bool isInFemaleBlob; +int maskImageHeight; +int maskImageWidth; +int diagLength; + +vector > bresenhamLine; Image* residual; vector fOVector; @@ -60,12 +73,12 @@ int sequenceSize=1; int startOfAOneObject = -1; int endOfAOneObject = -1; -vector fnVector; -string inputFileName; - +// This decides if we want to output an overlay. You'll get the same results +// either way but you won't be able to verify it. taken as an argument. bool writeFinalImages = false; // GLOBAL PATHS +string inputFileName; string maskImagePath; string origImagePath; string finalOutputPath; @@ -73,6 +86,7 @@ string outputFilePrefix; vector > velocityDirectionsF; vector > velocityDirectionsS; +vector fnVector; pair avgVelocityF; pair avgVelocityS; @@ -83,6 +97,7 @@ pair overAllVelocityS; vector > evDirectionF; vector > evDirectionS; +// Information about frames that will be written out at the end of proessing. int totalMaleLookingAtFemale = 0; int totalFemaleLookingAtMale = 0; int totalSingleBlob = 0; @@ -93,7 +108,6 @@ map centroidDistanceMap; map headDirAngleMap; map speedMap; - void initSequence(){ startOfATrackSequence = -1; endOfATrackSequence = -1; @@ -125,8 +139,7 @@ void bubbleSort(vector & fov) { } } -void writeHist(const char* filename, map dataMap) -{ +void writeHist(const char* filename, map dataMap) { *output << "In the beginning of the write hist" << endl; *output << "dataMap size " << dataMap.size() << endl; @@ -143,7 +156,6 @@ void writeHist(const char* filename, map dataMap) back = dataMap.end(); back--; - unsigned int first = front->first, last = back->first; *output << "Min: " << first << " " << "Max: " << last << " " << "Count: " << last-first << endl; vector hist(last+1, 0); @@ -174,24 +186,22 @@ void writeHist(const char* filename, map dataMap) } -void findObj(Image* img, int x, int y, vector > & shape ,bool eightCon=true, bool colorLookingFor=true); -void eightConnObj(Image* img, int x, int y, vector > & obj, bool color=true); -void fourConnObj(Image* img, int x, int y, vector > & obj, bool color=true); +double calculateDotProduct(pair v, pair eV); +void calculateHeadVector(FlyObject fO, pair &headDirection); vector covariantDecomposition(vector > & points); -pair getCentroid(vector > & points); -bool isInterface(Image* orig, unsigned int x, unsigned int y); -void writeFrameImage(int fn, string imS); +void determineHeadDirection(int fileCounter); void drawTheFlyObject(FrameInfo currentFI, string fileName, int isFirst, bool singleBlob=false,bool unprocessed = false); void drawTheSequence(int startIndex, int endIndex, int isFirst, bool singleBlob = false, bool unprocessed = false); +void eightConnObj(Image* img, int x, int y, vector > & obj, bool color=true); double euclideanDist(FlyObject a, FlyObject b); +void findObj(Image* img, int x, int y, vector > & shape ,bool eightCon=true, bool colorLookingFor=true); +void fourConnObj(Image* img, int x, int y, vector > & obj, bool color=true); +pair getCentroid(vector > & points); +bool isInterface(Image* orig, unsigned int x, unsigned int y); bool identifyFlyObjectFromFrameToFrame(FrameInfo prevFI, FrameInfo& currentFI, bool gotRidOfSingleBlob=false) ; int roundT(double v) {return int(v+0.5);} -void determineHeadDirection(int fileCounter); - - void normalizeVector(pair &a); -double calculateDotProduct(pair v, pair eV); -void calculateHeadVector(FlyObject fO, pair &headDirection); +void writeFrameImage(int fn, string imS); void normalizeVector(pair &a) { double temp = a.first*a.first + a.second*a.second; @@ -632,10 +642,7 @@ if (inWhite) } }*/ -bool isInFemaleBlob; -int maskImageHeight; -int maskImageWidth; -vector > bresenhamLine; + void putPixel(Image* maskImage, int x, int y) { @@ -969,7 +976,7 @@ int draw_line_bm(Image* maskImage, int x0, int y0, int x1, int y1) { default: *output << "No octant which should be a bug\n"; - exit(0); + exit(EXIT_FAILURE); break; } @@ -977,14 +984,20 @@ int draw_line_bm(Image* maskImage, int x0, int y0, int x1, int y1) { } -double euclideanDist(pair newLocation, pair initLocation) { - +inline double euclideanDist(pair newLocation, pair initLocation) { double temp = pow((newLocation.first - initLocation.first), 2.0) + pow((newLocation.second - initLocation.second), 2.0); temp = sqrt(temp); return temp; +} + +inline double getSpeed(pair vector) { + double value = vector.first*vector.first + vector.second*vector.second; + value = sqrt(value); + return value; } + int sequenceCondition(FrameInfo prevFI,FrameInfo currentFI) { bool prevFIsSingleBlob = prevFI.getIsSingleBlob(); bool currentFIsSingleBlob = currentFI.getIsSingleBlob(); @@ -1022,7 +1035,6 @@ void drawTheSequence(int startIndex, int endIndex, int isFirst, bool singleBlob, } - void objectHeadDirection(FlyObject prevFO, FlyObject ¤tFO) { // take the head direction from the previous frame @@ -1200,11 +1212,9 @@ void velocityDirection(int st, int end, pair &velDirectionF, pa pair cFFCentroid = cFFirstFO.getCentroid(); pair cFSCentroid = cFSecondFO.getCentroid(); - pair pFFCentroid = pFFirstFO.getCentroid(); pair pFSCentroid = pFSecondFO.getCentroid(); - int velXFirst = cFFCentroid.first - pFFCentroid.first; int velYFirst = cFFCentroid.second - pFFCentroid.second; @@ -1220,23 +1230,13 @@ void velocityDirection(int st, int end, pair &velDirectionF, pa velDirectionF = cFVV; velDirectionS = cSVV; - - } -double getSpeed(pair vector) { - double value = vector.first*vector.first + vector.second*vector.second; - value = sqrt(value); - - return value; - -} void velocityDirections(int stIndex, int endIndex) { - velocityDirectionsF.clear(); velocityDirectionsS.clear(); int i = 0; @@ -1309,7 +1309,6 @@ void velocityDirections(int stIndex, int endIndex) { } -ofstream foutLPS; void largestIncreasingPositiveDotProductSeq(vector > velocityDirs, int &startIndex, int &endIndex) { int positiveVelSeqSize = 0; @@ -1347,8 +1346,6 @@ void largestIncreasingPositiveDotProductSeq(vector > veloci //*output << "end "< cFOVector = currentFI.getFOVector(); FlyObject cFFO = cFOVector[object-1]; - pair cFVV = cFFO.getVelocityV(); + //pair cFVV = cFFO.getVelocityV(); //*output << "Velocity before normalization "< tempVelocity = cFSecondFO.getVelocityV(); + //pair tempVelocity = cFSecondFO.getVelocityV(); //*output << "Velocity was "< tempFOV; // to find the new head direction - bool currentlyCalculatingHead = true; + //bool currentlyCalculatingHead = true; while (inputFile>>fileName) { int fi = fileName.find("_"); + // Be aware that this limits us to sample size of 99,999 (55.55 minutes) // current sequence numbers spans from 0 - 18019, so 5 digits are needed int span = 5; string tempString = fileName.substr(fi+1,span); @@ -1997,7 +1973,7 @@ int main(int argc, char **argv) // residual image is initialized with black representing not visited. residual = new Image(buffer, "black"); - //*output<<"reading file "< 0 ) { - // *output << "size of the object is: " << s < eigenVal = covariantDecomposition(shape); - { //objCount++; @@ -2028,14 +2002,11 @@ int main(int argc, char **argv) pair (eigenVal[4], eigenVal[5]), 0.0); tempFOV.push_back(tempFO); - } } - } } - delete img; delete residual; @@ -2045,10 +2016,8 @@ int main(int argc, char **argv) fOVector.clear(); for (int ti=0; ti > foundShape; + vector > shape; + + Image *image, *mask; + cout << "Segmented image "<columns(); - int height = image->rows(); + width = image->columns(); + height = image->rows(); - char buffer[100]; sprintf(buffer,"%ix%i",width,height); // the residual image should be newed residual = new Image(buffer, "black"); - bool found = false; - vector > foundShape; - vector > shape; *output<<"Detecting the male object for finding the start point"< eigenVal = covariantDecomposition(foundShape); - int x0, y0, x1, y1; - - x0 = cen_x; - y0 = cen_y; - - double ev_x; - double ev_y; - if (eVDirection == true) { ev_x = static_cast (x0) + static_cast (diagLength)*eigenVal[4]; ev_y = static_cast (y0) + static_cast (diagLength)*eigenVal[5]; @@ -2367,19 +2336,19 @@ void findTheStartPoint(string fileName, int desiredSize, int otherSize, int cen_ *output<<"Endpoint: centroid (x0,y0)==("< point = foundShape[i]; - maskImage->pixelColor(point.first, point.second,"white"); + mask->pixelColor(point.first, point.second,"white"); } - /*int hits= */ draw_line_bm(maskImage, x1, y1, x0, y0); + /*int hits= */ draw_line_bm(mask, x1, y1, x0, y0); - //maskImage->strokeColor("red"); - //maskImage->draw(DrawableLine(x1, y1, x0, y0)); - //maskImage->write("test.png"); + //mask->strokeColor("red"); + //mask->draw(DrawableLine(x1, y1, x0, y0)); + //mask->write("test.png"); *output<<"BresenhamLine size is "< 0) { pair temp = bresenhamLine[bresenhamLine.size()-1]; *output << "Finding the starting point: Hits source at "<pixelColor(temp.first, temp.second); + ColorMono c = mask->pixelColor(temp.first, temp.second); //maleSP_x = prev_x; //maleSP_y = prev_y; @@ -2403,7 +2372,7 @@ void findTheStartPoint(string fileName, int desiredSize, int otherSize, int cen_ } else { isFoundStartPoint = false; - *output<<"The object is at the border in the mask image. BresenhamLine vector is empty. Size : "< 0) { pair temp = bresenhamLine[bresenhamLine.size()-1]; *output << "Finding the starting point: Hits source at "<pixelColor(temp.first, temp.second); + ColorMono c = mask->pixelColor(temp.first, temp.second); //maleSP_x = prev_x; //maleSP_y = prev_y; if (c.mono() == true) { *output << "start point from the source object should be black"<strokeColor("blue"); pair velocityV = currentFO.getVelocityV(); ev_x = static_cast(centroid.first) + 30.0 * velocityV.first; ev_y = static_cast(centroid.second) + 30.0 * velocityV.second; img->draw(DrawableLine( centroid.first, centroid.second, static_cast(ev_x), static_cast(ev_y) )); - - // draw the historical head vector img->strokeColor("white"); pair headV = currentFO.getHead(); @@ -2717,16 +2683,13 @@ void drawTheFlyObject(FrameInfo currentFI, string fileName, int isFirst, bool si ev_y = static_cast (centroid.second) + 25.0*headV.second; img->draw( DrawableLine(centroid.first, centroid.second, static_cast (ev_x), static_cast (ev_y)) ); - //draw the object tracking circle if (n == isFirst and n==0) { *output << "Tracking the n = "<strokeColor("yellow"); img->draw(DrawableCircle(centroid.first, centroid.second, centroid.first+5, centroid.second)); img->pixelColor(prev_x, prev_y, "red"); - } else if ( n == isFirst and n==1) { - *output << "Tracking the "<strokeColor("yellow"); img->fillColor("none"); @@ -2734,7 +2697,6 @@ void drawTheFlyObject(FrameInfo currentFI, string fileName, int isFirst, bool si img->draw(DrawableCircle(centroid.first, centroid.second, centroid.first+5, centroid.second)); } - } } } @@ -2743,11 +2705,9 @@ void drawTheFlyObject(FrameInfo currentFI, string fileName, int isFirst, bool si img->write(outputFileName.c_str()); delete img; } - - // when do not want to identify on the original comment below line and uncomment the above one - delete maskImage; + // TODO: Wtf is going on here? if (isHitting == 1 || isHittingFemaleToMale == 0) calculateStatistics(currentFI, fileName, isFirst, singleBlob, true, false, unprocessed); else if (isHitting == 0 || isHittingFemaleToMale == 1) @@ -2760,10 +2720,8 @@ void drawTheFlyObject(FrameInfo currentFI, string fileName, int isFirst, bool si } -void findObj(Image* img, int x, int y, vector > & shape ,bool eightCon, bool colorLookingFor) -{ +void findObj(Image* img, int x, int y, vector > & shape ,bool eightCon, bool colorLookingFor) { assert(residual != NULL); - if (eightCon == true) eightConnObj(img, x, y, shape, colorLookingFor); else { @@ -2772,8 +2730,7 @@ void findObj(Image* img, int x, int y, vector > & shape ,bool eigh } -void fourConnObj(Image* img, int x, int y, vector > & obj, bool color) -{ +void fourConnObj(Image* img, int x, int y, vector > & obj, bool color) { int width = img->columns(),height = img->rows(); // boundary violation check @@ -2813,8 +2770,7 @@ void fourConnObj(Image* img, int x, int y, vector > & obj, bool c } -void eightConnObj(Image* img, int x, int y, vector > & obj, bool color) -{ +void eightConnObj(Image* img, int x, int y, vector > & obj, bool color) { int width = img->columns(),height = img->rows(); // boundary violation check -- cgit v1.2.1 From 7d76e9aaee9dc40158117e7702b12fe6184e5d11 Mon Sep 17 00:00:00 2001 From: Calvin Morrison Date: Sun, 30 Dec 2012 22:09:05 -0500 Subject: Update README.markdown Fixed error in link --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 9a95eba..1e4791e 100644 --- a/README.markdown +++ b/README.markdown @@ -3,7 +3,7 @@ Automated Categorization of Drosophila Learning and Memory Behaviors using Video For more information about this project, goto: -https://www.cs.drexel.edu/~david/Papers/Md_Reza_MS_Thesis.pdf_ +https://www.cs.drexel.edu/~david/Papers/Md_Reza_MS_Thesis.pdf This repository contains all of the source codes used for the Fly Tracking project. -- cgit v1.2.1 From bda4a425da1073ca38b7ccf006d02f65b25a4755 Mon Sep 17 00:00:00 2001 From: Calvin Morrison Date: Wed, 14 May 2014 15:23:05 -0400 Subject: add changes for histogramming --- fly-tools/FlyTrackingMain.cpp | 907 ++++++++++++++++++++++-------------------- fly-tools/Makefile | 4 +- 2 files changed, 486 insertions(+), 425 deletions(-) diff --git a/fly-tools/FlyTrackingMain.cpp b/fly-tools/FlyTrackingMain.cpp index 30dc3db..d44d546 100644 --- a/fly-tools/FlyTrackingMain.cpp +++ b/fly-tools/FlyTrackingMain.cpp @@ -8,12 +8,13 @@ #include #include -#include +#include #include #include #include #include +#include #include "FrameInfo.h" @@ -139,7 +140,48 @@ void bubbleSort(vector & fov) { } } -void writeHist(const char* filename, map dataMap) { + +void getMeanStdDev(map dataMap, double *mean, double *standardDev) { + // mean = 1/N*(sum(i*H_i)) for i = 0 to M-1 + double sumOfValues = 0.0; + double i = 0.0; + double N = 0.0; + double M = 0.0; + + vector currentHistogramValues; + + for(i = 0; i < dataMap.size(); i++) { + sumOfValues = sumOfValues + i*dataMap[i]; + N += dataMap[i]; + + cout << "sum:" << sumOfValues << endl; + cout << "N:" << N << endl; + cout << "i:" << i << endl; + } + + // mean + *mean = sumOfValues/N; + double lmean = 0; + lmean = sumOfValues/N; + cout << "mean:" << *mean << endl; + cout << "mean:" << lmean << " = " << sumOfValues << "/" << N << endl; + + // sigma^2 = (sum( (i-mean)^2*H_i ) )/(N-1) for i = 0 to M-1 + *standardDev = 0.0; + double sumSquaredResults = 0.0; + int j = 0; + for ( i = 0.0; i < dataMap.size(); i++) { + sumSquaredResults += pow((i-*mean), 2.0)*dataMap[j]; + *output << "sumsqres:" << sumSquaredResults << endl; + j++; + } + + // standard deviation + *standardDev = sumSquaredResults/(N-1); + *standardDev = sqrt(*standardDev); +} + +double writeHist(const char* filename, map dataMap) { *output << "In the beginning of the write hist" << endl; *output << "dataMap size " << dataMap.size() << endl; @@ -148,7 +190,7 @@ void writeHist(const char* filename, map dataMap) { ofstream fout(filename); fout <<"No entry in the histogram and size is " << dataMap.size() << endl; fout.close(); - return; + return 0; } @@ -183,7 +225,8 @@ void writeHist(const char* filename, map dataMap) { catch (...) { cerr << "Bad memory loc for opening file" << endl; } - + + return 0; } double calculateDotProduct(pair v, pair eV); @@ -1839,465 +1882,130 @@ void processASequence(int startOfATrackSequence, int endOfATrackSequence) { } -int main(int argc, char **argv) { - - int c; - bool verbose = false; - string usage = "Usage: FlyTracking -i -o -f -m -p "; - opterr = 0; - while ((c = getopt (argc, argv, "i:f:m:p:o:hxv")) != -1) - switch (c) { - case 'i': - inputFileName = optarg; - break; - case 'o': - origImagePath = optarg; - break; - case 'f': - finalOutputPath = optarg; - break; - case 'm': - maskImagePath = optarg; - break; - case 'p': - outputFilePrefix = optarg; - break; - case 'h': - cout << usage << endl; - exit(EXIT_FAILURE); - break; - case 'x': - writeFinalImages = true; - break; - case 'v': - verbose = true; - break; - default: - break; - } +// is set each time the start is found +// useful when one blob is detected on the border of the mask image +bool isFoundStartPoint = false; +int hitTheFly(Image* maskImage, int &intersectX, int &intersectY) { - (verbose) ? output = &cout : output = &nullLog; + //Image* maskImage = new Image(fileName.c_str()); - *output << "verbose logging out" << endl; + for (int i=bresenhamLine.size()-1; i>=0; i--) { - if( inputFileName.empty() || origImagePath.empty() || finalOutputPath.empty() || maskImagePath.empty() || outputFilePrefix.empty() ) { - cerr << usage << endl; - cerr << "input name: " << inputFileName << endl; - cerr << "original path: " << origImagePath << endl; - cerr << "output path: " << finalOutputPath << endl; - cerr << "mask path: " << maskImagePath << endl; - cerr << "output prefix: " << outputFilePrefix << endl; - exit(EXIT_FAILURE); - } + pair tempP = bresenhamLine[i]; - string fileName; - ifstream inputFile(inputFileName.c_str()); + int x = tempP.first; - if (inputFile.fail() ) { - cerr << "cannot open the input file that contains name of the input images\n"; - exit(EXIT_FAILURE); - } + int y = tempP.second; - string statFileName = finalOutputPath + outputFilePrefix + "_statFile.txt"; - foutSt.open(statFileName.c_str()); + ColorMono currPixelColor = ColorMono(maskImage->pixelColor(x,y)); - if (foutSt.fail()) { - cerr<<"cannot open the statfile"< > shape; - vector tempFOV; + int width = 0; + int height = 0; - // to find the new head direction - //bool currentlyCalculatingHead = true; + int x0, y0, x1, y1; - while (inputFile>>fileName) { + x0 = cen_x; + y0 = cen_y; - int fi = fileName.find("_"); - // Be aware that this limits us to sample size of 99,999 (55.55 minutes) - // current sequence numbers spans from 0 - 18019, so 5 digits are needed - int span = 5; - string tempString = fileName.substr(fi+1,span); - int frameCounter = atoi(tempString.c_str()); - //*output << frameCounter<columns(),height = img->rows(); - diagLength= static_cast ( sqrt( (height*height) + (width*width) ) ); + vector > foundShape; + vector > shape; - //*output << "Diagonal length is "<columns(); + height = image->rows(); - if ( s > 0 ) - { - // *output << "size of the object is: " << s < eigenVal = covariantDecomposition(shape); - { - //objCount++; + sprintf(buffer,"%ix%i",width,height); - double velocity_x=0.0, velocity_y=0.0; - // save the object information - FlyObject tempFO(s, - pair (eigenVal[6], eigenVal[7]), - pair (eigenVal[4], eigenVal[5]), - pair (velocity_x, velocity_y), - false, - pair (eigenVal[4], eigenVal[5]), - 0.0); - tempFOV.push_back(tempFO); - } - } - } - } + // the residual image should be newed + residual = new Image(buffer, "black"); - delete img; - delete residual; + *output<<"Detecting the male object for finding the start point"< 0 ) + { - for (int ti=0; ti tmpCentroid = getCentroid(shape); + foutDebugCen<<"tmpCentroid.first, tmpCentroid.second = ("< 1) { + pair point = shape[l]; + *output << "point.first, point.second "<= 15 to be a single blob state, so pass false parameter. - drawTheSequence(startOfAOneObject, endOfAOneObject,0, true, false); - startOfAOneObject = -1; - endOfAOneObject = -1; - //startOfATrackSequence = 1; - sequenceSize = 1; - } - - - if(seqCond == STUCKING_TO_A_SINGLE_BLOB) { - *output << "StartIndex "< 15 when the size of the sequence is > 16. - if ((endOfATrackSequence - startOfATrackSequence) >=15 ) { - processASequence(startOfATrackSequence, endOfATrackSequence); - *output << "Done processing"< 15 ) { - - *output << "Last sequence that does not stick to a single blob status startIndex "<(totalMaleLookingAtFemale+totalFemaleLookingAtMale)/static_cast(totalSeparated); - percentageLookingAt *= 100.0; - - double percentageSingleBlob = static_cast(totalSingleBlob)/static_cast(fileCounter); - percentageSingleBlob *= 100.0; - - foutSt<<"Total number of single blob "<=0; i--) { - - pair tempP = bresenhamLine[i]; - - int x = tempP.first; - - int y = tempP.second; - - ColorMono currPixelColor = ColorMono(maskImage->pixelColor(x,y)); - - if (currPixelColor.mono() == true) { - *output << "Hit the target fly"<<" "< > foundShape; - vector > shape; - - Image *image, *mask; - - cout << "Segmented image "<columns(); - height = image->rows(); - - sprintf(buffer,"%ix%i",width,height); - - // the residual image should be newed - residual = new Image(buffer, "black"); - - *output<<"Detecting the male object for finding the start point"< 0 ) - { - - *output << "size of the object is: " << s < tmpCentroid = getCentroid(shape); - foutDebugCen<<"tmpCentroid.first, tmpCentroid.second = ("< point = shape[l]; - *output << "point.first, point.second "< > shape; + vector tempFOV; + + // to find the new head direction + //bool currentlyCalculatingHead = true; + + while (inputFile>>fileName) { + + int fi = fileName.find("_"); + // Be aware that this limits us to sample size of 99,999 (55.55 minutes) + // current sequence numbers spans from 0 - 18019, so 5 digits are needed + int span = 5; + string tempString = fileName.substr(fi+1,span); + int frameCounter = atoi(tempString.c_str()); + //*output << frameCounter<columns(),height = img->rows(); + diagLength= static_cast ( sqrt( (height*height) + (width*width) ) ); + + //*output << "Diagonal length is "< 0 ) + { + // *output << "size of the object is: " << s < eigenVal = covariantDecomposition(shape); + { + //objCount++; + + double velocity_x=0.0, velocity_y=0.0; + // save the object information + FlyObject tempFO(s, + pair (eigenVal[6], eigenVal[7]), + pair (eigenVal[4], eigenVal[5]), + pair (velocity_x, velocity_y), + false, + pair (eigenVal[4], eigenVal[5]), + 0.0); + tempFOV.push_back(tempFO); + } + } + } + } + + delete img; + delete residual; + + // *output<<"Sorting the objects according to size"< 1) { + + FrameInfo prevFI = fIVector[fileCounter-1]; + + int seqCond = sequenceCondition(prevFI, currentFI); + + if (seqCond == STUCKING_TO_A_SINGLE_BLOB) { + + endOfATrackSequence = fileCounter-1; + + // save the index for printing the one object later on + startOfAOneObject = fileCounter; + + } else if (seqCond == SEPARATING_FROM_SINGLE_BLOB) { + + startOfATrackSequence = fileCounter; + + // draw the single blob sequence + endOfAOneObject = fileCounter - 1; + *output << "Only one object StartIndex "<= 15 to be a single blob state, so pass false parameter. + drawTheSequence(startOfAOneObject, endOfAOneObject,0, true, false); + startOfAOneObject = -1; + endOfAOneObject = -1; + //startOfATrackSequence = 1; + sequenceSize = 1; + } + + + if(seqCond == STUCKING_TO_A_SINGLE_BLOB) { + *output << "StartIndex "< 15 when the size of the sequence is > 16. + if ((endOfATrackSequence - startOfATrackSequence) >=15 ) { + processASequence(startOfATrackSequence, endOfATrackSequence); + *output << "Done processing"< 15 ) { + + *output << "Last sequence that does not stick to a single blob status startIndex "<(totalMaleLookingAtFemale+totalFemaleLookingAtMale)/static_cast(totalSeparated); + percentageLookingAt *= 100.0; + + double percentageSingleBlob = static_cast(totalSingleBlob)/static_cast(fileCounter); + percentageSingleBlob *= 100.0; + + foutSt<<"Total number of together "<