00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "MBARI/VisualEvent.H"
00038
00039 #include "Image/DrawOps.H"
00040 #include "Image/Image.H"
00041 #include "Image/Pixels.H"
00042 #include "Image/Rectangle.H"
00043 #include "Image/ShapeOps.H"
00044 #include "Image/Transforms.H"
00045 #include "Image/colorDefs.H"
00046 #include "MBARI/Geometry2D.H"
00047 #include "MBARI/mbariFunctions.H"
00048 #include "Util/Assert.H"
00049 #include "Util/StringConversions.H"
00050
00051 #include <algorithm>
00052 #include <istream>
00053 #include <ostream>
00054
00055
00056
00057
00058 Token::Token()
00059 : bitObject(),
00060 location(),
00061 prediction(),
00062 line(),
00063 angle(0.0F),
00064 frame_nr(0)
00065 {}
00066
00067
00068 Token::Token (float x, float y, uint frame, BitObject bo)
00069 : bitObject(bo),
00070 location(x,y),
00071 prediction(),
00072 line(),
00073 angle(0.0F),
00074 frame_nr(frame)
00075 {}
00076
00077
00078 Token::Token (BitObject bo, uint frame)
00079 : bitObject(bo),
00080 location(bo.getCentroidXY()),
00081 prediction(),
00082 line(),
00083 angle(0.0F),
00084 frame_nr(frame)
00085 {}
00086
00087
00088 Token::Token (std::istream& is)
00089 {
00090 readFromStream(is);
00091 }
00092
00093
00094 void Token::writeToStream(std::ostream& os) const
00095 {
00096 os << frame_nr << ' ';
00097 location.writeToStream(os);
00098 prediction.writeToStream(os);
00099 line.writeToStream(os);
00100 os << angle << '\n';
00101 bitObject.writeToStream(os);
00102 os << "\n";
00103 }
00104
00105
00106 void Token::readFromStream(std::istream& is)
00107 {
00108 is >> frame_nr;
00109 location.readFromStream(is);
00110 prediction.readFromStream(is);
00111 line.readFromStream(is);
00112 is >> angle;
00113 bitObject = BitObject(is);
00114 }
00115
00116
00117 void Token::writePosition(std::ostream& os) const
00118 {
00119 location.writeToStream(os);
00120 }
00121
00122
00123
00124
00125
00126 PropertyVectorSet::PropertyVectorSet()
00127 {}
00128
00129
00130 PropertyVectorSet::PropertyVectorSet(std::istream& is)
00131 {
00132 readFromStream(is);
00133 }
00134
00135
00136 void PropertyVectorSet::writeToStream(std::ostream& os) const
00137 {
00138 uint s2;
00139 if (itsVectors.empty()) s2 = 0;
00140 else s2 = itsVectors.front().size();
00141
00142 os << itsVectors.size() << " " << s2 << "\n";
00143
00144 for (uint i = 0; i < itsVectors.size(); ++i)
00145 {
00146 for (uint j = 0; j < s2; ++j)
00147 os << itsVectors[i][j] << " ";
00148
00149 os << "\n";
00150 }
00151 }
00152
00153
00154 void PropertyVectorSet::readFromStream(std::istream& is)
00155 {
00156 uint s1, s2;
00157 is >> s1; is >> s2;
00158 itsVectors = std::vector< std::vector<float> > (s1, std::vector<float>(s2));
00159
00160 for (uint i = 0; i < s1; ++i)
00161 for (uint j = 0; j < s2; ++j)
00162 is >> itsVectors[i][j];
00163 }
00164
00165
00166 std::vector<float> PropertyVectorSet::getPropertyVectorForEvent(const int num)
00167 {
00168 for (uint i = 0; i < itsVectors.size(); ++i)
00169 if ((int)(itsVectors[i][0]) == num) return itsVectors[i];
00170
00171 LFATAL("property vector for event number %d not found!", num);
00172 return std::vector<float>();
00173 }
00174
00175
00176
00177
00178 VisualEvent::VisualEvent(Token tk, int maxDist)
00179 : startframe(tk.frame_nr),
00180 endframe(tk.frame_nr),
00181 max_size(tk.bitObject.getArea()),
00182 maxsize_framenr(tk.frame_nr),
00183 closed(false),
00184 itsMaxDist(maxDist),
00185 xTracker(tk.location.x(),0.1F,10.0F),
00186 yTracker(tk.location.y(),0.1F,10.0F)
00187 {
00188 LINFO("tk.location = (%g, %g); area: %i",tk.location.x(),tk.location.y(),
00189 tk.bitObject.getArea());
00190 tokens.push_back(tk);
00191 ++counter;
00192 myNum = counter;
00193 }
00194
00195 uint VisualEvent::counter = 0;
00196
00197
00198 VisualEvent::VisualEvent(std::istream& is)
00199 {
00200 readFromStream(is);
00201 }
00202
00203
00204 void VisualEvent::writeToStream(std::ostream& os) const
00205 {
00206 os << myNum << " " << startframe << " " << endframe << "\n";
00207 os << max_size << " " << maxsize_framenr << "\n";
00208
00209 if (closed) os << "1\n";
00210 else os << "0\n";
00211
00212 os << itsMaxDist << "\n";
00213
00214 xTracker.writeToStream(os);
00215 yTracker.writeToStream(os);
00216
00217 os << tokens.size() << "\n";
00218
00219 for (uint i = 0; i < tokens.size(); ++i)
00220 tokens[i].writeToStream(os);
00221
00222 os << "\n";
00223 }
00224
00225
00226 void VisualEvent::readFromStream(std::istream& is)
00227 {
00228 is >> myNum;
00229 is >> startframe;
00230 is >> endframe;
00231 is >> max_size;
00232 is >> maxsize_framenr;
00233
00234 int n; is >> n;
00235 closed = (n == 1);
00236
00237 is >> itsMaxDist;
00238
00239 xTracker.readFromStream(is);
00240 yTracker.readFromStream(is);
00241
00242 int t;
00243 is >> t;
00244 tokens.clear();
00245 for (int i = 0; i < t; ++i)
00246 tokens.push_back(Token(is));
00247 }
00248
00249
00250 void VisualEvent::writePositions(std::ostream& os) const
00251 {
00252 for (uint i = 0; i < tokens.size(); ++i)
00253 tokens[i].writePosition(os);
00254
00255 os << "\n";
00256 }
00257
00258
00259 Point2D<int> VisualEvent::predictedLocation() const
00260 {
00261 int x = int(xTracker.getEstimate() + 0.5F);
00262 int y = int(yTracker.getEstimate() + 0.5F);
00263 return Point2D<int>(x,y);
00264 }
00265
00266
00267 bool VisualEvent::isTokenOk(const Token& tk) const
00268 {
00269 return ((tk.frame_nr - endframe) == 1) && !closed;
00270 }
00271
00272
00273 float VisualEvent::getCost(const Token& tk) const
00274 {
00275 if (!isTokenOk(tk)) return -1.0F;
00276
00277 float cost = (xTracker.getCost(tk.location.x()) +
00278 yTracker.getCost(tk.location.y()));
00279
00280 LINFO("Event no. %i; obj location: %g, %g; predicted location: %g, %g; cost: %g",
00281 myNum, tk.location.x(), tk.location.y(), xTracker.getEstimate(),
00282 yTracker.getEstimate(), cost);
00283 return cost;
00284 }
00285
00286
00287 void VisualEvent::assign(const Token& tk, const Vector2D& foe)
00288 {
00289 ASSERT(isTokenOk(tk));
00290
00291 tokens.push_back(tk);
00292
00293 tokens.back().prediction = Vector2D(xTracker.getEstimate(),
00294 yTracker.getEstimate());
00295 tokens.back().location = Vector2D(xTracker.update(tk.location.x()),
00296 yTracker.update(tk.location.y()));
00297
00298
00299
00300 Vector2D dir = tokens.front().location - tokens.back().location;
00301 tokens.back().line.reset(tokens.back().location, dir);
00302
00303 if (foe.isValid())
00304 tokens.back().angle = dir.angle(tokens.back().location - foe);
00305 else
00306 tokens.back().angle = 0.0F;
00307
00308 if (tk.bitObject.getArea() > max_size)
00309 {
00310 max_size = tk.bitObject.getArea();
00311 maxsize_framenr = tk.frame_nr;
00312 }
00313 endframe = tk.frame_nr;
00314 }
00315
00316
00317 bool VisualEvent::doesIntersect(const BitObject& obj, int frameNum) const
00318 {
00319 if (!isFrameOk(frameNum)) return false;
00320 else return getToken(frameNum).bitObject.doesIntersect(obj);
00321 }
00322
00323
00324
00325 std::vector<float> VisualEvent::getPropertyVector()
00326 {
00327 std::vector<float> vec;
00328 Token tk = getMaxSizeToken();
00329 BitObject bo = tk.bitObject;
00330
00331
00332 vec.push_back(getEventNum());
00333
00334
00335 vec.push_back(-1);
00336
00337
00338 if (!bo.isValid())
00339 {
00340
00341 vec.push_back(-1);
00342
00343
00344 for (uint i = 3; i <= 12; ++i)
00345 vec.push_back(0);
00346
00347
00348 return vec;
00349 }
00350
00351
00352
00353
00354 vec.push_back(bo.getArea());
00355
00356
00357 float uxx, uyy, uxy;
00358 bo.getSecondMoments(uxx, uyy, uxy);
00359 vec.push_back(uxx);
00360 vec.push_back(uyy);
00361 vec.push_back(uxy);
00362
00363
00364 vec.push_back(bo.getMajorAxis());
00365
00366
00367 vec.push_back(bo.getMinorAxis());
00368
00369
00370 vec.push_back(bo.getElongation());
00371
00372
00373 vec.push_back(bo.getOriAngle());
00374
00375
00376 float maxIntens,minIntens,avgIntens;
00377 bo.getMaxMinAvgIntensity(maxIntens, minIntens, avgIntens);
00378 vec.push_back(maxIntens);
00379 vec.push_back(minIntens);
00380 vec.push_back(avgIntens);
00381
00382
00383 vec.push_back(tk.angle);
00384
00385
00386 return vec;
00387 }
00388
00389
00390 Dims VisualEvent::getMaxObjectDims() const
00391 {
00392 int w = -1, h = -1;
00393 std::vector<Token>::const_iterator t;
00394 for (t = tokens.begin(); t != tokens.end(); ++t)
00395 {
00396 Dims d = t->bitObject.getObjectDims();
00397 w = std::max(w, d.w());
00398 h = std::max(h, d.h());
00399 }
00400 return Dims(w,h);
00401 }
00402
00403
00404
00405
00406 VisualEventSet::VisualEventSet(const int maxDist,
00407 const uint minFrameNum,
00408 const int minSize,
00409 const std::string& fileName)
00410 : itsMaxDist(maxDist),
00411 itsMinFrameNum(minFrameNum),
00412 itsMinSize(minSize),
00413 startframe(-1),
00414 endframe(-1),
00415 itsFileName(fileName)
00416 {
00417 float maxAreaDiff = maxDist * maxDist / 4.0F;
00418 itsMaxCost = maxDist * maxDist + maxAreaDiff * maxAreaDiff;
00419 }
00420
00421
00422 VisualEventSet::VisualEventSet(std::istream& is)
00423 {
00424 readFromStream(is);
00425 }
00426
00427
00428 void VisualEventSet::writeToStream(std::ostream& os) const
00429 {
00430 os << itsFileName << "\n";
00431 os << itsMaxDist << " "
00432 << itsMaxCost << " "
00433 << itsMinFrameNum << " "
00434 << itsMinSize << "\n";
00435 os << startframe << ' ' << endframe << '\n';
00436
00437 os << itsEvents.size() << "\n";
00438 std::list<VisualEvent>::const_iterator currEvent;
00439 for (currEvent = itsEvents.begin(); currEvent != itsEvents.end(); ++currEvent)
00440 currEvent->writeToStream(os);
00441
00442 os << itsFOE.size() << '\n';
00443 for (uint i = 0; i < itsFOE.size(); ++i)
00444 itsFOE[i].writeToStream(os);
00445
00446 os << "\n";
00447 }
00448
00449
00450 void VisualEventSet::readFromStream(std::istream& is)
00451 {
00452 is >> itsFileName; LINFO("filename: %s",itsFileName.c_str());
00453 is >> itsMaxDist;
00454 is >> itsMaxCost;
00455 is >> itsMinFrameNum;
00456 is >> itsMinSize;
00457 is >> startframe;
00458 is >> endframe;
00459
00460 int n; is >> n;
00461 itsEvents.clear();
00462 for (int i = 0; i < n; ++i)
00463 itsEvents.push_back(VisualEvent(is));
00464
00465 is >> n;
00466 itsFOE.clear();
00467 for (int i = 0; i < n; ++i)
00468 itsFOE.push_back(Vector2D(is));
00469 }
00470
00471
00472 void VisualEventSet::writePositions(std::ostream& os) const
00473 {
00474 std::list<VisualEvent>::const_iterator currEvent;
00475 for (currEvent = itsEvents.begin(); currEvent != itsEvents.end(); ++currEvent)
00476 currEvent->writePositions(os);
00477 }
00478
00479
00480 void VisualEventSet::updateEvents(const Image<byte>& binMap,
00481 const Vector2D& curFOE,
00482 int frameNum)
00483 {
00484 if (startframe == -1) {startframe = frameNum; endframe = frameNum;}
00485 ASSERT((frameNum == endframe) || (frameNum == endframe+1));
00486 if (frameNum > endframe) endframe = frameNum;
00487
00488 itsFOE.push_back(curFOE);
00489
00490 std::list<VisualEvent>::iterator currEvent;
00491 for (currEvent = itsEvents.begin(); currEvent != itsEvents.end(); ++currEvent)
00492 {
00493 if (currEvent->isClosed()) continue;
00494
00495
00496 Point2D<int> pred = currEvent->predictedLocation();
00497
00498
00499
00500 int gone = 0;
00501 if ((pred.i < -gone) || (pred.i >= (binMap.getWidth() + gone)) ||
00502 (pred.j < -gone) || (pred.j >= (binMap.getHeight() + gone)))
00503 {
00504 currEvent->close();
00505 LINFO("Event %i out of bounds - closed",currEvent->getEventNum());
00506 continue;
00507 }
00508
00509
00510 Rectangle region =
00511 Rectangle::tlbrI(pred.j - itsMaxDist, pred.i - itsMaxDist,
00512 pred.j + itsMaxDist, pred.i + itsMaxDist);
00513 region = region.getOverlap(binMap.getBounds());
00514
00515
00516 std::list<BitObject> objs = extractBitObjects(binMap, region, itsMinSize);
00517
00518
00519
00520
00521 float lCost = -1.0F;
00522 std::list<BitObject>::iterator cObj, lObj = objs.end();
00523 for (cObj = objs.begin(); cObj != objs.end(); ++cObj)
00524 {
00525 if (doesIntersect(*cObj, frameNum)) continue;
00526
00527 float cost = currEvent->getCost(Token(*cObj,frameNum));
00528
00529
00530
00531 if (cost < 0.0F) continue;
00532 if ((lCost == -1.0F) || (cost < lCost))
00533 {
00534 lCost = cost;
00535 lObj = cObj;
00536
00537 }
00538 }
00539
00540
00541 if ((lCost > itsMaxCost) || (lCost == -1.0))
00542 {
00543 currEvent->close();
00544 LINFO("Event %i - no token found, closing event",
00545 currEvent->getEventNum());
00546 }
00547 else
00548 {
00549
00550 Token tk(*lObj, frameNum);
00551 currEvent->assign(tk, curFOE);
00552
00553 LINFO("Event %i - token found at %g, %g",currEvent->getEventNum(),
00554 currEvent->getToken(frameNum).location.x(),
00555 currEvent->getToken(frameNum).location.y());
00556 }
00557 }
00558 }
00559
00560
00561 void VisualEventSet::initiateEvents(std::list<BitObject>& bos, int frameNum)
00562 {
00563 if (startframe == -1) {startframe = frameNum; endframe = frameNum;}
00564 ASSERT((frameNum == endframe) || (frameNum == endframe+1));
00565 if (frameNum > endframe) endframe = frameNum;
00566
00567 std::list<BitObject>::iterator currObj;
00568
00569
00570 currObj = bos.begin();
00571 while(currObj != bos.end())
00572 {
00573
00574 if (doesIntersect(*currObj, frameNum))
00575 {
00576
00577
00578
00579 currObj = bos.erase(currObj);
00580 }
00581 else
00582 {
00583
00584
00585
00586 ++currObj;
00587 }
00588 }
00589
00590
00591 for (currObj = bos.begin(); currObj != bos.end(); ++currObj)
00592 {
00593 itsEvents.push_back(VisualEvent(Token(*currObj, frameNum), itsMaxDist));
00594 LINFO("assigning object of area: %i to new event %i",currObj->getArea(),
00595 itsEvents.back().getEventNum());
00596 }
00597 }
00598
00599
00600 bool VisualEventSet::doesIntersect(const BitObject& obj, int frameNum) const
00601 {
00602 std::list<VisualEvent>::const_iterator cEv;
00603 for (cEv = itsEvents.begin(); cEv != itsEvents.end(); ++cEv)
00604 if (cEv->doesIntersect(obj,frameNum)) return true;
00605
00606 return false;
00607 }
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705 Vector2D VisualEventSet::getFOE(int frameNum) const
00706 {
00707
00708 int idx = frameNum - startframe;
00709
00710
00711 ASSERT((idx >= 0)&& (idx < (int)itsFOE.size()));
00712
00713 return itsFOE[idx];
00714 }
00715
00716
00717 uint VisualEventSet::numEvents() const
00718 {
00719 return itsEvents.size();
00720 }
00721
00722
00723 void VisualEventSet::reset()
00724 {
00725 itsEvents.clear();
00726 }
00727
00728
00729 void VisualEventSet::cleanUp(uint currFrame, uint maxFrameSkip)
00730 {
00731 std::list<VisualEvent>::iterator currEvent = itsEvents.begin();
00732 while (currEvent != itsEvents.end())
00733 {
00734 if (currEvent->isClosed() &&
00735 (currEvent->getNumberOfFrames() < itsMinFrameNum))
00736 {
00737 LINFO("Erasing event %i, because it has only %i frames.",
00738 currEvent->getEventNum(), currEvent->getNumberOfFrames());
00739 currEvent = itsEvents.erase(currEvent);
00740 }
00741 else ++currEvent;
00742
00743 }
00744 }
00745
00746
00747 void VisualEventSet::closeAll()
00748 {
00749 std::list<VisualEvent>::iterator cEvent;
00750 for (cEvent = itsEvents.begin(); cEvent != itsEvents.end(); ++cEvent)
00751 cEvent->close();
00752 }
00753
00754
00755 std::vector<Token> VisualEventSet::getTokens(uint frameNum)
00756 {
00757 std::vector<Token> tokens;
00758 std::list<VisualEvent>::iterator currEvent;
00759 for (currEvent = itsEvents.begin(); currEvent != itsEvents.end(); ++currEvent)
00760 {
00761
00762 if (!currEvent->isFrameOk(frameNum)) continue;
00763
00764 tokens.push_back(currEvent->getToken(frameNum));
00765 }
00766
00767 return tokens;
00768 }
00769
00770
00771 void VisualEventSet::drawTokens(Image< PixRGB<byte> >& img,
00772 uint frameNum,
00773 PropertyVectorSet& pvs,
00774 int circleRadius,
00775 BitObjectDrawMode mode,
00776 float opacity,
00777 PixRGB<byte> colorInteresting,
00778 PixRGB<byte> colorCandidate,
00779 PixRGB<byte> colorPred,
00780 PixRGB<byte> colorFOE,
00781 bool showEventLabels)
00782 {
00783
00784 const int numW = 10;
00785 const int numH = 21;
00786
00787 std::list<VisualEvent>::iterator currEvent;
00788 for (currEvent = itsEvents.begin(); currEvent != itsEvents.end(); ++currEvent)
00789 {
00790
00791 if (!currEvent->isFrameOk(frameNum)) continue;
00792
00793 PixRGB<byte> circleColor;
00794 Token tk = currEvent->getToken(frameNum);
00795 Point2D<int> center = tk.location.getPoint2D();
00796
00797 if (isEventInteresting(pvs.getPropertyVectorForEvent
00798 (currEvent->getEventNum())))
00799 circleColor = colorInteresting;
00800 else
00801 circleColor = colorCandidate;
00802
00803
00804 Image< PixRGB<byte> > textImg;
00805 if (showEventLabels)
00806 {
00807
00808 std::string numText = toStr(currEvent->getEventNum());
00809 textImg.resize(numW * numText.length(), numH, NO_INIT);
00810 textImg.clear(COL_WHITE);
00811 writeText(textImg, Point2D<int>(0,0), numText.c_str());
00812 }
00813
00814
00815 if (circleColor != COL_TRANSPARENT)
00816 {
00817
00818 Rectangle bbox;
00819
00820
00821 if (tk.bitObject.isValid())
00822 {
00823 tk.bitObject.draw(mode, img, circleColor, opacity);
00824 bbox = tk.bitObject.getBoundingBox(BitObject::IMAGE);
00825
00826 }
00827 else
00828 {
00829 LINFO("BitObject is invalid: area: %i;",tk.bitObject.getArea());
00830 LFATAL("bounding box: %s",toStr(tk.bitObject.getBoundingBox()).c_str());
00831 drawCircle(img, center, circleRadius, circleColor);
00832 bbox = Rectangle::tlbrI(center.j - circleRadius, center.i - circleRadius,
00833 center.j + circleRadius, center.i + circleRadius);
00834 bbox = bbox.getOverlap(img.getBounds());
00835 }
00836
00837
00838 if (showEventLabels)
00839 {
00840 Point2D<int> numLoc = getLabelPosition(img.getDims(),bbox,textImg.getDims());
00841 Image<PixRGB <byte> > textImg2 = replaceVals(textImg,COL_BLACK,circleColor);
00842 textImg2 = replaceVals(textImg2,COL_WHITE,COL_TRANSPARENT);
00843 pasteImage(img,textImg2,COL_TRANSPARENT, numLoc, opacity);
00844
00845 }
00846
00847 }
00848
00849
00850 if ((colorPred != COL_TRANSPARENT) && tk.prediction.isValid())
00851 {
00852 Point2D<int> ctr = tk.prediction.getPoint2D();
00853 drawCircle(img, ctr,10,colorPred);
00854 Rectangle ebox =
00855 Rectangle::tlbrI(ctr.j - 10, ctr.i - 10, ctr.j + 10, ctr.i + 10);
00856 ebox = ebox.getOverlap(img.getBounds());
00857 if (showEventLabels)
00858 {
00859 Point2D<int> numLoc = getLabelPosition(img.getDims(), ebox, textImg.getDims());
00860 Image< PixRGB<byte> > textImg2 = replaceVals(textImg,COL_BLACK,colorPred);
00861 textImg2 = replaceVals(textImg2,COL_WHITE,COL_TRANSPARENT);
00862 pasteImage(img,textImg2,COL_TRANSPARENT, numLoc, opacity);
00863 }
00864 }
00865
00866 }
00867
00868
00869 if ((colorFOE != COL_TRANSPARENT) && getFOE(frameNum).isValid())
00870 {
00871 Point2D<int> ctr = getFOE(frameNum).getPoint2D();
00872 drawDisk(img, ctr,2,colorFOE);
00873 }
00874
00875 }
00876
00877
00878 Point2D<int> VisualEventSet::getLabelPosition(Dims imgDims,
00879 Rectangle bbox,
00880 Dims textDims) const
00881 {
00882
00883 const int dist = 2;
00884
00885 Point2D<int> loc(bbox.left(),(bbox.top() - dist - textDims.h()));
00886
00887
00888 if ((loc.i + textDims.w()) > imgDims.w())
00889 loc.i = imgDims.w() - textDims.w() - 1;
00890
00891
00892 if (loc.j < 0)
00893 loc.j = bbox.bottomI() + dist;
00894
00895 return loc;
00896 }
00897
00898
00899 PropertyVectorSet VisualEventSet::getPropertyVectorSet()
00900 {
00901 PropertyVectorSet pvs;
00902
00903 std::list<VisualEvent>::iterator currEvent;
00904 for (currEvent = itsEvents.begin(); currEvent != itsEvents.end();
00905 ++currEvent)
00906 pvs.itsVectors.push_back(currEvent->getPropertyVector());
00907
00908 return pvs;
00909 }
00910
00911
00912
00913 int VisualEventSet::getAllClosedFrameNum(uint currFrame)
00914 {
00915 std::list<VisualEvent>::iterator currEvent;
00916 for (int frame = (int)currFrame; frame >= -1; --frame)
00917 {
00918 bool done = true;
00919
00920 for (currEvent = itsEvents.begin(); currEvent != itsEvents.end();
00921 ++currEvent)
00922 {
00923 done &= ((frame < (int)currEvent->getStartFrame())
00924 || currEvent->isClosed());
00925 if (!done) break;
00926 }
00927
00928 if (done) return frame;
00929 }
00930 return -1;
00931 }
00932
00933
00934 bool VisualEventSet::isEventInteresting(std::vector<float> propVec) const
00935 {
00936 const float interestThresh = 5;
00937 const float uxyThresh = 0.4F;
00938
00939
00940 if (propVec[1] >= 0.0F)
00941 return (propVec[1] >= interestThresh);
00942
00943 else
00944 return (fabs(propVec[5]) >= uxyThresh);
00945 }
00946
00947
00948 bool VisualEventSet::doesEventExist(uint eventNum) const
00949 {
00950 std::list<VisualEvent>::const_iterator evt;
00951 for (evt = itsEvents.begin(); evt != itsEvents.end(); ++evt)
00952 if (evt->getEventNum() == eventNum) return true;
00953
00954 return false;
00955 }
00956
00957
00958 VisualEvent VisualEventSet::getEventByNumber(uint eventNum) const
00959 {
00960 std::list<VisualEvent>::const_iterator evt;
00961 for (evt = itsEvents.begin(); evt != itsEvents.end(); ++evt)
00962 if (evt->getEventNum() == eventNum) return *evt;
00963
00964 LFATAL("Event with number %i does not exist.",eventNum);
00965
00966 return *evt;
00967 }
00968
00969
00970 std::vector<std::list<VisualEvent>::iterator>
00971 VisualEventSet::getEventsForFrame(uint framenum)
00972 {
00973 std::vector<std::list<VisualEvent>::iterator> result;
00974 std::list<VisualEvent>::iterator event;
00975 for (event = itsEvents.begin(); event != itsEvents.end(); ++event)
00976 if (event->isFrameOk(framenum)) result.push_back(event);
00977
00978 return result;
00979 }
00980
00981
00982
00983
00984
00985