BitMatrix<dim> subquotientMap (const Subquotient<dim>& source, const Subquotient<dim>& dest, const BitMatrix<dim>& m) { assert(m.numColumns()==source.rank()); assert(m.numRows()==dest.rank()); BitMatrix<dim> result(dest.dimension(),0); // restrict m to source.space() for (RankFlags::iterator it=source.support().begin(); it(); ++it) { SmallBitVector v = m*source.space().basis(*it); assert(v.size()==dest.rank()); /* // go to canonical representative modulo destination subspace dest.denominator().mod_reduce(v); assert(v.size()==dest.rank()); // get coordinates in canonical basis v.slice(dest.space().support()); // express |v| in basis of |d_space| assert(v.size()==dest.space().dimension()); v.slice(dest.support()); */ v=dest.toBasis(v); assert(v.size()==dest.dimension()); // dimension of the subquotient result.addColumn(v); } return result; }
// create the map for converting index to matrix position // 1 2 3 // 1 2 4 7 5 3 6 8 9 --> 4 5 6 // 7 8 9 void DepthEstimator::MapMatrix2ZigzagIdx(const Image8U::Size& size, DepthEstimator::MapRefArr& coords, BitMatrix& mask, int rawStride) { typedef DepthEstimator::MapRef MapRef; const int w = size.width; const int w1 = size.width-1; coords.Empty(); coords.Reserve(size.area()); for (int dy=0, h=rawStride; dy<size.height; dy+=h) { if (h*2 > size.height - dy) h = size.height - dy; int lastX = 0; MapRef x(MapRef::ZERO); for (int i=0, ei=w*h; i<ei; ++i) { const MapRef pt(x.x, x.y+dy); if (mask.empty() || mask.isSet(pt)) coords.Insert(pt); if (x.x-- == 0 || ++x.y == h) { if (++lastX < w) { x.x = lastX; x.y = 0; } else { x.x = w1; x.y = lastX - w1; } } } } }
// find score from alpha to beta AlphaBetaBase::search( const Board& board, bool passed, int depth, eval_t alpha, eval_t beta) { BitMatrix moves = board.get_move_bit(); if (moves.size() == 0) { if (passed) { return board.get_score(); } else { return search(board.make_inverse(), true, depth - 1, -beta, -alpha); } } else { for (BitMoveOrderingIterator it(board, *p_evaluator_); it.has_next(); it.go_next()) { BitBoard next_board = it.get_next(); eval_t val = evaluate(next_board, false, -beta, -alpha); if (alpha < val) { alpha = val; } } return alpha; } }
/*! \brief Constructs the normalised subspace generated by the columns of a |BitMatrix|, i.e., the image of that matrix */ template<size_t dim> Subspace<dim>:: Subspace(const BitMatrix<dim>& M) : d_basis(M.image()) , d_support() , d_rank(M.numRows()) { // change |d_basis| to a normalised form, and set |d_support|: bitvector::Gauss_Jordan(d_support,d_basis); }
// Adapted from "sizeOfBlackWhiteBlackRun" in zxing::qrcode::Detector Point QREdgeDetector::endOfReverseBlackWhiteBlackRun(const BitMatrix& image, Point from, Point to) { int fromX = (int)from.x; int fromY = (int)from.y; int toX = (int)to.x; int toY = (int)to.y; bool steep = abs(toY - fromY) > abs(toX - fromX); if (steep) { int temp = fromX; fromX = fromY; fromY = temp; temp = toX; toX = toY; toY = temp; } int dx = abs(toX - fromX); int dy = abs(toY - fromY); int error = -dx >> 1; int ystep = fromY < toY ? -1 : 1; int xstep = fromX < toX ? -1 : 1; int state = 0; // In black pixels, looking for white, first or second time // In case there are no points, prepopulate to from int realX = fromX; int realY = fromY; for (int x = fromX, y = fromY; x != toX; x += xstep) { realX = steep ? y : x; realY = steep ? x : y; if(realX < 0 || realY < 0 || realX >= (int)image.getWidth() || realY >= (int)image.getHeight()) break; if (state == 1) { // In white pixels, looking for black if (image.get(realX, realY)) { state++; } } else { if (!image.get(realX, realY)) { state++; } } if (state == 3) { // Found black, white, black, and stumbled back onto white; done return Point(realX, realY); } error += dy; if (error > 0) { y += ystep; error -= dx; } } // B-W-B run not found, return the last point visited. return Point(realX, realY); }
ByteArray BitMatrixParser::ReadCodewords(const BitMatrix& image) { ByteArray result(144); int height = image.height(); int width = image.width(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int bit = BITNR[y][x]; if (bit >= 0 && image.get(x, y)) { result[bit / 6] |= static_cast<uint8_t>(1 << (5 - (bit % 6))); } } } return result; }
static ZXing::Result Decode(const BitMatrix &matrix) { BitArray row; matrix.getRow(0, row); std::unique_ptr<RowReader::DecodingState> state; return Code128Reader(DecodeHints()).decodeRow(0, row, state); }
void Subspace<dim>::apply(const BitMatrix<dim>& r) { assert(r.numColumns()==d_rank); BitVectorList<dim> b; b.reserve(dimension()); for (size_t j = 0; j<dimension(); ++j) { b.push_back(r*d_basis[j]); assert(b.back().size()==r.numRows()); } Subspace<dim> ns(b,r.numRows()); // construct (and normalize) new subspace swap(ns); // and install it in our place }
/** * <p>Attempts to locate an alignment pattern in a limited region of the image, which is * guessed to contain it. This method uses {@link AlignmentPattern}.</p> * * @param overallEstModuleSize estimated module size so far * @param estAlignmentX x coordinate of center of area probably containing alignment pattern * @param estAlignmentY y coordinate of above * @param allowanceFactor number of pixels in all directions to search from the center * @return {@link AlignmentPattern} if found, or null otherwise * @throws NotFoundException if an unexpected error occurs during detection */ AlignmentPattern FindAlignmentInRegion(const BitMatrix& image, float overallEstModuleSize, int estAlignmentX, int estAlignmentY, float allowanceFactor) { // Look for an alignment pattern (3 modules in size) around where it // should be int allowance = (int)(allowanceFactor * overallEstModuleSize); int alignmentAreaLeftX = std::max(0, estAlignmentX - allowance); int alignmentAreaRightX = std::min(image.width() - 1, estAlignmentX + allowance); if (alignmentAreaRightX - alignmentAreaLeftX < overallEstModuleSize * 3) { return {}; } int alignmentAreaTopY = std::max(0, estAlignmentY - allowance); int alignmentAreaBottomY = std::min(image.height() - 1, estAlignmentY + allowance); if (alignmentAreaBottomY - alignmentAreaTopY < overallEstModuleSize * 3) { return {}; } return AlignmentPatternFinder::Find(image, alignmentAreaLeftX, alignmentAreaTopY, alignmentAreaRightX - alignmentAreaLeftX, alignmentAreaBottomY - alignmentAreaTopY, overallEstModuleSize); }
/** * Determines whether a segment contains a black point * * @param a min value of the scanned coordinate * @param b max value of the scanned coordinate * @param fixed value of fixed coordinate * @param horizontal set to true if scan must be horizontal, false if vertical * @return true if a black point has been found, else false. */ static bool ContainsBlackPoint(const BitMatrix& image, int a, int b, int fixed, bool horizontal) { if (horizontal) { for (int x = a; x <= b; x++) { if (image.get(x, fixed)) { return true; } } } else { for (int y = a; y <= b; y++) { if (image.get(fixed, y)) { return true; } } } return false; }
/** * Applies a single threshold to a block of pixels. */ static void ThresholdBlock(const uint8_t* luminances, int xoffset, int yoffset, int threshold, int stride, BitMatrix& matrix) { for (int y = 0, offset = yoffset * stride + xoffset; y < BLOCK_SIZE; y++, offset += stride) { for (int x = 0; x < BLOCK_SIZE; x++) { // Comparison needs to be <= so that black == 0 pixels are black even if the threshold is 0. if (luminances[offset + x] <= threshold) { matrix.set(xoffset + x, yoffset + y); } } } }
// Applies a single threshold to an 8x8 block of pixels. void LocalBlockBinarizer::threshold8x8Block(const unsigned char* luminances, int xoffset, int yoffset, int threshold, int stride, BitMatrix& matrix) { for (int y = 0; y < 8; y++) { int offset = (yoffset + y) * stride + xoffset; for (int x = 0; x < 8; x++) { int pixel = luminances[offset + x]; if (pixel < threshold) { matrix.set(xoffset + x, yoffset + y); } } } }
/** * See {@link #sizeOfBlackWhiteBlackRun(int, int, int, int)}; computes the total width of * a finder pattern by looking for a black-white-black run from the center in the direction * of another point (another finder pattern center), and in the opposite direction too. */ static float SizeOfBlackWhiteBlackRunBothWays(const BitMatrix& image, int fromX, int fromY, int toX, int toY) { float result = SizeOfBlackWhiteBlackRun(image, fromX, fromY, toX, toY); // Now count other way -- don't run off image though of course float scale = 1.0f; int otherToX = fromX - (toX - fromX); if (otherToX < 0) { scale = (float)fromX / (float)(fromX - otherToX); otherToX = 0; } else if (otherToX >= image.width()) { scale = (float)(image.width() - 1 - fromX) / (float)(otherToX - fromX); otherToX = image.width() - 1; } int otherToY = (int)(fromY - (toY - fromY) * scale); scale = 1.0f; if (otherToY < 0) { scale = (float)fromY / (float)(fromY - otherToY); otherToY = 0; } else if (otherToY >= image.height()) { scale = (float)(image.height() - 1 - fromY) / (float)(otherToY - fromY); otherToY = image.height() - 1; } otherToX = (int)(fromX + (otherToX - fromX) * scale); result += SizeOfBlackWhiteBlackRun(image, fromX, fromY, otherToX, otherToY); // Middle pixel is double-counted this way; subtract 1 return result - 1.0f; }
/** * <p>This method traces a line from a point in the image, in the direction towards another point. * It begins in a black region, and keeps going until it finds white, then black, then white again. * It reports the distance from the start to this point.</p> * * <p>This is used when figuring out how wide a finder pattern is, when the finder pattern * may be skewed or rotated.</p> */ static float SizeOfBlackWhiteBlackRun(const BitMatrix& image, int fromX, int fromY, int toX, int toY) { // Mild variant of Bresenham's algorithm; // see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm bool steep = std::abs(toY - fromY) > std::abs(toX - fromX); if (steep) { std::swap(fromX, fromY); std::swap(toX, toY); } int dx = std::abs(toX - fromX); int dy = std::abs(toY - fromY); int error = -dx / 2; int xstep = fromX < toX ? 1 : -1; int ystep = fromY < toY ? 1 : -1; // In black pixels, looking for white, first or second time. int state = 0; // Loop up until x == toX, but not beyond int xLimit = toX + xstep; for (int x = fromX, y = fromY; x != xLimit; x += xstep) { int realX = steep ? y : x; int realY = steep ? x : y; // Does current pixel mean we have moved white to black or vice versa? // Scanning black in state 0,2 and white in state 1, so if we find the wrong // color, advance to next state or end if we are in state 2 already if ((state == 1) == image.get(realX, realY)) { if (state == 2) { return ResultPoint::Distance(x, y, fromX, fromY); } state++; } error += dy; if (error > 0) { if (y == toY) { break; } y += ystep; error -= dx; } } // Found black-white-black; give the benefit of the doubt that the next pixel outside the image // is "white" so this last point at (toX+xStep,toY) is the right ending. This is really a // small approximation; (toX+xStep,toY+yStep) might be really correct. Ignore this. if (state == 2) { return ResultPoint::Distance(toX + xstep, toY, fromX, fromY); } // else we didn't find even black-white-black; no estimate is really possible return std::numeric_limits<float>::quiet_NaN(); }
static bool GetBlackPointOnSegment(const BitMatrix& image, int aX, int aY, int bX, int bY, ResultPoint& result) { int dist = RoundToNearest(ResultPoint::Distance(aX, aY, bX, bY)); float xStep = static_cast<float>(bX - aX) / dist; float yStep = static_cast<float>(bY - aY) / dist; for (int i = 0; i < dist; i++) { int x = RoundToNearest(aX + i * xStep); int y = RoundToNearest(aY + i * yStep); if (image.get(x, y)) { result.set(static_cast<float>(x), static_cast<float>(y)); return true; } } return false; }
int main(int argc, char **argv) { clock_t begin = clock(); // MultiQuadTuple<N, M> f = MultiQuadTuple<N, M>::randomMultiQuadTuple(); // BitVector<N> x = BitVector<N>::randomVector(); // testLeftCompose(f, x); // testRightCompose(f, x); // testEvaluateMQT(f, x); //PrivateKey<N> pk; BitMatrix<N> randomInvertible = BitMatrix<N>::randomInvertibleMatrix(); randomInvertible.print(); // testBridgeKeyInstantiation(pk); // testPublicKey(pk); clock_t end = clock(); cout << "Time elapsed: " << double(end - begin) / CLOCKS_PER_SEC << " sec" << endl; fclose(urandom); return 0; }
TEST(QRWriterTest, OverSize) { // The QR should be multiplied up to fit, with extra padding if necessary int bigEnough = 256; Writer writer; BitMatrix matrix = writer.encode(L"http://www.google.com/", bigEnough, bigEnough); EXPECT_EQ(matrix.width(), bigEnough); EXPECT_EQ(matrix.height(), bigEnough); // The QR will not fit in this size, so the matrix should come back bigger int tooSmall = 20; matrix = writer.encode(L"http://www.google.com/", tooSmall, tooSmall); EXPECT_GT(matrix.width(), tooSmall); EXPECT_GT(matrix.height(), tooSmall); // We should also be able to handle non-square requests by padding them int strangeWidth = 500; int strangeHeight = 100; matrix = writer.encode(L"http://www.google.com/", strangeWidth, strangeHeight); EXPECT_EQ(matrix.width(), strangeWidth); EXPECT_EQ(matrix.height(), strangeHeight); }
/** * <p> * Detects a candidate barcode-like rectangular region within an image. It * starts around the center of the image, increases the size of the candidate * region until it finds a white rectangular region. * </p> * * @return {@link ResultPoint}[] describing the corners of the rectangular * region. The first and last points are opposed on the diagonal, as * are the second and third. The first point will be the topmost * point and the last, the bottommost. The second point will be * leftmost and the third, the rightmost * @throws NotFoundException if no Data Matrix Code can be found */ bool WhiteRectDetector::Detect(const BitMatrix& image, int initSize, int x, int y, ResultPoint& p0, ResultPoint& p1, ResultPoint& p2, ResultPoint& p3) { int height = image.height(); int width = image.width(); int halfsize = initSize / 2; int left = x - halfsize; int right = x + halfsize; int up = y - halfsize; int down = y + halfsize; if (up < 0 || left < 0 || down >= height || right >= width) { return false; } bool sizeExceeded = false; bool aBlackPointFoundOnBorder = true; bool atLeastOneBlackPointFoundOnBorder = false; bool atLeastOneBlackPointFoundOnRight = false; bool atLeastOneBlackPointFoundOnBottom = false; bool atLeastOneBlackPointFoundOnLeft = false; bool atLeastOneBlackPointFoundOnTop = false; while (aBlackPointFoundOnBorder) { aBlackPointFoundOnBorder = false; // ..... // . | // ..... bool rightBorderNotWhite = true; while ((rightBorderNotWhite || !atLeastOneBlackPointFoundOnRight) && right < width) { rightBorderNotWhite = ContainsBlackPoint(image, up, down, right, false); if (rightBorderNotWhite) { right++; aBlackPointFoundOnBorder = true; atLeastOneBlackPointFoundOnRight = true; } else if (!atLeastOneBlackPointFoundOnRight) { right++; } } if (right >= width) { sizeExceeded = true; break; } // ..... // . . // .___. bool bottomBorderNotWhite = true; while ((bottomBorderNotWhite || !atLeastOneBlackPointFoundOnBottom) && down < height) { bottomBorderNotWhite = ContainsBlackPoint(image, left, right, down, true); if (bottomBorderNotWhite) { down++; aBlackPointFoundOnBorder = true; atLeastOneBlackPointFoundOnBottom = true; } else if (!atLeastOneBlackPointFoundOnBottom) { down++; } } if (down >= height) { sizeExceeded = true; break; } // ..... // | . // ..... bool leftBorderNotWhite = true; while ((leftBorderNotWhite || !atLeastOneBlackPointFoundOnLeft) && left >= 0) { leftBorderNotWhite = ContainsBlackPoint(image, up, down, left, false); if (leftBorderNotWhite) { left--; aBlackPointFoundOnBorder = true; atLeastOneBlackPointFoundOnLeft = true; } else if (!atLeastOneBlackPointFoundOnLeft) { left--; } } if (left < 0) { sizeExceeded = true; break; } // .___. // . . // ..... bool topBorderNotWhite = true; while ((topBorderNotWhite || !atLeastOneBlackPointFoundOnTop) && up >= 0) { topBorderNotWhite = ContainsBlackPoint(image, left, right, up, true); if (topBorderNotWhite) { up--; aBlackPointFoundOnBorder = true; atLeastOneBlackPointFoundOnTop = true; } else if (!atLeastOneBlackPointFoundOnTop) { up--; } } if (up < 0) { sizeExceeded = true; break; } if (aBlackPointFoundOnBorder) { atLeastOneBlackPointFoundOnBorder = true; } } if (!sizeExceeded && atLeastOneBlackPointFoundOnBorder) { int maxSize = right - left; ResultPoint z; bool found = false; for (int i = 1; !found && i < maxSize; i++) { found = GetBlackPointOnSegment(image, left, down - i, left + i, down, z); } if (!found) { return false; } ResultPoint t; found = false; //go down right for (int i = 1; !found && i < maxSize; i++) { found = GetBlackPointOnSegment(image, left, up + i, left + i, up, t); } if (!found) { return false; } ResultPoint x; found = false; //go down left for (int i = 1; !found && i < maxSize; i++) { found = GetBlackPointOnSegment(image, right, up + i, right - i, up, x); } if (!found) { return false; } ResultPoint y; found = false; //go up left for (int i = 1; !found && i < maxSize; i++) { found = GetBlackPointOnSegment(image, right, down - i, right - i, down, y); } if (!found) { return false; } CenterEdges(y, z, x, t, width, p0, p1, p2, p3); return true; } else { return false; } }
eval_t NegaScout::evaluate( const Board& board, unsigned depth, bool passed, eval_t alpha, eval_t beta) { //std::cerr << board.to_zebra_str() << std::endl; TransTableController<TransTable> ttc(*p_trans_table_); if (!ttc.init_alpha_beta(board, alpha, beta)) { return ttc.get_return_value(); } eval_t g = alpha; if (depth == 0) { leaf_count_++; g = p_evaluator_->evaluate(board, BLACK); } else { node_count_++; eval_t a = alpha; eval_t b = beta; bool first = true; BitBoard::data_type moves = board.get_move_bit(); //std::cerr << moves.to_str() << std::endl; unsigned moves_size = moves.size(); if (moves_size == 0) { if (passed) { g = board.get_score() / 1024; } else { Board next_board = board.make_inverse(); g = -evaluate(next_board, depth - 1, true, -beta, -alpha); } } else { if (depth >= max_depth_) { std::cerr << moves.to_str() << std::endl; } BitMoveOrderingIterator it(board, *p_evaluator_); while (it.has_next()) { /* while (moves.any()) { BitBoard::data_type next = moves.get_next_bit(); moves ^= next; BitBoard next_board(board); next_board.move(next); next_board.inverse(); */ BitBoard next_board = it.get_next(); if (depth >= max_depth_ - 2) { BitMatrix move = board.get_blank_bit() ^ next_board.get_blank_bit(); std::cerr << "move: " << Position(move.get_next()).to_str() << " " << move.to_str() << std::endl; } /* // scout eval_t val = -evaluate(next_board, depth - 1, false, -b, -a); if (a < val && val < beta && !first) val = -evaluate(next_board, depth - 1, false, -beta, -val); */ eval_t val = -evaluate(next_board, depth - 1, false, -b, -a); //a = std::max(a, val); if (a < val) { if (depth == max_depth_) next_move_ = (board.get_blank_bit() ^ next_board.get_blank_bit()).get_next(); a = val; } g = std::max(g, val); if (depth == max_depth_) { std::cerr << "a: " << a << ", g: " << g << std::endl; } if (a >= beta) { if (depth == max_depth_) { next_move_ = (board.get_blank_bit() ^ next_board.get_blank_bit()).get_next(); //next_move_ = next.get_next(); std::cerr << "next: " << next_move_ << std::endl; } return a; } //b = a + 1; first = false; it.go_next(); } } } ttc.update_alpha_beta(board, g, alpha, beta); return g; }
void QRcodeReader::decode() { Binarizer binarizer(img); img = binarizer.getBlackMatrix(); if (more) { imshow("original", rgbImg); imshow("test",img); waitKey(0); printf("**************************************************************\n"); printf("Begin detection to find the three finder pattern centers:\n"); } Finder finder = Finder(img); FinderResult fr = finder.find(); if (more) { printf("\n"); printf("Three finder pattern centers:\n"); FinderPoint bL = fr.getBottomLeft(); FinderPoint tL = fr.getTopLeft(); FinderPoint tR = fr.getTopRight(); printf("bottomLeft: (%f, %f)\n", bL.getX(), bL.getY()); printf("topLeft: (%f, %f)\n", tL.getX(), tL.getY()); printf("topRight: (%f, %f)\n", tR.getX(), tR.getY()); Point2f p1 = Point2f(bL.getX(), bL.getY()); circle(rgbImg, p1, 3, Scalar(0,255,0)); Point2f p2 = Point2f(tL.getX(), tL.getY()); circle(rgbImg, p2, 3, Scalar(0,255,0)); Point2f p3 = Point2f(tR.getX(), tR.getY()); circle(rgbImg, p3, 3, Scalar(0,255,0)); imshow("original", rgbImg); waitKey(0); } Detector detector = Detector(img); DetectorResult detectorResult = detector.processFinderPatternInfo(fr); if (more) { vector<FinderPoint> patternPoints = detectorResult.getResultPoints(); BitMatrix bits = detectorResult.getBits(); printf("\n"); printf("Module Size: %f\n", detectorResult.getModuleSize()); printf("Dimension: %d\n", detectorResult.getDimension()); printf("Alignment Pattern : (%f, %f)\n", patternPoints[3].getX(), patternPoints[3].getY()); Point2f p4 = Point2f(patternPoints[3].getX(), patternPoints[3].getY()); circle(rgbImg, p4, 3, Scalar(0,255,0)); imshow("original", rgbImg); waitKey(0); printf("\n"); printf("The bit matrix:\n"); bits.display(); printf("\nDetection Done!\n"); printf("**************************************************************\n"); waitKey(0); } Decoder decoder = Decoder(detectorResult); DecoderResult decoderResult = decoder.decode(); if (more) { printf("Decode:\n"); printf("version : %d\n", decoderResult.getVersion()); printf("Error correct level : %d\n", decoderResult.getEcLevel()); vector<char> resultBytes = decoderResult.getResultBytes(); printf("Data bytes: "); for (int i = 0; i < resultBytes.size(); ++i) { printf("%d ",resultBytes[i]); } printf("\n"); string result = decoderResult.getResultText(); printf("%s\n", result.c_str()); waitKey(0); } else { string result = decoderResult.getResultText(); printf("%s\n", result.c_str()); } }
//----------------------------------------------------------------------------- void RandomPassiveSet(BitMatrix& passive_set, Random& rng, const unsigned int height, const unsigned int width) { passive_set.Resize(height, width); unsigned int* buf_ps = passive_set.Buffer(); const unsigned int ldim = passive_set.LDim(); const unsigned int full_wds = height / BitMatrix::BITS_PER_WORD; const unsigned int extra = height - BitMatrix::BITS_PER_WORD*full_wds; const unsigned int MASK = passive_set.Mask(); // initial nonzero bit pattern to fill columns with unsigned int pattern = 0x01; // randomly shuffle the column indices of the passive set std::vector<unsigned int> col_indices(width); for (unsigned int q=0; q<width; ++q) col_indices[q] = q; if (width > 1) FisherYatesShuffle(col_indices.begin(), col_indices.end(), rng); for (unsigned int c=0; c<width; ++c) { unsigned int col_index = col_indices[c]; unsigned int col_offset = col_index * ldim; // Fill this column with the bit pattern, ensuring that the // final bits in each column (outside the MASK for the passive // set matrix) are zero. unsigned int r_wd=0; for (; r_wd < full_wds; ++r_wd) buf_ps[col_offset + r_wd] = pattern; if (extra > 0) { unsigned int wd = MASK & pattern; assert(wd > 0); buf_ps[col_offset + r_wd] = wd; } // shift the pattern to the left one bit and OR in a new bit pattern <<= 1; pattern |= 1; // start over if all ones if (0xFFFFFFFF == pattern) pattern = 0x01; } // None of the columns should contain all zero bits. std::vector<unsigned int> col_sums(width); passive_set.SumColumns(col_sums); for (unsigned int c=0; c<width; ++c) { if (0 == col_sums[c]) { unsigned int col_offset = c*ldim; cout << "RandomPassiveSet: column " << c << " is a zero column." << endl; cout << "Pattern: " << std::hex << pattern << std::dec << endl; cout << "Height: " << height << ", width: " << width << endl; cout << "full_wds: " << full_wds << endl; cout << "extra: " << extra << endl; cout << "Ldim: " << ldim << ", extra: " << extra << endl; cout << "MASK: " << std::hex << MASK << std::dec << endl; cout << "col_offset: " << col_offset << endl; unsigned int r_wd = 0; for (; r_wd<full_wds; ++r_wd) cout << "words_[" << r_wd << "]: " << std::hex << buf_ps[col_offset + r_wd] << std::dec << endl; if (MASK > 0) { unsigned int wd = MASK & buf_ps[col_offset + r_wd]; cout << "words_[" << r_wd << "]: " << std::hex << wd << std::dec << endl; } assert(0 != col_sums[c]); } } }
void BppUpdateSets(BitMatrix& nonopt_set, BitMatrix& infeas_set, const BitMatrix& not_opt_mask, const DenseMatrix<T>& X, const DenseMatrix<T>& Y, const BitMatrix& passive_set) { // This function performs the equivalent of these operations: // // nonopt_set = not_opt_mask & (Y < T(0)) & ~passive_set; // infeas_set = not_opt_mask & (X < T(0)) & passive_set; const unsigned int height = not_opt_mask.Height(); const unsigned int width = not_opt_mask.Width(); if ( (static_cast<unsigned int>(X.Height()) != height) || (static_cast<unsigned int>(Y.Height()) != height) || (passive_set.Height() != height)) throw std::logic_error("BppUpdateSets: height mismatch"); if ( (static_cast<unsigned int>(X.Width()) != width) || (static_cast<unsigned int>(Y.Width()) != width) || (passive_set.Width() != width)) throw std::logic_error("BppUpdateSets: width mismatch"); nonopt_set.Resize(height, width); infeas_set.Resize(height, width); const unsigned int BITS = BitMatrix::BITS_PER_WORD; const unsigned int MASK = nonopt_set.Mask(); assert(infeas_set.Mask() == MASK); unsigned int* buf_r = nonopt_set.Buffer(); const unsigned int ldim_r = nonopt_set.LDim(); unsigned int* buf_i = infeas_set.Buffer(); const unsigned int ldim_i = infeas_set.LDim(); const unsigned int* buf_m = not_opt_mask.LockedBuffer(); const unsigned int ldim_m = not_opt_mask.LDim(); const T* buf_x = X.LockedBuffer(); const unsigned int ldim_x = X.LDim(); const T* buf_y = Y.LockedBuffer(); const unsigned int ldim_y = Y.LDim(); const unsigned int* buf_p = passive_set.LockedBuffer(); const unsigned int ldim_p = passive_set.LDim(); const unsigned int full_wds = height / BITS; const unsigned int extra = height - BITS*full_wds; assert(ldim_r >= ldim_m); assert(ldim_r >= ldim_p); OPENMP_PRAGMA(omp parallel for) for (unsigned int c=0; c<width; ++c) { unsigned int offset_r = c*ldim_r; unsigned int offset_i = c*ldim_i; unsigned int offset_m = c*ldim_m; unsigned int offset_x = c*ldim_x; unsigned int offset_y = c*ldim_y; unsigned int offset_p = c*ldim_p; unsigned int r_wd = 0, r=0; for (; r_wd<full_wds; ++r_wd) { unsigned int x_wd = 0, y_wd = 0; for (unsigned int q=0; q<BITS; ++q, ++r) { if (buf_x[offset_x + r] < T(0)) x_wd |= (1 << q); if (buf_y[offset_y + r] < T(0)) y_wd |= (1 << q); } buf_r[offset_r + r_wd] = buf_m[offset_m + r_wd] & y_wd & ~buf_p[offset_p + r_wd]; buf_i[offset_i + r_wd] = buf_m[offset_m + r_wd] & x_wd & buf_p[offset_p + r_wd]; } if (extra > 0) { unsigned int x_wd = 0, y_wd = 0; for (unsigned int q=0; q<extra; ++q, ++r) { if (buf_x[offset_x + r] < T(0)) x_wd |= (1 << q); if (buf_y[offset_y + r] < T(0)) y_wd |= (1 << q); } buf_r[offset_r + r_wd] = MASK & buf_m[offset_m + r_wd] & y_wd & ~buf_p[offset_p + r_wd]; buf_i[offset_i + r_wd] = MASK & buf_m[offset_m + r_wd] & x_wd & buf_p[offset_p + r_wd]; } } }
void findEdgePoints(std::vector<Point>& points, const BitMatrix& image, Point start, Point end, bool invert, int skip, float deviation) { float xdist = end.x - start.x; float ydist = end.y - start.y; float length = sqrt(xdist * xdist + ydist * ydist); int var; if (abs(xdist) > abs(ydist)) { // Horizontal if (xdist < 0) skip = -skip; var = int(abs(deviation * length / xdist)); float dy = ydist / xdist * skip; bool left = (skip < 0) ^ invert; int x = int(start.x); int steps = int(xdist / skip); for (int i = 0; i < steps; i++) { x += skip; if (x < 0 || x >= (int)image.getWidth()) continue; // In case we start off the edge int my = int(start.y + dy * i); int ey = min(my + var + 1, (int)image.getHeight() - 1); int sy = max(my - var, 0); for (int y = sy + 1; y < ey; y++) { if (left) { if (image.get(x, y) && !image.get(x, y + 1)) { points.push_back(Point(x, y + 0.5f)); } } else { if (!image.get(x, y) && image.get(x, y + 1)) { points.push_back(Point(x, y + 0.5f)); } } } } } else { // Vertical if (ydist < 0) skip = -skip; var = int(abs(deviation * length / ydist)); float dx = xdist / ydist * skip; bool down = (skip > 0) ^ invert; int y = int(start.y); int steps = int(ydist / skip); for (int i = 0; i < steps; i++) { y += skip; if (y < 0 || y >= (int)image.getHeight()) continue; // In case we start off the edge int mx = int(start.x + dx * i); int ex = min(mx + var + 1, (int)image.getWidth() - 1); int sx = max(mx - var, 0); for (int x = sx + 1; x < ex; x++) { if (down) { if (image.get(x, y) && !image.get(x + 1, y)) { points.push_back(Point(x + 0.5f, y)); } } else { if (!image.get(x, y) && image.get(x + 1, y)) { points.push_back(Point(x + 0.5f, y)); } } } } } }
bool WhiteRectDetector::Detect(const BitMatrix& image, ResultPoint& p0, ResultPoint& p1, ResultPoint& p2, ResultPoint& p3) { return Detect(image, INIT_SIZE, image.width() / 2, image.height() / 2, p0, p1, p2, p3); }