idx<T> image_region_to_rect(idx<T> &im, const rect<int> &r, uint oheight, uint owidth, rect<int> *cropped, uint dh, uint dw) { // TODO: check that rectangle is within image if (im.order() != 2 && im.order() != 3) eblerror("expected a 2d or 3d input but got " << im); idxdim d(im); d.setdim(dh, oheight); d.setdim(dw, owidth); idx<T> res(d); float hcenter = r.h0 + (float)r.height / 2; // input height center float wcenter = r.w0 + (float)r.width / 2; // input width center // // limit centers to half the width/height away from borders // // to handle incorrect regions // hcenter = MIN((float)im.dim(dh) - (float)r.height/2, // std::max((float)r.height/2, hcenter)); // wcenter = MIN((float)im.dim(dw) - (float)r.width/2, // std::max((float)r.width/2, wcenter)); float h0 = hcenter - (float)oheight / 2; // out height offset in input float w0 = wcenter - (float)owidth / 2; // out width offset in input float h1 = hcenter + (float)oheight / 2; float w1 = wcenter + (float)owidth / 2; int gh0 = (int)std::max(0, (int)MIN(im.dim(dh), h0)); // input h offset int gw0 = (int)std::max(0, (int)MIN(im.dim(dw), w0)); // input w offset int gh1 = (int)std::max(0, (int)MIN(im.dim(dh), h1)); int gw1 = (int)std::max(0, (int)MIN(im.dim(dw), w1)); int h = gh1 - gh0 + std::max(0, -r.h0); // out height narrow int w = gw1 - gw0 + std::max(0, -r.w0); // out width narrow int fh0 = (int)std::max(0, (int)(gh0 - h0)); // out height offset narrow int fw0 = (int)std::max(0, (int)(gw0 - w0)); // out width offset narrow // narrow original image int hmin = std::max(0, std::min((int)res.dim(dh) - fh0, std::min((int)im.dim(dh) - gh0, h))); int wmin = std::max(0, std::min((int)res.dim(dw) - fw0, std::min((int)im.dim(dw) - gw0, w))); // clear result image idx_clear(res); if (hmin != 0 && wmin != 0) // only copy if overlap with image { idx<T> tmpim = im.narrow(dh, hmin, gh0); tmpim = tmpim.narrow(dw, wmin, gw0); // narrow target image idx<T> tmpres = res.narrow(dh, hmin, fh0); tmpres = tmpres.narrow(dw, wmin, fw0); // copy original to target idx_copy(tmpim, tmpres); } // set cropped rectangle to region in the output image containing input if (cropped) { cropped->h0 = fh0; cropped->w0 = fw0; cropped->height = hmin; cropped->width = wmin; } return res; }
void image_paste_center(idx<T> &in, idx<T> &out) { if (in.order() != 3 || out.order() != 3) eblerror("expected 3d idx but got " << in << " and " << out); int d0 = 1; int d1 = d0 + 1; intg ci = in.dim(d0) - out.dim(d0); intg cj = in.dim(d1) - out.dim(d1); intg xci = (int) (ci / 2); intg xcj = (int) (cj / 2); idx<T> i = in.narrow(d0, out.dim(d0), xci); i = i.narrow(d1, out.dim(d1), xcj); idx_copy(i, out); }
idxlooper<T>::idxlooper(idx<T> &m, int ld) : idx<T>((dummyt*)0) { if (m.order() == 0) // TODO: allow looping once on 0-order idx eblerror("cannot loop on idx with order 0. idx is: " << m); i = 0; dimd = m.spec.dim[ld]; modd = m.spec.mod[ld]; m.spec.select_into(&(this->spec), ld, i); this->storage = m.storage; this->storage->lock(); }
bool tracking_thread<Tnet>::get_data(vector<bbox*> &bboxes2, idx<ubyte> &frame2, idx<ubyte> &tpl2) { // lock data pthread_mutex_lock(&mutex_out); // only read data if it has been updated if (!out_updated) { // unlock data pthread_mutex_unlock(&mutex_out); return false; } // clear bboxes for (ibox = bboxes2.begin(); ibox != bboxes2.end(); ++ibox) { if (*ibox) delete *ibox; } bboxes2.clear(); // copy bboxes pointers (now responsible for deleting them). for (ibox = bboxes.begin(); ibox != bboxes.end(); ++ibox) { bboxes2.push_back(*ibox); } // check frame is correctly allocated, if not, allocate. if (frame2.order() != frame.order()) frame2 = idx<ubyte>(frame.get_idxdim()); else if (frame2.get_idxdim() != frame.get_idxdim()) frame2.resize(frame.get_idxdim()); // copy frame idx_copy(frame, frame2); // check tpl is correctly allocated, if not, allocate. if (tpl2.order() != tpl.order()) tpl2 = idx<ubyte>(tpl.get_idxdim()); else if (tpl2.get_idxdim() != tpl.get_idxdim()) tpl2.resize(tpl.get_idxdim()); // copy tpl idx_copy(tpl, tpl2); // reset updated flag out_updated = false; // unlock data pthread_mutex_unlock(&mutex_out); // confirm that we copied data. return true; }
void serialize(Archive & ar, idx<ubyte>& mat, const unsigned int version) { intg d1, d2, d3; if (Archive::is_saving::value) { // saving to stream if (!mat.contiguousp()) eblerror("expected contiguous idx for serialization"); if (mat.order() != 3) eblerror("no support for idx order != 3 for now, got: " << mat); d1 = mat.dim(0); d2 = mat.dim(1); d3 = mat.dim(2); ar & d1; ar & d2; ar & d3; idx_aloop1(m, mat, ubyte) { ar & *m; } } else { // loading from stream
bool detection_thread<T>::set_data(idx<ubyte> &frame2, std::string &fullname, std::string &name, uint id) { // lock data (non blocking) if (!mutex_in.trylock()) return false; // check frame is correctly allocated, if not, allocate. if (frame2.order() != uframe.order()) uframe = idx<ubyte>(frame2.get_idxdim()); else if (frame2.get_idxdim() != uframe.get_idxdim()) uframe.resize(frame2.get_idxdim()); idx_copy(frame2, uframe); // copy frame frame_loaded = true; // frame is loaded frame_fullname = fullname; frame_name = name; // copy name frame_id = id; // copy frame_id in_updated = true; // reset updated flag bavailable = false; // declare thread as not available bfed = true; // data has been fed at least once mutex_in.unlock(); // unlock data return true; // confirm that we copied data. }
bool detection_thread<T>::get_data(bboxes &bboxes2, idx<ubyte> &frame2, uint &total_saved_, std::string &frame_name_, uint *id, svector<midx<T> > *samples, bboxes *bbsamples, bool *skipped) { // lock data mutex_out.lock(); // only read data if it has been updated if (!out_updated) { // unlock data mutex_out.unlock(); return false; } // data is updated, but just to tell we skipped the frame if (frame_skipped) { if (skipped) *skipped = true; frame_skipped = false; // reset updated flag out_updated = false; // declare thread as available bavailable = true; // unlock data mutex_out.unlock(); return false; } if (skipped) *skipped = false; // clear bboxes bboxes2.clear(); bboxes2.push_back_new(bbs); bbs.clear(); // no use for local bounding boxes anymore, clear them // check frame is correctly allocated, if not, allocate. if (frame2.order() != uframe.order()) frame2 = idx<ubyte>(uframe.get_idxdim()); else if (frame2.get_idxdim() != uframe.get_idxdim()) frame2.resize(uframe.get_idxdim()); // copy frame idx_copy(uframe, frame2); // set total of boxes saved total_saved_ = total_saved; // set frame name frame_name_ = frame_name; // set frame id if (id) *id = frame_id; // overwrite samples if (samples) { samples->clear(); samples->push_back_new(returned_samples); returned_samples.clear(); } if (bbsamples) { bbsamples->clear(); bbsamples->push_back_new(returned_samples_bboxes); returned_samples_bboxes.clear(); } // reset updated flag out_updated = false; // declare thread as available bavailable = true; // unlock data mutex_out.unlock(); // confirm that we copied data. return true; }