// ###################################################################### void NeoBrain::init(Dims imageDims, int nPoints, int wz ) { win_size = wz; #ifdef HAVE_OPENCV MAX_COUNT = nPoints; count = 0; points[0] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0])); points[1] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0])); prev_grey = Image<byte>(imageDims, ZEROS); pyramid = cvCreateImage( cvSize(imageDims.w(), imageDims.h()), 8, 1 ); prev_pyramid = cvCreateImage( cvSize(imageDims.w(), imageDims.h()), 8, 1 ); status = (char*)cvAlloc(MAX_COUNT); #endif flags = 0; itsState = CHECK_TARGET; itsImageDims = imageDims; itsTracking = false; if (itsSpeakSaliency.getVal()) { itsSpeechSynth->sendCommand("(lex.add.entry '(\"bigpause\" n (((pau) 1) ((pau) 1) ((pau) 1) ((pau) 1))))\n", -10, true); itsSpeechSynth->sendCommand("(set! daisy (wave.load \"daisy.wav\"))", -10, true); itsSpeechSynth->sendCommand("(set! headinfo (wave.load \"headInfo.wav\"))", -10, true); } }
void BitObject::drawOutline(Image<T_or_RGB>& img, const T_or_RGB& color, float opacity) { ASSERT(isValid()); ASSERT(img.initialized()); float op2 = 1.0F - opacity; Dims d = img.getDims(); Image<byte> mask = getObjectMask(); // rescale if needed if (d != itsImageDims) mask = rescaleNI(mask, d.w(), d.h()); // object-shaped drawing int thick = 1; Image<byte> om(mask); om = contour2D(om); // compute binary contour image const int w = img.getWidth(); const int h = img.getHeight(); Point2D<int> ppp; for (ppp.j = 0; ppp.j < h; ppp.j ++) for (ppp.i = 0; ppp.i < w; ppp.i ++) if (om.getVal(ppp.i, ppp.j)) // got a contour point -> draw here drawDisk(img, ppp, thick, T_or_RGB(img.getVal(ppp) * op2 + color * opacity)); // small disk for each point } // end drawOutline
// ###################################################################### Image<float> downSizeClean(const Image<float>& src, const Dims& new_dims, const int filterWidth) { GVX_TRACE(__PRETTY_FUNCTION__); if (src.getDims() == new_dims) return src; ASSERT(new_dims.isNonEmpty()); ASSERT(filterWidth >= 1); Image<float> result = src; while (result.getWidth() > new_dims.w() * 2 && result.getHeight() > new_dims.h() * 2) { if (filterWidth == 1) { result = decX(result); result = decY(result); } else if (filterWidth == 2) { result = quickLocalAvg2x2(result); } else { result = decX(lowPassX(filterWidth, result)); result = decY(lowPassY(filterWidth, result)); } } return rescaleBilinear(result, new_dims); }
VideoFileInfo getVideoFileInfoFromFilename(const std::string& fname) { VideoFileInfo result; std::string base; std::string ext = nodotExtension(fname, &base); LDEBUG("ext is %s", ext.c_str()); if (ext.compare("gz") == 0) { ext = nodotExtension(base, &base); LDEBUG("new ext is %s", ext.c_str()); result.ctype = COMP_GZIP; } else if (ext.compare("bz2") == 0) { ext = nodotExtension(base, &base); LDEBUG("new ext is %s", ext.c_str()); result.ctype = COMP_BZIP2; } else { result.ctype = COMP_NONE; } const std::string dimsstr = nodotExtension(base); LDEBUG("dimsstr is '%s'", dimsstr.c_str()); if (dimsstr.size() == 0) { LERROR("no <width>x<height> specification found in '%s'; " "assuming default dims of %dx%d instead", fname.c_str(), defaultDims.w(), defaultDims.h()); result.dims = defaultDims; // we didn't get explicit dims, so let's be picky about the // file size matching the defaultDims (--yuv-dims), unless the // user also requests loose matching (--yuv-dims-loose) result.beStrict = strictLength; } else { result.dims = fromStr<Dims>(dimsstr); LDEBUG("parsed dims as %dx%d", result.dims.w(), result.dims.h()); // OK, the user gave us some explicit dims, so let's not be // picky about whether the file size matches the // dims+pixformat result.beStrict = false; } result.format = fromStr<VideoFormat>(ext); return result; }
void Logger::saveSingleEventFrame(MbariImage< PixRGB<byte> >& img, int frameNum, MbariVisualEvent::VisualEvent *event) { ASSERT(event->frameInRange(frameNum)); // create the file stem string evnum; if (itsSaveEventFeatures.getVal().length() > 0) evnum = sformat("%s_evt%04d_", itsSaveEventFeatures.getVal().c_str(), event->getEventNum() ); else evnum = sformat("evt%04d_", event->getEventNum()); Dims maxDims = event->getMaxObjectDims(); Dims d((float)maxDims.w()*itsScaleW, (float)maxDims.h()*itsScaleH); // compute the correct bounding box and cut it out Rectangle bbox1 = event->getToken(frameNum).bitObject.getBoundingBox(); Rectangle bbox = Rectangle::tlbrI(bbox1.top()*itsScaleH, bbox1.left()*itsScaleW, bbox1.bottomI()*itsScaleH, bbox1.rightI()*itsScaleW); //Point2D cen = event.getToken(frameNum).bitObject.getCentroid(); // first the horizontal direction int wpad = (d.w() - bbox.width()) / 2; int ll = bbox.left() - wpad; //int ll = cen.i - d.w() / 2; int rr = ll + d.w(); if (ll < 0) { rr -= ll; ll = 0; } if (rr >= img.getWidth()) { rr = img.getWidth() - 1; ll = rr - d.w(); } // now the same thing with the vertical direction int hpad = (d.h() - bbox.height()) / 2; int tt = bbox.top() - hpad; //int tt = cen.j - d.h() / 2; int bb = tt + d.h(); if (tt < 0) { bb -= tt; tt = 0; } if (bb >= img.getHeight()) { bb = img.getHeight() - 1; tt = bb - d.h(); } Rectangle bboxFinal = Rectangle::tlbrI(tt, ll, bb, rr); bboxFinal = bboxFinal.getOverlap(Rectangle(Point2D<int>(0, 0), img.getDims() - 1)); // scale if needed and cut out the rectangle and save it Image< PixRGB<byte> > cut = crop(img, bboxFinal); itsOfs->writeFrame(GenericFrame(cut), evnum, FrameInfo(evnum, SRC_POS)); }
// ###################################################################### void TaskRelevanceMapSocial::inputFrame(const InputFrame& f) { const Dims mapdims = f.getDims(); const int sml = itsLevelSpec.getVal().mapLevel(); const float EyeVal = 128.0F, MouthVal = 64.0F, FaceVal = 32.0F, BodyVal = 16.0F, PersonVal = 4.0F, BkgdVal = 1.0F; Image<float> BigMap; BigMap.resize(mapdims, true); BigMap.clear(1.0F); Scene sceneData = itsObjectsInfo->getSceneData(itsFrame); // loop through all the regions on a given frame and assign z-stack order std::vector<float> weights(itsNumObjects, 1.0F); for (std::vector<Object>::iterator itrObject = sceneData.objects.begin(); itrObject != sceneData.objects.end(); itrObject++) { uint idx = (*itrObject).id; std::string ObjName = toLowerCase(itsObjectsNames[idx]); if (ObjName.find("eye") != std::string::npos) {weights[idx] = EyeVal;} else if (ObjName.find("mouth") != std::string::npos) {weights[idx] = MouthVal;} else if (ObjName.find("head") != std::string::npos || ObjName.find("face") != std::string::npos) {weights[idx] = FaceVal;} else if (ObjName.find("body") != std::string::npos) {weights[idx] = BodyVal;} else if (ObjName.find("person") != std::string::npos || ObjName.find("people") != std::string::npos || ObjName.find("man") != std::string::npos || ObjName.find("woman") != std::string::npos) {weights[idx] = PersonVal;} else {weights[idx] = BkgdVal;} } uint i,j,tmp; // sort z-stack weights const uint numInScene = sceneData.objects.size(); std::vector<uint> zorder(numInScene); for (i = 0; i < numInScene; i++) zorder[i] = i; for (i = 0; i < numInScene; i++) for (j = 0; j < numInScene-i-1; j++) if(weights[sceneData.objects[zorder[j]].id] > weights[sceneData.objects[zorder[j+1]].id]) { tmp = zorder[j]; zorder[j] = zorder[j+1]; zorder[j+1] = tmp; } // fill BigMap from bottom of z-stack to top // todo: enforce C0/C1 continuity by some poisson problem? for (i = 0; i < numInScene; i++) { Object iObj = sceneData.objects[zorder[i]]; drawFilledPolygon(BigMap, iObj.polygon, weights[iObj.id]); } itsMap = rescale(BigMap, mapdims.w() >> sml, mapdims.h() >> sml); itsFrame++; }
// ###################################################################### Dims ForegroundDetectionChannel::getMapDims() const { if (!this->hasInput()) LFATAL("Oops! I haven't received any input yet"); const Dims indims = this->getInputDims(); return Dims(indims.w() >> itsLevelSpec.getVal().mapLevel(), indims.h() >> itsLevelSpec.getVal().mapLevel()); }
// ###################################################################### Dims ResizeSpec::transformDims(const Dims& in) { switch (itsMethod) { case NOOP: return in; break; case FIXED: return itsNewDims; break; case SCALE_UP: // if a scale factor is 0, then that dimension just passes // through untouched return Dims(itsFactorW > 0.0 ? int(0.5 + in.w() * itsFactorW) : in.w(), itsFactorH > 0.0 ? int(0.5 + in.h() * itsFactorH) : in.h()); break; case SCALE_DOWN: // if a scale factor is 0, then that dimension just passes // through untouched return Dims(itsFactorW > 0.0 ? int(0.5 + in.w() / itsFactorW) : in.w(), itsFactorH > 0.0 ? int(0.5 + in.h() / itsFactorH) : in.h()); break; } // we should never get here, because even if the user gave bogus // input, we should have caught that in convertFromString() or // wherever, so that once we have a ResizeSpec object, it should be // guaranteed to have a valid itsMethod value: ASSERT(0); /* can't happen */ return Dims(); }
// ###################################################################### Button::Button(Point2D<int> topLeft,Dims dims ) { itsTopLeftPoint = topLeft; itsCenterPoint = Point2D<int>(topLeft.i+dims.w()/2,topLeft.j+dims.h()/2); itsDims = dims; itsRectangle = Rectangle(topLeft,dims); itsBgColor = PixRGB<byte>(0,255,0); itsBorderColor = PixRGB<byte>(255,255,255); itsLabelColor = PixRGB<byte>(255,255,255); itsFontSize = 20; itsBorderThickness = 0; }
void BitObject::drawShape(Image<T_or_RGB>& img, const T_or_RGB& color, float opacity) { ASSERT(isValid()); ASSERT(img.initialized()); Dims d = img.getDims(); Image<byte> mask = itsObjectMask; Rectangle bbox = itsBoundingBox; // rescale if needed if (d != itsImageDims) { float scaleW = (float) d.w() / (float) itsImageDims.w(); float scaleH = (float) d.h() / (float) itsImageDims.h(); int i = (int) ((float) bbox.left() * scaleW); int j = (int) ((float) bbox.top() * scaleH); int w = (int) ((float) bbox.width() * scaleW); int h = (int) ((float) bbox.height() *scaleH); const Point2D<int> topleft(i,j); bbox = Rectangle(topleft, Dims(w,h)); mask = rescaleNI(mask, d.w(), d.h()); } int w = img.getWidth(); float op2 = 1.0F - opacity; typename Image<T_or_RGB>::iterator iptr, iptr2; Image<byte>::const_iterator mptr = mask.begin(); iptr2 = img.beginw() + bbox.top() * w + bbox.left(); for (int y = bbox.top(); y <= bbox.bottomI(); ++y) { iptr = iptr2; for (int x = bbox.left(); x <= bbox.rightI(); ++x) { if (*mptr > 0) *iptr = T_or_RGB(*iptr * op2 + color * opacity); ++iptr; ++mptr; } iptr2 += w; } }
void NeuralSimModule<T>::setModel(const std::string& model_name, const Dims& dims, const SimTime& starttime) { //set our border policy based on wether we are using space variant boundaries or not BorderPolicy bp = (itsUseSpaceVariantBoundary.getVal()) ? CROSS_HEMI : NONE; //change any factory parameters uint w = dims.w(); uint h = dims.h(); nsu::setParameter(nsu::SimStructure::Factory::instance(), bp, itsSCtimestep.getVal(), w, h); //reset the module LINFO("model type: %s", model_name.c_str()); itsStructure.reset(nsu::SimStructure::Factory::instance().createConvert<T*>(model_name)); itsStructure->setTime(starttime); //setup plotting range nsu::NormalizeType ntype; Range<double> itsRange = itsDisplayRange.getVal(); if ((itsRange.min() < 0) && (itsRange.max() < 0))//if both are less than 0 scale { ntype = nsu::SCALE; itsRange = Range<double>(0.0,0.0); } else if ((itsRange.min() == 0) && (itsRange.max() == 0))//set to min/max of data ntype = nsu::RANGE; else //set to auto scale at each time ntype = nsu::SET_RANGE; //set a decode if desired and initialize plotting if (itsDecoderType.getVal().compare("None") != 0) { nsu::NeuralDecoder* nd = nsu::NeuralDecoder::Factory::instance().create(itsDecoderType.getVal()); itsPlot.reset(new nsu::StructurePlot(*itsStructure, *nd, its2DPlotDepth.getVal(), ntype, itsRange.min(), itsRange.max())); delete nd; } else itsPlot.reset(new nsu::StructurePlot(*itsStructure, its2DPlotDepth.getVal(), ntype, itsRange.min(), itsRange.max())); //update our probe position and set sampling rate for display text itsPlot->setSamplingRate(itsStructure->getTimeStep()); nsu::Location location(itsProbe.getVal()); itsPlot->setProbe(location); //setup image set to hold input const uint depth = (itsStructure->numSubs() < 1) ? 2 : itsStructure->numSubs()+1; itsInput = ImageSet<double>(depth); itsInputGain = std::vector<double>(depth, 1.0); }
// ###################################################################### void TaskRelevanceMapAdapter:: onSimEventRetinaImage(SimEventQueue& q, rutz::shared_ptr<SimEventRetinaImage>& e) { const Dims d = e->frame().colorByte().getDims(); const int sml = itsLevelSpec.getVal().mapLevel(); const Dims mapdims(d.w() >> sml, d.h() >> sml); // great, here is a new input image. Initialize our map if needed: if (itsMap.getDims() != mapdims) { itsMap.resize(mapdims,true); itsMap.clear(1.0F); // neutral relevance } // now do any implementation-specific processing: this->inputFrame(e->frame()); }
void BitObject::drawBoundingBox(Image<T_or_RGB>& img, const T_or_RGB& color, float opacity) { ASSERT(isValid()); ASSERT(img.initialized()); Rectangle bbox = itsBoundingBox; // rescale if needed if (img.getDims() != itsImageDims) { Dims d = img.getDims(); float scaleW = (float) d.w() / (float) itsImageDims.w(); float scaleH = (float) d.h() / (float) itsImageDims.h(); int i = (int) ((float) bbox.left() * scaleW); int j = (int) ((float) bbox.top() * scaleH); int w = (int) ((float) bbox.width() * scaleW); int h = (int) ((float) bbox.height() *scaleH); const Point2D<int> topleft(i,j); bbox = Rectangle(topleft, Dims(w,h)); } float op2 = 1.0F - opacity; int t = bbox.top(); int b = bbox.bottomI(); int l = bbox.left(); int r = bbox.rightI(); for (int x = l; x <= r; ++x) { Point2D<int> p1(x,t), p2(x,b); img.setVal(p1,img.getVal(p1) * op2 + color * opacity); img.setVal(p2,img.getVal(p2) * op2 + color * opacity); } for (int y = t+1; y < b; ++y) { Point2D<int> p1(l,y), p2(r,y); img.setVal(p1,img.getVal(p1) * op2 + color * opacity); img.setVal(p2,img.getVal(p2) * op2 + color * opacity); } }
void DetectionParametersSingleton::initialize(DetectionParameters &p, const Dims &dims, const int foaRadius) { DetectionParametersSingleton *dp = instance(); // calculate cost parameter from other derived values // initialize parameters const int maxDist = dims.w() / MAX_DIST_RATIO; float maxAreaDiff = maxDist * maxDist / 4.0F; float maxDistFloat = (float) maxDist; if (p.itsTrackingMode == TMKalmanFilter || p.itsTrackingMode == TMKalmanHough || p.itsTrackingMode == TMHough ) p.itsMaxCost = pow(maxDistFloat,2.0F); else p.itsMaxCost = maxDist; p.itsMaxDist = maxDist; if (p.itsMinEventArea == 0) p.itsMinEventArea = foaRadius; if (p.itsMaxEventArea == 0) p.itsMaxEventArea = foaRadius * MAX_SIZE_FACTOR; dp->itsParameters = p; }
void VisualTracker::initTracker(Dims imageDims) { #ifdef HAVE_OPENCV itsMaxNumPoints = 1; itsCurrentNumPoints = 0; itsCurrentPoints = (CvPoint2D32f*)cvAlloc(itsMaxNumPoints*sizeof(itsCurrentPoints)); itsPreviousPoints = (CvPoint2D32f*)cvAlloc(itsMaxNumPoints*sizeof(itsPreviousPoints)); itsPreviousGreyImg = Image<byte>(imageDims, ZEROS); itsCurrentPyramid = cvCreateImage( cvSize(imageDims.w(), imageDims.h()), 8, 1 ); itsPreviousPyramid = cvCreateImage( cvSize(imageDims.w(), imageDims.h()), 8, 1 ); itsTrackStatus = (char*)cvAlloc(itsMaxNumPoints); itsTrackError = (float*)cvAlloc(itsMaxNumPoints); if (itsUseKalman) { itsKalman = cvCreateKalman(4, //Dim of state vector x,y,dx,dy 2); //dim of mesurment vector x,y //State transition matrix //x y dx dy const float A[] = { 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1}; //Observation matrix const float H[] = { 1, 0, 0, 0, 0, 1, 0, 0}; //set the transition and mesurment matrix memcpy( itsKalman->transition_matrix->data.fl, A, sizeof(A)); memcpy( itsKalman->measurement_matrix->data.fl, H, sizeof(H)); //Set the process and measurment noise cvSetIdentity( itsKalman->process_noise_cov, cvRealScalar(1e-5) ); cvSetIdentity( itsKalman->measurement_noise_cov, cvRealScalar(1e-1) ); /*posteriori error estimate covariance matrix (P(k)): P(k)=(I-K(k)*H)*P'(k) */ cvSetIdentity( itsKalman->error_cov_post, cvRealScalar(1)); cvZero(itsKalman->state_post); /* corrected state (x(k)): x(k)=x'(k)+K(k)*(z(k)-H*x'(k)) */ cvZero(itsKalman->state_pre); /* predicted state (x'(k)): x(k)=A*x(k-1)+B*u(k) */ } // //camshift // int hdims = 16; // float hranges_arr[] = {0,180}; // float* hranges = hranges_arr; // // itsObjectHist = cvCreateHist( 1, &hdims, CV_HIST_ARRAY, &hranges, 1 ); // itsBackproject = cvCreateImage( cvSize(imageDims.w(), imageDims.h()), 8, 1 ); itsTrackFlags = 0; #endif itsInitTracker = false; }
// ###################################################################### LogPolarTransform::LogPolarTransform(const Dims& indims, const Dims& outdims, const double deg_per_pixel, const double step) : itsInDims(indims), itsOutDims(outdims) { const int w = indims.w(); const int h = indims.h(); Range<double> xrng; Range<double> yrng; const double A = 3.0; const double B_x = 1.4; const double B_y = 1.8; for (int j = 0; j < h; ++j) for (int i = 0; i < w; ++i) { if (j > 0 && j < h-1 && i > 0 && i < w-1) continue; const double x = (i - w / 2.0) * deg_per_pixel; const double y = (j - h / 2.0) * deg_per_pixel; const double sx = (x < 0.0) ? 1.0 : -1.0; const double r = sqrt(x*x + y*y); const double th = atan2(y, fabs(x)); const double X = sx * B_x * log(sqrt(r*r + 2*A*r*cos(th) + A*A) / A); const double Y = -B_y * atan(r*sin(th) / (r*cos(th) + A)); // (s * X / B_x) = log(sqrt(r*r + 2*A*r*cos(th) + A*A) / A) // exp(s* X / B_x) = sqrt(r*r + 2*A*r*cos(th) + A*A) / A // A * exp(s* X / B_x) = sqrt(r*r + 2*A*r*cos(th) + A*A) xrng.merge(X); yrng.merge(Y); } const double scale = std::min((outdims.w() - 1) / xrng.range(), (outdims.h() - 1) / yrng.range()); const int dw = outdims.w(); for (double j = 0; j < h; j += step) for (double i = 0; i < w; i += step) { const double x = (i - w / 2.0) * deg_per_pixel; const double y = (j - h / 2.0) * deg_per_pixel; const double sx = (x < 0.0) ? 1.0 : -1.0; const double r = sqrt(x*x + y*y); const double th = atan2(y, fabs(x)); const double X = sx * B_x * log(sqrt(r*r + 2*A*r*cos(th) + A*A) / A); const double Y = -B_y * atan(r*sin(th) / (r*cos(th) + A)); //if (!isFinite(X)) //LINFO("i,j = %f,%f", i, j); // (s * X / B_x) = log(sqrt(r*r + 2*A*r*cos(th) + A*A) / A) // exp(s* X / B_x) = sqrt(r*r + 2*A*r*cos(th) + A*A) / A // A * exp(s* X / B_x) = sqrt(r*r + 2*A*r*cos(th) + A*A) if (isFinite(X)) { const int NX = int((X - xrng.min()) * scale); const int NY = int((Y - yrng.min()) * scale); std::pair<int, int> p(int(j)*w + int(i), NY*dw + NX); if ((p.second > 0) && (p.second < itsOutDims.sz())) itsCoords.push_back(p); } } }
// ###################################################################### void DescriptorVec::buildRawDV() { bool salientLocationWithinSubmaps = true; Point2D<int> objSalientLoc(-1,-1); //the feature location const LevelSpec lspec = itsComplexChannel->getModelParamVal<LevelSpec>("LevelSpec"); const int smlevel = lspec.mapLevel(); int x=int(itsFoveaLoc.i / double(1 << smlevel) + 0.49); int y=int(itsFoveaLoc.j / double(1 << smlevel) + 0.49); int foveaW = int(itsFoveaSize.getVal().w() / double(1 << smlevel) + 0.49); int foveaH = int(itsFoveaSize.getVal().h() / double(1 << smlevel) + 0.49); int tl_x = x - (foveaW/2); int tl_y = y - (foveaH/2); Dims mapDims = itsComplexChannel->getSubmap(0).getDims(); //Shift the fovea location so we dont go outside the image //Sift the fovea position if nessesary if (tl_x < 0) tl_x = 0; if (tl_y < 0) tl_y = 0; if (tl_x+foveaW > mapDims.w()) tl_x = mapDims.w() - foveaW; if (tl_y+foveaH > mapDims.h()) tl_y = mapDims.h() - foveaH; if (!salientLocationWithinSubmaps) { //Find the most salient location within the fovea Image<float> SMap = itsComplexChannel->getOutput(); Image<float> tmp = SMap; //TODO need to resize to fovea //Find the max location within the fovea float maxVal; Point2D<int> maxLoc; findMax(tmp, maxLoc, maxVal); //convert back to original SMap cordinates // objSalientLoc.i=tl_x+maxLoc.i; // objSalientLoc.j=tl_y+maxLoc.j; objSalientLoc.i=x; objSalientLoc.j=y; itsAttentionLoc = objSalientLoc; } //Go through all the submaps building the DV itsFV.clear(); //clear the FV uint numSubmaps = itsComplexChannel->numSubmaps(); for (uint i = 0; i < numSubmaps; i++) { //Image<float> submap = itsComplexChannel->getSubmap(i); Image<float> submap = itsComplexChannel->getRawCSmap(i); // resize submap to fixed scale if necessary: if (submap.getWidth() > mapDims.w()) submap = downSize(submap, mapDims); else if (submap.getWidth() < mapDims.w()) submap = rescale(submap, mapDims); //TODO convert to quickInterpolate if (salientLocationWithinSubmaps) //get the location from the salient location within each submap { Image<float> tmp = submap; //get only the fovea region if (foveaW < tmp.getWidth()) //crop if our fovea is smaller tmp = crop(tmp, Point2D<int>(tl_x, tl_y), Dims(foveaW, foveaH)); // tmp = maxNormalize(tmp, 0.0F, 10.0F, VCXNORM_MAXNORM); //find salient locations //Find the max location within the fovea float maxVal; Point2D<int> maxLoc; findMax(tmp, maxLoc, maxVal); //LINFO("%i: Max val %f, loc(%i,%i)", i, maxVal, maxLoc.i, maxLoc.j); objSalientLoc.i=tl_x+maxLoc.i; objSalientLoc.j=tl_y+maxLoc.j; } if (objSalientLoc.i < 0) objSalientLoc.i = 0; if (objSalientLoc.j < 0) objSalientLoc.j = 0; if (objSalientLoc.i > submap.getWidth()-1) objSalientLoc.i = submap.getWidth()-1; if (objSalientLoc.j > submap.getHeight()-1) objSalientLoc.j = submap.getHeight()-1; // LINFO("Location from %i,%i: (%i,%i)", objSalientLoc.i, objSalientLoc.j, // submap.getWidth(), submap.getHeight()); float featureVal = submap.getVal(objSalientLoc.i,objSalientLoc.j); itsFV.push_back(featureVal); // SHOWIMG(rescale(submap, 255, 255)); } }
Image<T> downSize(const Image<T>& src, const Dims& dims, const int filterWidth) { return downSize(src, dims.w(), dims.h(), filterWidth); }
// ###################################################################### void Logger::run(nub::soft_ref<MbariResultViewer> rv, MbariImage<PixRGB <byte> >& img, MbariVisualEvent::VisualEventSet& eventSet, const Dims scaledDims) { // adjust scaling if needed Dims d = img.getDims(); itsScaleW = (float)d.w()/(float)scaledDims.w(); itsScaleH = (float)d.h()/(float)scaledDims.h(); // initialize property vector and FOE estimator MbariVisualEvent::PropertyVectorSet pvs; // this is a list of all the events that have a token in this frame std::list<MbariVisualEvent::VisualEvent *> eventFrameList; // this is a complete list of all those events that are ready to be written std::list<MbariVisualEvent::VisualEvent *> eventListToSave; // get event frame list for this frame and those events that are ready to be saved // this is a list of all the events that have a token in this frame eventFrameList = eventSet.getEventsForFrame(img.getFrameNum()); // this is a complete list of all those events that are ready to be written eventListToSave = eventSet.getEventsReadyToSave(img.getFrameNum()); // write out eventSet? if (itsSaveEventsName.getVal().length() > 0 ) saveVisualEvent(eventSet, eventFrameList); // write out summary ? if (itsSaveSummaryEventsName.getVal().length() > 0) saveVisualEventSummary(Version::versionString(), eventListToSave); // flag events that have been saved for delete std::list<MbariVisualEvent::VisualEvent *>::iterator i; for (i = eventListToSave.begin(); i != eventListToSave.end(); ++i) (*i)->flagWriteComplete(); // write out positions? if (itsSavePositionsName.getVal().length() > 0) savePositions(eventFrameList); MbariVisualEvent::PropertyVectorSet pvsToSave = eventSet.getPropertyVectorSetToSave(); // write out property vector set? if (itsSavePropertiesName.getVal().length() > 0) saveProperties(pvsToSave); // TODO: this is currently not used...look back in history to where this got cut-out // need to obtain the property vector set? if (itsLoadPropertiesName.getVal().length() > 0) pvs = eventSet.getPropertyVectorSet(); // get a list of events for this frame eventFrameList = eventSet.getEventsForFrame(img.getFrameNum()); // write out eventSet to XML? if (itsSaveXMLEventSetName.getVal().length() > 0) { saveVisualEventSetToXML(eventFrameList, img.getFrameNum(), img.getMetaData().getTC(), itsFrameRange); } const int circleRadiusRatio = 40; const int circleRadius = img.getDims().w() / circleRadiusRatio; Image< PixRGB<byte> > output = rv->createOutput(img, eventSet, circleRadius, itsScaleW, itsScaleH); // write ? if (itsSaveOutput.getVal()) itsOfs->writeFrame(GenericFrame(output), "results", FrameInfo("results", SRC_POS)); // display output ? rv->display(output, img.getFrameNum(), "Results"); // need to save any event clips? if (itsSaveEventNumsAll) { //save all events std::list<MbariVisualEvent::VisualEvent *>::iterator i; for (i = eventFrameList.begin(); i != eventFrameList.end(); ++i) saveSingleEventFrame(img, img.getFrameNum(), *i); } else { // need to save any particular event clips? uint csavenum = numSaveEventClips(); for (uint idx = 0; idx < csavenum; ++idx) { uint evnum = getSaveEventClipNum(idx); if (!eventSet.doesEventExist(evnum)) continue; MbariVisualEvent::VisualEvent *event = eventSet.getEventByNumber(evnum); if (event->frameInRange(img.getFrameNum())) saveSingleEventFrame(img, img.getFrameNum(), event); } } //flag events that have been saved for delete otherwise takes too much memory for (i = eventListToSave.begin(); i != eventListToSave.end(); ++i) (*i)->flagForDelete(); while (!eventFrameList.empty()) eventFrameList.pop_front(); while (!eventListToSave.empty()) eventListToSave.pop_front(); }
// ###################################################################### std::list<BitObject> ObjectDetection::run(nub::soft_ref<MbariResultViewer> rv, const std::list<Winner> &winlist, const Image< PixRGB<byte> > &segmentInImg) { DetectionParameters p = DetectionParametersSingleton::instance()->itsParameters; std::list<BitObject> bosFiltered; std::list<BitObject> bosUnfiltered; std::list<Winner>::const_iterator iter = winlist.begin(); //go through each winner and extract salient objects while (iter != winlist.end()) { // get the foa mask BitObject boFOA = (*iter).getBitObject(); WTAwinner winner = (*iter).getWTAwinner(); // if the foa mask area is too small, we aren't going to find any large enough objects so bail out if (boFOA.getArea() < p.itsMinEventArea) { iter++; continue; } // if only using the foamask region and not the foamask to guide the detection if (p.itsUseFoaMaskRegion) { LINFO("----------------->Using FOA mask region"); Rectangle foaregion = boFOA.getBoundingBox(); Point2D<int> center = boFOA.getCentroid(); Dims d = segmentInImg.getDims(); Dims segmentDims = Dims((float)foaregion.width()*2.0,(float)foaregion.height()*2.0); Dims searchDims = Dims((float)foaregion.width(),(float)foaregion.height()); Rectangle searchRegion = Rectangle::centerDims(center, searchDims); searchRegion = searchRegion.getOverlap(Rectangle(Point2D<int>(0, 0), segmentInImg.getDims() - 1)); Rectangle segmentRegion = Rectangle::centerDims(center, segmentDims); segmentRegion = segmentRegion.getOverlap(Rectangle(Point2D<int>(0, 0), segmentInImg.getDims() - 1)); // get the region used for searching for a match based on the foa region LINFO("Extracting bit objects from frame %d winning point %d %d/region %s minSize %d maxSize %d %d %d", \ (*iter).getFrameNum(), winner.p.i, winner.p.j, convertToString(searchRegion).c_str(), p.itsMinEventArea, p.itsMaxEventArea, d.w(), d.h()); std::list<BitObject> sobjs = extractBitObjects(segmentInImg, center, searchRegion, segmentRegion, (float)p.itsMinEventArea/2.F, p.itsMaxEventArea); std::list<BitObject> sobjsKeep; // need at least two objects to find a match, otherwise just background if (sobjs.size() > 1 ) { // set the winning voltage for each winning bit object std::list<BitObject>::iterator iter; for (iter = sobjs.begin(); iter != sobjs.end(); ++iter) { if ( (*iter).getArea() >= p.itsMaxEventArea && (*iter).getArea() <= p.itsMaxEventArea) { (*iter).setSMV(winner.sv); sobjsKeep.push_back(*iter); } } // add to the list bosUnfiltered.splice(bosUnfiltered.begin(), sobjsKeep); } else { LINFO("Can't find bit object, checking FOA mask"); if (boFOA.getArea() >= p.itsMinEventArea && boFOA.getArea() <= p.itsMaxEventArea) { boFOA.setSMV(winner.sv); sobjsKeep.push_back(boFOA); bosUnfiltered.splice(bosUnfiltered.begin(), sobjsKeep); LINFO("FOA mask ok %d < %d < %d", p.itsMinEventArea, boFOA.getArea(), p.itsMaxEventArea); } else LINFO("FOA mask too large %d > %d or %d > %d",boFOA.getArea(), p.itsMinEventArea, boFOA.getArea(), p.itsMaxEventArea); } } else { LINFO("----------------->Using FOA mask only"); if (boFOA.getArea() >= p.itsMinEventArea && boFOA.getArea() <= p.itsMaxEventArea) { boFOA.setSMV(winner.sv); bosUnfiltered.push_back(boFOA); LINFO("FOA mask ok %d < %d < %d", p.itsMinEventArea, boFOA.getArea(), p.itsMaxEventArea); } else LINFO("FOA mask too large %d > %d or %d > %d",boFOA.getArea(), p.itsMinEventArea, boFOA.getArea(), p.itsMaxEventArea); } iter++; }// end while iter != winners.end() LINFO("Found %i bitobject(s)", bosUnfiltered.size()); bool found; int minSize = p.itsMaxEventArea; // loop until we find all non-overlapping objects starting with the smallest while (!bosUnfiltered.empty()) { std::list<BitObject>::iterator biter, siter, smallest; // find the smallest object smallest = bosUnfiltered.begin(); for (siter = bosUnfiltered.begin(); siter != bosUnfiltered.end(); ++siter) if (siter->getArea() < minSize) { minSize = siter->getArea(); smallest = siter; } // does the smallest object intersect with any of the already stored ones found = true; for (biter = bosFiltered.begin(); biter != bosFiltered.end(); ++biter) { if (smallest->isValid() && biter->isValid() && biter->doesIntersect(*smallest)) { // no need to store intersecting objects -> get rid of smallest // and look for the next smallest bosUnfiltered.erase(smallest); found = false; break; } } if (found && smallest->isValid()) bosFiltered.push_back(*smallest); } LINFO("Found total %d non intersecting objects", bosFiltered.size()); return bosFiltered; }
Image<T> rescaleBilinear(const Image<T>& src, const Dims& dims) { return rescaleBilinear(src, dims.w(), dims.h()); }
Image<T> rescaleNI(const Image<T>& src, const Dims& dims) { return rescaleNI(src, dims.w(), dims.h()); }
// ###################################################################### FfmpegEncoder::FfmpegEncoder(const std::string& fname, const std::string& codecname, const int bitrate, const int framerate, const int frameratebase, const Dims& dims, const int bufsz, const bool useFormatContext) : itsFile(0), itsContext(), itsFormatContext(0), itsFrameNumber(0), itsOutbufSize(bufsz), itsFrameSizeRange(), itsUseFormatContext(useFormatContext) { GVX_TRACE(__PRETTY_FUNCTION__); // no need to guard these functions for being called multiple times; // they all have internal guards av_register_all(); avcodec_init(); avcodec_register_all(); AVOutputFormat* oformat = NULL; #if LIBAVCODEC_VERSION_MAJOR >= 53 && LIBAVCODEC_VERSION_MINOR >= 21 if (codecname.compare("List") == 0) { // list available codecs LINFO("##### Available output codecs (not all may work for video):"); AVOutputFormat* f = av_oformat_next(NULL); while(f) { LINFO("%s: %s %d", f->name, f->long_name, f->flags); f = av_oformat_next(f); } LFATAL("Please select a codec from this list"); } else { // format is given // no av_find_output_format()?? let's do it by hand... AVOutputFormat* f = av_oformat_next(NULL); while(f) { if (codecname.compare(f->name) == 0) { oformat = f; break; } f = av_oformat_next(f); } } #else if (codecname.compare("List") == 0) { // list available codecs LINFO("##### Available output codecs (not all may work for video):"); for(AVOutputFormat* f = first_oformat; f != NULL; f = f->next) LINFO("%s: %s %d", f->name, f->long_name, f->flags); LFATAL("Please select a codec from this list"); } else { // format is given // no av_find_output_format()?? let's do it by hand... for(AVOutputFormat* f = first_oformat; f != NULL; f = f->next) if (codecname.compare(f->name) == 0) { oformat = f; break; } } #endif if (oformat == 0) LFATAL("No such video codec '%s';\n" "try re-running with --output-codec=List to see a list\n" "of available codecs", codecname.c_str()); char ext[100]; ext[0] = '.'; uint i; for (i = 0; i < strlen(oformat->extensions); i ++) if (oformat->extensions[i] == ',') break; else ext[i+1] = oformat->extensions[i]; ext[i+1] = '\0'; LINFO("Using output format '%s' (%s), extension %s", oformat->name, oformat->long_name, ext); std::string oname(fname); std::string::size_type idx1 = oname.rfind('/', oname.npos); std::string::size_type idx2 = oname.rfind('.', oname.npos); // must check that idx2 is valid; otherwise if we do // oname.erase(idx2) with e.g. idx2==npos then we will get a // std::out_of_range exception if (idx2 < oname.size() && idx2 > idx1) oname.erase(idx2, oname.npos); oname.append(ext); LINFO("Output file: %s", oname.c_str()); if (itsUseFormatContext) { #ifdef INVT_FFMPEG_HAS_FORMATCONTEXT_FUNCTIONS LINFO("Using FormatContext to output data"); #ifdef AVMEDIA_TYPE_VIDEO itsFormatContext = avformat_alloc_context(); #else itsFormatContext = av_alloc_format_context(); #endif if (!itsFormatContext) LFATAL("Cannot allocate format context"); itsFormatContext->oformat = oformat; itsAVStream = av_new_stream(itsFormatContext, 0); if (!itsAVStream) LFATAL("Can not allocate AVStream"); #else LFATAL("Need a new version of ffmpeg libs for this option"); itsFormatContext = NULL; #endif } AVCodec* const codec = avcodec_find_encoder(oformat->video_codec); if (codec == NULL) LFATAL("codec not found"); #if defined(INVT_FFMPEG_HAS_DEFAULTS_FUNCTIONS) avcodec_get_context_defaults(&itsContext); #else { AVCodecContext* const tmp = avcodec_alloc_context(); memcpy(&itsContext, tmp, sizeof(AVCodecContext)); free(tmp); } #endif itsContext.bit_rate = bitrate; // Be sure to set itsContext.pix_fmt -- it may occasionally // appear to work to leave pix_fmt unset, because the value we want, // PIX_FMT_YUV420P, has the enum value of 0, so if the uninitialized // memory for pix_fmt happens to have the value 0, then we'll slip // through without setting it explicitly. itsContext.pix_fmt = PIX_FMT_YUV420P; /* resolution must be a multiple of two */ itsContext.width = dims.w(); itsContext.height = dims.h(); #if defined(INVT_FFMPEG_AVCODECCONTEXT_HAS_TIME_BASE) AVRational time_base = { frameratebase, framerate }; itsContext.time_base = time_base; const int frb = frameratebase; #elif LIBAVCODEC_VERSION_INT >= 0x000406 && LIBAVCODEC_BUILD > 4665 itsContext.frame_rate = framerate; const int frb = frameratebase; itsContext.frame_rate_base = frb; #else itsContext.frame_rate = framerate; const int frb = FRAME_RATE_BASE; #endif itsContext.gop_size = 10; /* emit one intra frame every ten frames */ if(codec->id != CODEC_ID_MPEG4 && codec->id != CODEC_ID_MPEG1VIDEO && codec->id != CODEC_ID_MPEG2VIDEO) itsContext.max_b_frames = 0; else itsContext.max_b_frames = 1; itsFrameNumber = 0; LINFO("using max_b_frames=%i bitrate=%u width=%u height=%u framerate=%u frameratebase=%u", itsContext.max_b_frames, itsContext.bit_rate, itsContext.width, itsContext.height, framerate, frb); if (avcodec_open(&itsContext, codec) < 0) LFATAL("could not open codec\n"); if (itsUseFormatContext) { #ifdef INVT_FFMPEG_HAS_FORMATCONTEXT_FUNCTIONS AVCodecContext *c = itsAVStream->codec; c->codec_id = itsContext.codec_id; #ifdef CODEC_TYPE_VIDEO c->codec_type = CODEC_TYPE_VIDEO; #else #ifdef AVMEDIA_TYPE_VIDEO c->codec_type = AVMEDIA_TYPE_VIDEO; #endif #endif /* put sample parameters */ c->bit_rate = itsContext.bit_rate; /* resolution must be a multiple of two */ c->width = itsContext.width; c->height = itsContext.height; /* time base: this is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented. for fixed-fps content, timebase should be 1/framerate and timestamp increments should be identically 1. */ #if defined(INVT_FFMPEG_AVCODECCONTEXT_HAS_TIME_BASE) c->time_base.den = itsContext.time_base.den; c->time_base.num = itsContext.time_base.num; #endif c->gop_size = 12; /* emit one intra frame every twelve frames at most */ c->pix_fmt = itsContext.pix_fmt; /* set the output parameters (must be done even if no parameters). */ if (av_set_parameters(itsFormatContext, NULL) < 0) LFATAL("Invalid output format parameters"); #if defined(INVT_FFMPEG_URL_OPEN_FUNC_TAKES_SINGLE_POINTER) #if defined(INVT_FFMPEG_AVFORMATCONTEXT_BYTEIO_ISPOINTER) if (url_fopen(itsFormatContext->pb, oname.c_str(), URL_WRONLY) < 0) LFATAL("Could not open '%s'", oname.c_str()); #else if (url_fopen(&itsFormatContext->pb, oname.c_str(), URL_WRONLY) < 0) LFATAL("Could not open '%s'", oname.c_str()); #endif #else #if defined(INVT_FFMPEG_AVFORMATCONTEXT_BYTEIO_ISPOINTER) if (url_fopen(&itsFormatContext->pb, oname.c_str(), URL_WRONLY) < 0) LFATAL("Could not open '%s'", oname.c_str()); #else LFATAL("Could not open '%s' ffmpeg version mismatch", oname.c_str()); #endif #endif //INVT_FFMPEG_URL_OPEN_FUNC_TAKES_SINGLE_POINTER) /* write the stream header, if any */ av_write_header(itsFormatContext); #else LFATAL("Need a new version of FFMPEG for this option"); #endif } else { itsFile = fopen(oname.c_str(), "w"); if (itsFile==NULL) LFATAL("could not open file! %s", oname.c_str()); } LINFO("EnCoder Inited"); }
// ###################################################################### QuickTimeGrabber::Impl::Impl(const Dims& dims) : itsSeqGrab(0, &CloseComponent), itsSGChanVideo(&itsSeqGrab.it), itsDrawSeq(0), itsTimeScale(0), itsTimeBase(0), itsQueuedFrameCount(0), itsSkipFrameCount(0), itsSkipFrameCountTotal(0), itsPrevTime(0), itsFrameCount(0), itsGWorld(0), itsGotFrame(false), itsCurrentImage(), itsErrorMsg(), itsStreamStarted(false) { OSErr err; EnterMovies(); // open the default sequence grabber itsSeqGrab.it = OpenDefaultComponent(SeqGrabComponentType, 0); if (itsSeqGrab.it == NULL) LFATAL("OpenDefaultComponent() failed"); // initialize the default sequence grabber component if (noErr != (err = SGInitialize(itsSeqGrab.it))) LFATAL("SGInitialize() failed (err=%ld)", (long) err); Rect scaleRect; MacSetRect(&scaleRect, 0, 0, dims.w(), dims.h()); ASSERT(itsGWorld == 0); QTNewGWorld(&itsGWorld, k32ARGBPixelFormat, &scaleRect, NULL, NULL, kNativeEndianPixMap); // set its graphics world if (noErr != (err = SGSetGWorld(itsSeqGrab.it, itsGWorld, NULL))) LFATAL("SGSetGWorld() failed (err=%ld)", (long) err); // specify the destination data reference for a record operation // tell it we're not making a movie if the flag seqGrabDontMakeMovie // is used, the sequence grabber still calls your data function, but // does not write any data to the movie file writeType will always // be set to seqGrabWriteAppend if (noErr != (err = SGSetDataRef(itsSeqGrab.it, 0, 0, seqGrabDontMakeMovie | seqGrabDataProcIsInterruptSafe))) LFATAL("SGSetDataRef() failed (err=%ld)", (long) err); Impl::SGChannelHolder sgchanSound(&itsSeqGrab.it); if (noErr != (err = SGNewChannel(itsSeqGrab.it, VideoMediaType, &itsSGChanVideo.it))) LFATAL("SGNewChannel(video) failed (err=%ld)", (long) err); if (noErr != (err = SGNewChannel(itsSeqGrab.it, SoundMediaType, &sgchanSound.it))) { // don't care if we couldn't get a sound channel sgchanSound.it = NULL; LERROR("SGNewChannel(audio) failed (err=%ld)", (long) err); } // get the active rectangle Rect srcBounds; if (noErr != (err = SGGetSrcVideoBounds(itsSGChanVideo.it, &srcBounds))) LFATAL("SGGetSrcVideoBounds() failed (err=%ld)", (long) err); // we always want all the source setVideoChannelBounds(itsSGChanVideo.it, &srcBounds, &srcBounds); // set usage for new video channel to avoid playthrough // note we don't set seqGrabPlayDuringRecord if (noErr != (err = SGSetChannelUsage(itsSGChanVideo.it, seqGrabRecord | seqGrabLowLatencyCapture | seqGrabAlwaysUseTimeBase))) LFATAL("SGSetChannelUsage(video) failed (err=%ld)", (long) err); if (noErr != (err = SGSetChannelUsage(sgchanSound.it, seqGrabRecord | //seqGrabPlayDuringRecord | seqGrabLowLatencyCapture | seqGrabAlwaysUseTimeBase))) LERROR("SGSetChannelUsage(audio) failed (err=%ld)", (long) err); // specify a sequence grabber data function if (noErr != (err = SGSetDataProc(itsSeqGrab.it, NewSGDataUPP(Impl::grabDataProc), (long)(this)))) LFATAL("SGSetDataProc() failed (err=%ld)", (long) err); SGSetChannelRefCon(itsSGChanVideo.it, (long)(this)); // set up the video bottlenecks so we can get our queued frame count VideoBottles vb = { 0 }; if (noErr != (err = SGGetVideoBottlenecks(itsSGChanVideo.it, &vb))) LFATAL("SGGetVideoBottlenecks() failed (err=%ld)", (long) err); vb.procCount = 9; // there are 9 bottleneck procs; this must be filled in vb.grabCompressCompleteProc = NewSGGrabCompressCompleteBottleUPP (Impl::grabCompressCompleteBottle); if (noErr != (err = SGSetVideoBottlenecks(itsSGChanVideo.it, &vb))) LFATAL("SGSetVideoBottlenecks() failed (err=%ld)", (long) err); SGSetFrameRate(itsSGChanVideo.it, FixRatio(30, 1)); }