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
00038 #include "Apps/BorderWatch/BorderWatchQt.qt.H"
00039
00040 #include <QtCore/QTimer>
00041 #include <QtGui/QLabel>
00042 #include <QtGui/QVBoxLayout>
00043 #include <QtGui/QHBoxLayout>
00044 #include <QtGui/QListWidget>
00045 #include <QtGui/QSplitter>
00046 #include <QtGui/QFrame>
00047 #include <QtGui/QProgressBar>
00048 #include <QtGui/QLineEdit>
00049 #include <QtGui/QCheckBox>
00050
00051 #include "Apps/BorderWatch/BorderWatchData.H"
00052 #include "Image/DrawOps.H"
00053 #include "Image/ShapeOps.H"
00054 #include "QtUtil/ImageConvert4.H"
00055 #include "Raster/GenericFrame.H"
00056 #include "Util/log.H"
00057 #include "Util/sformat.H"
00058
00059 #include <cstdio>
00060
00061
00062 BorderWatchQt::BorderWatchQt(std::vector<GenericFrame>& frames, std::vector<BorderWatchData>& data, QWidget* parent) :
00063 QWidget(parent), itsThreshold(4.0e-10F), itsFrames(frames), itsLogData(data), itsListIndex(0),
00064 itsMovieFrame(0), itsZoomed(false)
00065 {
00066 QVBoxLayout *main = new QVBoxLayout(this);
00067 main->setSpacing(4);
00068 main->setMargin(2);
00069
00070 QSplitter* splitter = new QSplitter(Qt::Horizontal, this);
00071 splitter->setChildrenCollapsible(false);
00072
00073 itsListWidget = new QListWidget(this);
00074 itsListWidget->setMinimumWidth(180);
00075
00076 splitter->addWidget(itsListWidget);
00077 connect(itsListWidget, SIGNAL(currentRowChanged(int)), this, SLOT(listChanged(int)));
00078
00079 QFrame *frame = new QFrame(this);
00080 frame->setFrameShape(QFrame::StyledPanel);
00081
00082 QVBoxLayout *panel = new QVBoxLayout;
00083
00084 QHBoxLayout *ed = new QHBoxLayout;
00085 ed->addStretch(1);
00086
00087 QLabel *lbl = new QLabel("Threshold:", this);
00088 ed->addWidget(lbl);
00089
00090 itsThreshEdit = new QLineEdit(sformat("%g", itsThreshold).c_str(), this);
00091 ed->addWidget(itsThreshEdit);
00092 connect(itsThreshEdit, SIGNAL(editingFinished()), this, SLOT(threshChanged()));
00093
00094 ed->addStretch(1);
00095
00096 QLabel *lbl2 = new QLabel(" Zoom X2:", this);
00097 ed->addWidget(lbl2);
00098
00099 QCheckBox *chk = new QCheckBox(this);
00100 chk->setCheckState(Qt::Checked); itsZoomed = true;
00101 connect(chk, SIGNAL(stateChanged(int)), this, SLOT(zoomChanged(int)));
00102 ed->addWidget(chk);
00103
00104 ed->addStretch(1);
00105
00106 panel->addLayout(ed);
00107
00108 QFrame* hline = new QFrame(this);
00109 hline->setFrameShape(QFrame::HLine);
00110 hline->setFrameShadow(QFrame::Raised);
00111 hline->setLineWidth(2);
00112 panel->addWidget(hline);
00113
00114 panel->addStretch(1);
00115
00116 QHBoxLayout* himage = new QHBoxLayout;
00117 himage->addStretch(1);
00118 itsFrameWidget = new QLabel(this);
00119 himage->addWidget(itsFrameWidget);
00120 himage->addStretch(1);
00121
00122 panel->addLayout(himage);
00123
00124 panel->addStretch(1);
00125
00126 itsProgressBar = new QProgressBar(this);
00127 panel->addWidget(itsProgressBar);
00128
00129 panel->addStretch(1);
00130
00131 frame->setLayout(panel);
00132 splitter->addWidget(frame);
00133
00134 splitter->setStretchFactor(0, 1);
00135 splitter->setStretchFactor(1, 7);
00136
00137 splitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00138 main->addWidget(splitter);
00139
00140 itsStatusLabel = new QLabel("Status: Idle.", this);
00141 itsStatusLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
00142 main->addWidget(itsStatusLabel);
00143
00144 this->setLayout(main);
00145
00146
00147 parseEvents();
00148
00149
00150 itsTimer = new QTimer(this);
00151 itsTimer->setInterval(33);
00152 connect(itsTimer, SIGNAL(timeout()), this, SLOT(timerTick()));
00153 itsTimer->start();
00154 }
00155
00156
00157 BorderWatchQt::~BorderWatchQt()
00158 {
00159 itsTimer->stop();
00160 }
00161
00162
00163 void BorderWatchQt::listChanged(const int idx)
00164 {
00165 itsListIndex = idx;
00166 if (itsEvents.size()) {
00167 const uint estart = itsEvents[idx].start, eend = itsEvents[idx].end;
00168
00169 itsListWidget->setCurrentRow(itsListIndex);
00170 itsMovieFrame = estart;
00171 itsProgressBar->setRange(estart, eend - 1);
00172 itsProgressBar->setValue(estart);
00173
00174
00175 float mscore = 0.0F;
00176 for (uint i = estart; i < eend; ++i) mscore = std::max(mscore, itsLogData[i].score);
00177
00178 itsStatusLabel->setText(sformat("Event %d || Frames: %06u - %06u || Max Score: %g", idx,
00179 estart, eend-1, mscore).c_str());
00180 }
00181 }
00182
00183
00184 void BorderWatchQt::parseEvents()
00185 {
00186 itsEvents.clear(); itsListWidget->clear(); bool inevent = false; const uint margin = 33; uint i = 0;
00187 char buf[100]; uint count = 0;
00188 std::vector<BorderWatchData>::const_iterator itr = itsLogData.begin(), stop = itsLogData.end();
00189 BWevent e;
00190 while (itr != stop) {
00191
00192 if (itr->score >= itsThreshold) {
00193 count = 0;
00194
00195 if (inevent == false)
00196 { inevent = true; e.start = i; if (e.start <= margin) e.start = 0; else e.start -= margin; }
00197 }
00198
00199
00200 if (inevent && count > margin) {
00201 inevent = false; count = 0; e.end = i;
00202 itsEvents.push_back(e);
00203 snprintf(buf, 100, "%04"ZU": %06u-%06u", itsEvents.size(), e.start, e.end);
00204 itsListWidget->addItem(buf);
00205 }
00206 ++itr; ++i; ++count;
00207 }
00208
00209
00210 if (inevent) {
00211 e.end = itsLogData.size()-1;
00212 itsEvents.push_back(e);
00213 snprintf(buf, 100, "%04"ZU": %06u-%06u", itsEvents.size(), e.start, e.end);
00214 itsListWidget->addItem(buf);
00215 }
00216
00217
00218 listChanged(0);
00219
00220 snprintf(buf, 100, "Extracted %"ZU" events above threshold = %e", itsEvents.size(), itsThreshold);
00221 itsStatusLabel->setText(buf);
00222 }
00223
00224
00225 void BorderWatchQt::timerTick()
00226 {
00227 if (itsEvents.size()) {
00228
00229 GenericFrame genframe = itsFrames[itsMovieFrame];
00230 Image<PixRGB<byte> > im = genframe.asRgbU8();
00231 if (itsZoomed) im = quickInterpolate(im, 2);
00232 BorderWatchData& d = itsLogData[itsMovieFrame];
00233
00234
00235 Point2D<int> p = d.salpoint; if (itsZoomed) { p.i *= 2; p.j *= 2; }
00236 if (d.score > itsThreshold) drawCircle(im, p, itsZoomed ? 30 : 15, PixRGB<byte>(255,255,0), 2);
00237 else drawCircle(im, p, itsZoomed ? 10 : 5, PixRGB<byte>(0,128,0), 1);
00238 writeText(im, Point2D<int>(10,0), sformat("%s - S=%g %06d", d.itime.c_str(), d.score, d.iframe).c_str(),
00239 PixRGB<byte>(255, 64, 0), PixRGB<byte>(0), SimpleFont::FIXED(6), true);
00240
00241
00242 QPixmap pixmap = convertToQPixmap4(im);
00243 itsFrameWidget->setPixmap(pixmap);
00244
00245
00246 itsProgressBar->setValue(itsMovieFrame);
00247
00248
00249 ++itsMovieFrame; if (itsMovieFrame >= itsEvents[itsListIndex].end) itsMovieFrame = itsEvents[itsListIndex].start;
00250 }
00251 }
00252
00253
00254 void BorderWatchQt::threshChanged()
00255 {
00256 QString txt = itsThreshEdit->text(); bool ok;
00257 float t = txt.toFloat(&ok);
00258
00259 if (ok) { itsThreshold = t; parseEvents(); }
00260 else itsStatusLabel->setText("Invalid threshold value");
00261 }
00262
00263
00264 void BorderWatchQt::zoomChanged(int state)
00265 {
00266 if (state == Qt::Checked) itsZoomed = true; else itsZoomed = false;
00267 }
00268
00269
00270
00271
00272
00273
00274