void drawInitialBlobs(IplImage * tmp_frame, CBlobResult blobs){ coord drawCoord; for (int i=0; i<blobs.GetNumBlobs();i++){ //!Creating the coordinate struct drawCoord.set( (int) blobs.GetBlob(i).MaxX(), (int) blobs.GetBlob(i).MinX(), (int) blobs.GetBlob(i).MaxY(), (int) blobs.GetBlob(i).MinY()); drawBlob(tmp_frame, drawCoord, 255, 255, 0); } }
// Compute single tracking score TrackingScore* TrackingEvaluator::computeScore(const TrackedObject& tracked_object, const Mat& frame, int frame_number, TrackingScoreHistory *history) { // Create score TrackingScore* score = new TrackingScore(&nbc); // Add score to history history->addScore(score, frame_number); // Get blob const cvb::CvBlob& orig_blob = tracked_object.currentRegion(); // Random move blobs - to test certainties cvb::CvBlob blob; cvCloneBlob(orig_blob, blob); // Save shape ratio score->setShapeRatio(((float)blob.width())/((float)blob.height())); // Save area score->setArea(blob.width()*blob.height()); // Compute object's binary mask, for the histogram Mat mask = drawBlob(blob, true, frame.cols, frame.rows); // Get grayscale frame Mat frame_gs; cvtColor(frame, frame_gs, CV_BGR2GRAY); // Split the color channels Mat* channels = new Mat[3]; split(frame, channels); Mat frame_b = channels[0]; Mat frame_g = channels[1]; Mat frame_r = channels[2]; delete [] channels; // Compute histograms Histogram hist_gs(frame_gs, mask); Histogram hist_r(frame_r, mask); Histogram hist_g(frame_g, mask); Histogram hist_b(frame_b, mask); // Save histogram score->setHistograms(hist_gs, hist_r, hist_g, hist_b); // Select part of frame on which to compute the texture features Mat copy_gs = frame_gs.clone(); // Blacken non-mask pixels for(unsigned int x=blob.x; x<=blob.maxx; x++) { for(unsigned int y=blob.y; y<=blob.maxy; y++) { if(mask.at<uchar>(y,x) == 0) { copy_gs.at<uchar>(y,x) = 0; } } } // Crop image Rect region(blob.x, blob.y, blob.width(), blob.height()); Mat texture_input = copy_gs(region); // Compute texture features for this object vector<float> texture_features = GaborFilter::applyFilterSet(texture_input, gabor_scales, parameters.get<int>("num_orientations"), false, 1, 0.5, 101); // Save texture features score->setTextureFeatures(texture_features); // Set temporal score to the number of appearances score->temporal_score = history->numScores(); // Get the frame number of the previous detection of this object, if available int prev_frame = -1; TrackingScore* prev_score = NULL; cvb::CvBlob prev_blob; if(history->numScores() > 1) { // Read frame number prev_frame = *(tracked_object.frameList().end() - 2); // Get previous score prev_score = (TrackingScore*) history->getScore(prev_frame); // Get previous blob prev_blob = *(tracked_object.regionList().end() - 2); // Compute shape ratio score score->shape_ratio_score = computeShapeRatioScore(prev_score->getShapeRatio(), score->getShapeRatio()); // Compute area score score->area_score = computeAreaScore(prev_score->getArea(), score->getArea()); // Compute histogram difference score score->histogram_diff_score = computeHistogramDiffScore(score, prev_score); // Compute texture difference score score->texture_diff_score = computeTextureDiffScore(score->getTextureFeatures(), prev_score->getTextureFeatures()); // Compute velocity for this score Point2f prev_position((prev_blob.maxx+prev_blob.x)/2, (prev_blob.maxy+prev_blob.y)/2); Point2f curr_position((blob.maxx+blob.x)/2, (blob.maxy+blob.y)/2); float velocity = sqrt((prev_position.x-curr_position.x)*(prev_position.x-curr_position.x) + (prev_position.y-curr_position.y)*(prev_position.y-curr_position.y)); score->setVelocity(velocity); // Add velocity to the accumulated velocity for this object (will be used to compute an average according to the number of detections) history->accumulateVelocity(velocity); // Check if the previous score has its velocity set if(prev_score->getVelocity() > 0) { //cout << "computing ms: " << score->getVelocity() << ", " << history->getAverageVelocity() << endl; // Compute motion smoothness score, based on current velocity and average velocity score->motion_smoothness = computeMotionSmoothnessScore(score->getVelocity(), history->getAverageVelocity()); } else { // Set score to 0 score->motion_smoothness = 0.0f; // Mark score as not full score->full = false; } // Compute direction for this score float direction = fastAtan2(-curr_position.y + prev_position.y, curr_position.x - prev_position.x); score->setDirection(direction); // Check if the previous score has its direction set //cout << "direction: " << direction << ", prev_score direction: " << prev_score->getDirection() << endl; if(prev_score->getDirection() > 0) { //cout << "computing d : " << prev_score->getDirection() << ", " << score->getDirection() << endl; // Compute direction score, based on current direction and previous direction score->direction_score = computeDirectionScore(score->getDirection(), prev_score->getDirection()); } else { // Set score to 0 score->direction_score = 0.0f; // Mark score as not full score->full = false; } //if(score->full)// && (frame_number % 10) == 0) //{ // out_file << score->shape_ratio_score << " " << score->area_score << " " << score->histogram_diff_score << " " << score->motion_smoothness << " " << score->direction_score << " " << score->texture_diff_score << " 1" << endl; // cout << score->shape_ratio_score << " " << score->area_score << " " << score->histogram_diff_score << " " << score->motion_smoothness << " " << score->direction_score << " " << score->texture_diff_score << " 1" << endl; //} //out_file << score->shape_ratio_score << " " << score->histogram_diff_score << " 1"; //if(pd) // out_file << score->value() << endl; } else { // Set score as certain score->certain = true; } Log::debug() << "tracking score: " << score->value() << "(" << score->shape_ratio_score << ", " << score->area_score << ", " << score->histogram_diff_score << ", " << (score->full ? score->motion_smoothness : -1) << ", " << (score->full ? score->direction_score : -1 ) << ", " << score->texture_diff_score << ")" << endl; // Return score return score; }
//-------------------------------------------------------------- void openniTracking::drawContourAnalysis(){ string temp; glPushMatrix(); glTranslatef(366, 90, 0); glScalef(320.0f/_width, 240.0f/_height, 1.0); ofEnableAlphaBlending(); ofFill(); for(unsigned int i = 0; i < blobTracker.blobs.size(); i++){ ostringstream docstring; docstring << blobTracker.findOrder(blobTracker.blobs[i]._id) << endl; temp = docstring.str(); blobsOrder[i] = atoi(temp.c_str()); glColor4f(0.847,0.25,0.25,0.4); ofRect(_s_blobInfo[i].center.x,_s_blobInfo[i].center.y,_s_blobInfo[i].size.width,_s_blobInfo[i].size.height); glColor4f(0.0,0.0,1.0,1.0); if(temp != ""){ ofDrawBitmapString(temp,_s_blobInfo[i].center.x + _s_blobInfo[i].size.width/2.0,_s_blobInfo[i].center.y + _s_blobInfo[i].size.height/2.0); } } glColor4f(1.0,1.0,1.0,1.0); for (unsigned int i = 0; i < contourFinder.nBlobs; i++){ //------------------- draw the contours if(cfDetail == 0){ glColor4f(0.847,0.25,0.25,1.0); ofNoFill(); drawBlob(0,0,contourFinder.blobs[i]); }else if(cfDetail == 1){ glColor4f(0.847,0.25,0.25,1.0); ofNoFill(); ofBeginShape(); for(unsigned int j = 0; j < contourSmooth[i].size(); j++){ ofVertex(contourSmooth[i].at(j).x, contourSmooth[i].at(j).y); } ofEndShape(true); }else if(cfDetail == 2){ glColor4f(0.847,0.25,0.25,1.0); ofNoFill(); ofBeginShape(); for(unsigned int k = 0; k < contourSimple[i].size(); k++){ ofVertex(contourSimple[i].at(k).x, contourSimple[i].at(k).y); } ofEndShape(true); } //------------------- fit angle of orientation glColor4f(1.0,0.906,0.463,1.0); float x1,y1,x2,y2; x1 = contourFinder.blobs[i].centroid.x + 25 * cos(blobAngle[i]); y1 = contourFinder.blobs[i].centroid.y + 25 * sin(blobAngle[i]); x2 = contourFinder.blobs[i].centroid.x - 25 * cos(blobAngle[i]); y2 = contourFinder.blobs[i].centroid.y - 25 * sin(blobAngle[i]); glPushMatrix(); glScalef(0.5,0.5,0.0); ofLine(x1*2,y1*2,x2*2,y2*2); glPopMatrix(); x1 = contourFinder.blobs[i].centroid.x + 10 * cos(blobAngle[i]+HALF_PI); y1 = contourFinder.blobs[i].centroid.y + 10 * sin(blobAngle[i]+HALF_PI); x2 = contourFinder.blobs[i].centroid.x - 10 * cos(blobAngle[i]+HALF_PI); y2 = contourFinder.blobs[i].centroid.y - 10 * sin(blobAngle[i]+HALF_PI); glPushMatrix(); glScalef(0.5,0.5,0.0); ofLine(x1*2,y1*2,x2*2,y2*2); glPopMatrix(); //------------------- fit geometry lines on countour if(computeContourGeometry){ glColor4f(0.1,1.0,0.0,0.8); ofNoFill(); for(unsigned int j = 0; j < geomLines[i].size(); j++){ ofLine(geomLines[i].at(j).x,geomLines[i].at(j).y,geomLines[i].at(j).z,geomLines[i].at(j).w); ofCircle(geomLines[i].at(j).x,geomLines[i].at(j).y,3); ofCircle(geomLines[i].at(j).z,geomLines[i].at(j).w,3); } } } glPopMatrix(); ofDisableAlphaBlending(); }