// store the map from grid point offset to mask used in phase correlation peak finding static void storeHintToMask(map<GridPtOff, Mat> &hintToMask, const Size &imSz, const Point2f &absHint, const MaxDists &dists) { for (int xOff = -1; xOff <= 1; xOff++) { for (int yOff = -1; yOff <= 1; yOff++) { if (!xOff && !yOff) { continue; } int maxDist; if (xOff) { if (yOff) { maxDist = dists.xy; } else { maxDist = dists.x; } } else { maxDist = dists.y; } Mat mask = Mat::zeros(Size(imSz.width + 2, imSz.height), CV_8UC1); Point baseXY(fround(absHint.x * xOff), fround(absHint.y * yOff)); if (baseXY.x > imSz.width) { baseXY.x -= imSz.width; } else if (baseXY.x < 0) { baseXY.x += imSz.width; } if (baseXY.y > imSz.height) { baseXY.y -= imSz.height; } else if (baseXY.y < 0) { baseXY.y += imSz.height; } if (xOff) { if (yOff) { circle(mask, baseXY, maxDist, Scalar(255, 255, 255, 255), -1); } else { for (int y = baseXY.y - imSz.height; y <= baseXY.y + imSz.height; y += imSz.height) { circle(mask, Point(baseXY.x, y), maxDist, Scalar(255, 255, 255, 255), -1); } } } else { for (int x = baseXY.x - imSz.width; x <= baseXY.x + imSz.width; x += imSz.width) { circle(mask, Point(x, baseXY.y), maxDist, Scalar(255, 255, 255, 255), -1); } } // Mat tmp; // resize(mask, tmp, Size(), 0.4, 0.4); // imshow("m", tmp); // waitKey(0); hintToMask.emplace(makeOff(xOff, yOff), mask); } } }
static int testcase(Ndb_cluster_connection&cc, int flag) { ndbout << "--- case " << flag << " ---" << endl; sprintf(tab, "TB%02d", flag); alignAddr = ! (flag & 1); ndbout << (alignAddr ? "align addresses" : "mis-align addresses") << endl; alignSize = ! (flag & 2); ndbout << (alignSize ? "align data sizes" : "mis-align data sizes") << endl; useBuf = ! (flag & 4); ndbout << (useBuf ? "use our buffers" : "use ndbapi buffers") << endl; noRandom = ! (flag & 8); ndbout << (noRandom ? "simple sizes" : "randomize sizes") << endl; int smax = 0, stot = 0, i; if (xverbose) ndbout << "- define table " << tab << endl; for (i = 0; i < attrcnt; i++) { col& c = ccol[i]; memset(&c, 0, sizeof(c)); sprintf(c.aAttrName, "C%d", i); if (i == 0) { c.aAttrType = UnSigned; c.aAttrSize = 32; c.aArraySize = 1; c.aTupleKey = TupleKey; c.nullable = false; } else { c.aAttrType = String; c.aAttrSize = 8; c.aArraySize = makeSize(i); if (smax < c.aArraySize) smax = c.aArraySize; stot += c.aArraySize; c.aTupleKey = NoKey; c.nullable = true; if (xverbose) ndbout << "-- column " << i << " size=" << c.aArraySize << endl; } c.buf = toAligned(c.data); c.bufsiz = sizeof(c.data) - (c.buf - c.data); } ndbout << "tab=" << tab << " cols=" << attrcnt << " size max=" << smax << " tot=" << stot << endl; if ((tcon = NdbSchemaCon::startSchemaTrans(ndb)) == 0) return ndberror("startSchemaTransaction"); if ((top = tcon->getNdbSchemaOp()) == 0) return ndberror("getNdbSchemaOp"); if (top->createTable(tab) < 0) return ndberror("createTable"); for (i = 0; i < attrcnt; i++) { col& c = ccol[i]; if (top->createAttribute( c.aAttrName, c.aTupleKey, c.aAttrSize, c.aArraySize, c.aAttrType, MMBased, c.nullable ) < 0) return ndberror("createAttribute col=%d", i); } if (tcon->execute() < 0) { if (! (tcon->getNdbError().code == 721 && existok)) return ndberror("execute"); ndbout << "using " << tab << endl; } else { ndbout << "created " << tab << endl; } top = 0; tcon = 0; if (xverbose) ndbout << "- delete" << endl; int delcnt = 0; for (key = 0; key < opercnt; key++) { if ((con = ndb->startTransaction()) == 0) return ndberror("startTransaction key=%d", key); if ((op = con->getNdbOperation(tab)) == 0) return ndberror("getNdbOperation key=%d", key); if (op->deleteTuple() < 0) return ndberror("deleteTuple key=%d", key); for (i = 0; i < attrcnt; i++) { col& c = ccol[i]; if (i == 0) { if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0) return ndberror("equal key=%d", key); } else { } } if (con->execute(Commit) < 0) { if (con->getNdbError().code != 626) return ndberror("execute key=%d", key); } else { delcnt++; } ndb->closeTransaction(con); } con = 0; op = 0; ndbout << "deleted " << delcnt << endl; if (xverbose) ndbout << "- insert" << endl; for (key = 0; key < opercnt; key++) { int off = makeOff(key); if ((con = ndb->startTransaction()) == 0) return ndberror("startTransaction key=%d", key); if ((op = con->getNdbOperation(tab)) == 0) return ndberror("getNdbOperation key=%d", key); if (op->insertTuple() < 0) return ndberror("insertTuple key=%d", key); for (i = 0; i < attrcnt; i++) { col& c = ccol[i]; if (i == 0) { if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0) return ndberror("equal key=%d", key); } else { memset(c.buf, 'A', c.bufsiz); for (int j = 0; j < c.aArraySize; j++) c.buf[j + off] = byteVal(key, i, j); if (op->setValue(c.aAttrName, c.buf + off, c.aArraySize) < 0) return ndberror("setValue key=%d col=%d", key, i); } } if (con->execute(Commit) < 0) return ndberror("execute key=%d", key); ndb->closeTransaction(con); } con = 0; op = 0; ndbout << "inserted " << key << endl; if (xverbose) ndbout << "- select" << endl; for (key = 0; key < opercnt; key++) { int off = makeOff(key); if (xverbose) ndbout << "-- key " << key << " off=" << off << endl; if ((con = ndb->startTransaction()) == 0) return ndberror("startTransaction key=%d", key); if ((op = con->getNdbOperation(tab)) == 0) return ndberror("getNdbOperation key=%d", key); if (op->readTuple() < 0) return ndberror("readTuple key=%d", key); for (i = 0; i < attrcnt; i++) { col& c = ccol[i]; if (i == 0) { if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0) return ndberror("equal key=%d", key); } else { if (xverbose) { char tmp[20]; if (useBuf) sprintf(tmp, "0x%p", c.buf + off); else strcpy(tmp, "ndbapi"); ndbout << "--- column " << i << " addr=" << tmp << endl; } memset(c.buf, 'B', c.bufsiz); if (useBuf) { if (op->getValue(c.aAttrName, c.buf + off) < 0) return ndberror("getValue key=%d col=%d", key, i); } else { if ((c.aRa = op->getValue(c.aAttrName)) == 0) return ndberror("getValue key=%d col=%d", key, i); } } } if (con->execute(Commit) != 0) return ndberror("execute key=%d", key); for (i = 0; i < attrcnt; i++) { col& c = ccol[i]; if (i == 0) { } else if (useBuf) { int j; for (j = 0; j < off; j++) { if (c.buf[j] != 'B') { return chkerror("mismatch before key=%d col=%d pos=%d ok=%02x bad=%02x", key, i, j, 'B', c.buf[j]); } } for (j = 0; j < c.aArraySize; j++) { if (c.buf[j + off] != byteVal(key, i, j)) { return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x", key, i, j, byteVal(key, i, j), c.buf[j]); } } for (j = c.aArraySize + off; j < c.bufsiz; j++) { if (c.buf[j] != 'B') { return chkerror("mismatch after key=%d col=%d pos=%d ok=%02x bad=%02x", key, i, j, 'B', c.buf[j]); } } } else { char* buf = c.aRa->aRef(); if (buf == 0) return ndberror("null aRef key=%d col%d", key, i); for (int j = 0; j < c.aArraySize; j++) { if (buf[j] != byteVal(key, i, j)) { return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x", key, i, j, byteVal(key, i, j), buf[j]); } } } } ndb->closeTransaction(con); } con = 0; op = 0; ndbout << "selected " << key << endl; if (xverbose) ndbout << "- scan" << endl; char found[MaxOper]; int k; for (k = 0; k < opercnt; k++) found[k] = 0; for (key = 0; key < opercnt; key++) { int off = makeOff(key); if (xverbose) ndbout << "-- key " << key << " off=" << off << endl; int newkey = 0; if ((con = ndb->startTransaction()) == 0) return ndberror("startTransaction key=%d", key); if ((op = sop = con->getNdbScanOperation(tab)) == 0) return ndberror("getNdbOperation key=%d", key); if (sop->readTuples(1)) return ndberror("openScanRead key=%d", key); { col& c = ccol[0]; if (op->load_const_u32(1, key) < 0) return ndberror("load_const_u32"); if (op->read_attr(c.aAttrName, 2) < 0) return ndberror("read_attr"); if (op->branch_eq(1, 2, 0) < 0) return ndberror("branch_eq"); if (op->interpret_exit_nok() < 0) return ndberror("interpret_exit_nok"); if (op->def_label(0) < 0) return ndberror("def_label"); if (op->interpret_exit_ok() < 0) return ndberror("interpret_exit_ok"); } for (i = 0; i < attrcnt; i++) { col& c = ccol[i]; if (i == 0) { if (op->getValue(c.aAttrName, (char*)&newkey) < 0) return ndberror("getValue key=%d col=%d", key, i); } else { if (xverbose) { char tmp[20]; if (useBuf) sprintf(tmp, "0x%p", c.buf + off); else strcpy(tmp, "ndbapi"); ndbout << "--- column " << i << " addr=" << tmp << endl; } memset(c.buf, 'C', c.bufsiz); if (useBuf) { if (op->getValue(c.aAttrName, c.buf + off) < 0) return ndberror("getValue key=%d col=%d", key, i); } else { if ((c.aRa = op->getValue(c.aAttrName)) == 0) return ndberror("getValue key=%d col=%d", key, i); } } } if (con->execute(NoCommit) < 0) return ndberror("executeScan key=%d", key); int ret, cnt = 0; while ((ret = sop->nextResult()) == 0) { if (key != newkey) return ndberror("unexpected key=%d newkey=%d", key, newkey); for (i = 1; i < attrcnt; i++) { col& c = ccol[i]; if (useBuf) { int j; for (j = 0; j < off; j++) { if (c.buf[j] != 'C') { return chkerror("mismatch before key=%d col=%d pos=%d ok=%02x bad=%02x", key, i, j, 'C', c.buf[j]); } } for (j = 0; j < c.aArraySize; j++) { if (c.buf[j + off] != byteVal(key, i, j)) { return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x", key, i, j, byteVal(key, i, j), c.buf[j]); } } for (j = c.aArraySize + off; j < c.bufsiz; j++) { if (c.buf[j] != 'C') { return chkerror("mismatch after key=%d col=%d pos=%d ok=%02x bad=%02x", key, i, j, 'C', c.buf[j]); } } } else { char* buf = c.aRa->aRef(); if (buf == 0) return ndberror("null aRef key=%d col%d", key, i); for (int j = 0; j < c.aArraySize; j++) { if (buf[j] != byteVal(key, i, j)) { return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x", key, i, j, byteVal(key, i, j), buf[j]); } } } } cnt++; } if (ret < 0) return ndberror("nextScanResult key=%d", key); if (cnt != 1) return ndberror("scan key=%d found %d", key, cnt); found[key] = 1; ndb->closeTransaction(con); } con = 0; op = 0; for (k = 0; k < opercnt; k++) if (! found[k]) return ndberror("key %d not found", k); ndbout << "scanned " << key << endl; ndbout << "done" << endl; return 0; }
// store translations into transMap void storeTrans(ImgFetcher &fetcher, const Point2f &absHint, PairToTransData &transMap, const MaxDists &dists) { vector<GridPtOff> imOffs; if (fetcher.row_major) { imOffs.push_back(makeOff(-1, 0)); imOffs.push_back(makeOff(-1, -1)); imOffs.push_back(makeOff(0, -1)); imOffs.push_back(makeOff(1, -1)); } else { imOffs.push_back(makeOff(0, -1)); imOffs.push_back(makeOff(-1, -1)); imOffs.push_back(makeOff(-1, 0)); imOffs.push_back(makeOff(-1, 1)); } map<PtPair, shared_future<TransData>> pairToTransFut; map<GridPt, shared_future<FFTHolder>> ptToFFTFut; unsigned loaded = 0; GridPt fixPt = {{0, 0}}; GridPt waitPt = {{0, 0}}; Mat cur; fetcher.getMat(fixPt, cur); Size imSz = cur.size(); unsigned fftLen = getFFTLen(imSz); map<GridPtOff, Mat> hintToMask; storeHintToMask(hintToMask, imSz, absHint, dists); float *tmp = (float *)fftwf_malloc_thr(sizeof(float) * fftLen); fftwf_plan r2cPlan = fftwf_plan_dft_r2c_2d(imSz.height, imSz.width, tmp, (fftwf_complex *)tmp, FFTW_MEASURE); fftwf_plan c2rPlan = fftwf_plan_dft_c2r_2d(imSz.height, imSz.width, (fftwf_complex *)tmp, tmp, FFTW_MEASURE); fftwf_free_thr(tmp); bool readDone = false; while (true) { //a dirty kind of event loop if (loaded > fetcher.cap || readDone) { // printf("start free waitPt %d %d\n", waitPt[0], waitPt[1]); // free oldest image, at waitPt for (auto &off: imOffs) { // *subtract* offset to avoid duplicating pairs GridPt nbrPt = {{waitPt[0] - off[0], waitPt[1] - off[1]}}; if (ptInGrid(nbrPt, fetcher)) { PtPair pair = {{waitPt, nbrPt}}; shared_future<TransData> transFut; if (!lookupPair(pairToTransFut, pair, transFut)) { printf("err: future of pair %d %d to %d %d not found\n", pair[0][0], pair[0][1], pair[1][0], pair[1][1]); exit(1); } transMap.emplace(pair, transFut.get()); pairToTransFut.erase(pair); } } fftwf_free_thr(ptToFFTFut[waitPt].get().fft); ptToFFTFut.erase(waitPt); if (!nextCoor(waitPt, fetcher)) { break; } loaded--; } if (!readDone) { //printf("emplace fft at %d %d\n", fixPt[0], fixPt[1]); fetcher.getMat(fixPt, cur); // fft only supports 32-bit float with even width, for now assert(cur.type() == CV_32FC1 && (int)cur.step[0] == cur.size().width * 4 && cur.step[1] == 4 && cur.size().width % 2 == 0); assert(cur.isContinuous()); ptToFFTFut.emplace(fixPt, async(launch::async, [&r2cPlan, &absHint](Mat im) { return FFTHolder(im, absHint, r2cPlan); }, cur )); for (auto &off: imOffs) { GridPt nbrPt = {{fixPt[0] + off[0], fixPt[1] + off[1]}}; if (ptInGrid(nbrPt, fetcher)) { PtPair pair = {{fixPt, nbrPt}}; // printf("emplace pair transfut %d %d, %d %d\n", pair[0][0], pair[0][1], pair[1][0], pair[1][1]); // needed since VS2012 async() can't take functions with too many arguments :( shared_future<FFTHolder> &a = ptToFFTFut[fixPt]; shared_future<FFTHolder> &b = ptToFFTFut[nbrPt]; pairToTransFut.emplace(pair, async(launch::async, [=] { return phaseCorrThr(a, b, c2rPlan, pair, absHint, hintToMask, imSz); })); } } loaded++; if (!nextCoor(fixPt, fetcher)) { readDone = true; } } } fftwf_destroy_plan(r2cPlan); fftwf_destroy_plan(c2rPlan); }