Example usage for org.opencv.core Mat rows

List of usage examples for org.opencv.core Mat rows

Introduction

In this page you can find the example usage for org.opencv.core Mat rows.

Prototype

public int rows() 

Source Link

Usage

From source file:com.shootoff.camera.autocalibration.AutoCalibrationManager.java

License:Open Source License

public Optional<Bounds> calibrateFrame(MatOfPoint2f boardCorners, Mat mat) {

    // For debugging
    Mat traceMat = null;/*  w w  w. ja  v  a 2 s.  c o m*/
    if (logger.isTraceEnabled()) {
        traceMat = mat.clone();
    }

    initializeSize(mat.cols(), mat.rows());

    // Step 2: Estimate the pattern corners
    MatOfPoint2f estimatedPatternRect = estimatePatternRect(traceMat, boardCorners);

    // Step 3: Use Hough Lines to find the actual corners
    final Optional<MatOfPoint2f> idealCorners = findIdealCorners(mat, estimatedPatternRect);

    if (!idealCorners.isPresent())
        return Optional.empty();

    if (logger.isTraceEnabled()) {
        String filename = String.format("calibrate-dist.png");
        final File file = new File(filename);
        filename = file.toString();
        Highgui.imwrite(filename, traceMat);
    }

    // Step 4: Initialize the warp matrix and bounding box
    initializeWarpPerspective(mat, idealCorners.get());

    if (boundingBox.getMinX() < 0 || boundingBox.getMinY() < 0
            || boundingBox.getWidth() > cameraManager.getFeedWidth()
            || boundingBox.getHeight() > cameraManager.getFeedHeight()) {
        return Optional.empty();
    }

    if (logger.isDebugEnabled())
        logger.debug("bounds {} {} {} {}", boundingBox.getMinX(), boundingBox.getMinY(), boundingBox.getWidth(),
                boundingBox.getHeight());

    final Mat undistorted = warpPerspective(mat);

    if (logger.isTraceEnabled()) {

        String filename = String.format("calibrate-undist.png");
        File file = new File(filename);
        filename = file.toString();
        Highgui.imwrite(filename, undistorted);

        Mat undistortedCropped = undistorted.submat((int) boundingBox.getMinY(), (int) boundingBox.getMaxY(),
                (int) boundingBox.getMinX(), (int) boundingBox.getMaxX());

        filename = String.format("calibrate-undist-cropped.png");
        file = new File(filename);
        filename = file.toString();
        Highgui.imwrite(filename, undistortedCropped);
    }

    Mat warpedBoardCorners = warpCorners(boardCorners);

    isCalibrated = true;

    if (calculateFrameDelay) {
        findColors(undistorted, warpedBoardCorners);

        final double squareHeight = boundingBox.getHeight() / (double) (PATTERN_HEIGHT + 1);
        final double squareWidth = boundingBox.getWidth() / (double) (PATTERN_WIDTH + 1);

        int secondSquareCenterX = (int) (boundingBox.getMinX() + (squareWidth * 1.5));
        int secondSquareCenterY = (int) (boundingBox.getMinY() + (squareHeight * .5));

        if (logger.isDebugEnabled())
            logger.debug("pF getFrameDelayPixel x {} y {} p {}", secondSquareCenterX, secondSquareCenterY,
                    undistorted.get(secondSquareCenterY, secondSquareCenterX));

    }

    return Optional.of(boundingBox);
}

From source file:com.shootoff.camera.autocalibration.AutoCalibrationManager.java

License:Open Source License

/**
 * Perspective pattern discovery// w ww .  j  a v a 2  s  .  com
 * 
 * Works similar to arena calibration but does not try to identify the
 * outline of the projection area We are only concerned with size, not
 * alignment or angle
 * 
 * This function blanks out the pattern that it discovers in the Mat it is
 * provided. This is so that the pattern is not discovered by future pattern
 * discovery, e.g. auto-calibration
 * 
 * workingMat should be null for all external callers unless there is some
 * need to work off a different Mat than is having patterns blanked out by
 * this function
 */
public Optional<Dimension2D> findPaperPattern(MatOfPoint2f boardCorners, Mat mat, Mat workingMat) {

    if (workingMat == null)
        workingMat = mat.clone();

    initializeSize(workingMat.cols(), workingMat.rows());

    // Step 2: Estimate the pattern corners
    final BoundingBox box = getPaperPatternDimensions(workingMat, boardCorners);

    // OpenCV gives us the checkerboard corners, not the outside dimension
    // So this estimates where the outside corner would be, plus a fudge
    // factor for the edge of the paper
    // Printer margins are usually a quarter inch on each edge
    double width = ((double) box.getWidth() * ((double) (PATTERN_WIDTH + 1) / (double) (PATTERN_WIDTH - 1))
            * 1.048);
    double height = ((double) box.getHeight() * ((double) (PATTERN_HEIGHT + 1) / (double) (PATTERN_HEIGHT - 1))
            * 1.063);

    final double PAPER_PATTERN_SIZE_THRESHOLD = .25;
    if (width > PAPER_PATTERN_SIZE_THRESHOLD * workingMat.cols()
            || height > PAPER_PATTERN_SIZE_THRESHOLD * workingMat.rows()) {
        logger.trace("Pattern too big to be paper, must be projection, setting blank {} x {}", box.getWidth(),
                box.getHeight());

        workingMat.submat((int) box.getMinY(), (int) box.getMaxY(), (int) box.getMinX(), (int) box.getMaxX())
                .setTo(new Scalar(0, 0, 0));

        if (logger.isTraceEnabled()) {
            String filename = String.format("blanked-box.png");
            File file = new File(filename);
            filename = file.toString();
            Highgui.imwrite(filename, workingMat);

        }

        final Optional<MatOfPoint2f> boardCornersNew = findChessboard(workingMat);

        if (!boardCornersNew.isPresent())
            return Optional.empty();

        logger.trace("Found new pattern, attempting findPaperPattern {}", boardCornersNew.get());

        return findPaperPattern(boardCornersNew.get(), mat, workingMat);

    }

    if (logger.isTraceEnabled()) {
        logger.trace("pattern width {} height {}", box.getWidth(), box.getHeight());

        logger.trace("paper width {} height {}", width, height);

        int widthOffset = ((int) width - (int) box.getWidth()) / 2;
        int heightOffset = ((int) height - (int) box.getHeight()) / 2;

        logger.trace("offset width {} height {}", widthOffset, heightOffset);

        Mat fullpattern = workingMat.clone();

        // TODO: This doesn't work if the pattern is upside down, but this is for debugging anyway right now
        // Should fix in case it causes an out of bounds or something
        Point topLeft = new Point(boardCorners.get(0, 0)[0], boardCorners.get(0, 0)[1]);
        Point topRight = new Point(boardCorners.get(PATTERN_WIDTH - 1, 0)[0],
                boardCorners.get(PATTERN_WIDTH - 1, 0)[1]);
        Point bottomRight = new Point(boardCorners.get(PATTERN_WIDTH * PATTERN_HEIGHT - 1, 0)[0],
                boardCorners.get(PATTERN_WIDTH * PATTERN_HEIGHT - 1, 0)[1]);
        Point bottomLeft = new Point(boardCorners.get(PATTERN_WIDTH * (PATTERN_HEIGHT - 1), 0)[0],
                boardCorners.get(PATTERN_WIDTH * (PATTERN_HEIGHT - 1), 0)[1]);

        Core.circle(fullpattern, topLeft, 1, new Scalar(255, 0, 0), -1);
        Core.circle(fullpattern, topRight, 1, new Scalar(255, 0, 0), -1);
        Core.circle(fullpattern, bottomRight, 1, new Scalar(255, 0, 0), -1);
        Core.circle(fullpattern, bottomLeft, 1, new Scalar(255, 0, 0), -1);

        String filename = String.format("marked-box.png");
        File file = new File(filename);
        filename = file.toString();
        Highgui.imwrite(filename, fullpattern);

        fullpattern = fullpattern.submat((int) box.getMinY() - heightOffset,
                (int) box.getMinY() - heightOffset + (int) height, (int) box.getMinX() - widthOffset,
                (int) box.getMinX() - widthOffset + (int) width);

        filename = String.format("full-box.png");
        file = new File(filename);
        filename = file.toString();
        Highgui.imwrite(filename, fullpattern);

        Mat cropped = workingMat.submat((int) box.getMinY(), (int) box.getMaxY(), (int) box.getMinX(),
                (int) box.getMaxX());

        filename = String.format("pattern-box.png");
        file = new File(filename);
        filename = file.toString();
        Highgui.imwrite(filename, cropped);
    }

    mat.submat((int) box.getMinY(), (int) box.getMaxY(), (int) box.getMinX(), (int) box.getMaxX())
            .setTo(new Scalar(0, 0, 0));

    return Optional.of(new Dimension2D(width, height));
}

From source file:com.shootoff.camera.shotdetection.JavaShotDetector.java

License:Open Source License

private Set<Pixel> findThresholdPixelsAndUpdateFilter(final Mat workingFrame, final boolean detectShots) {
    dynamicallyThresholded = 0;//from w  w  w  .  j a v a 2s . c  o  m

    final Set<Pixel> thresholdPixels = Collections.synchronizedSet(new HashSet<Pixel>());

    if (!cameraManager.isDetecting())
        return thresholdPixels;

    final int subWidth = workingFrame.cols() / SECTOR_COLUMNS;
    final int subHeight = workingFrame.rows() / SECTOR_ROWS;

    final int cols = workingFrame.cols();
    final int channels = workingFrame.channels();

    final int size = (int) (workingFrame.total() * channels);
    final byte[] workingFramePrimitive = new byte[size];
    workingFrame.get(0, 0, workingFramePrimitive);

    // In this loop we accomplish both MovingAverage updates AND threshold
    // pixel detection
    Parallel.forIndex(0, (SECTOR_ROWS * SECTOR_COLUMNS), 1, new Operation<Integer>() {
        public void perform(Integer sector) {
            final int sectorX = sector.intValue() % SECTOR_COLUMNS;
            final int sectorY = sector.intValue() / SECTOR_ROWS;

            if (!cameraManager.isSectorOn(sectorX, sectorY))
                return;

            final int startX = subWidth * sectorX;
            final int startY = subHeight * sectorY;

            for (int y = startY; y < startY + subHeight; y++) {
                final int yOffset = y * cols;
                for (int x = startX; x < startX + subWidth; x++) {
                    final int currentH = workingFramePrimitive[(yOffset + x) * channels] & 0xFF;
                    final int currentS = workingFramePrimitive[(yOffset + x) * channels + 1] & 0xFF;
                    final int currentV = workingFramePrimitive[(yOffset + x) * channels + 2] & 0xFF;

                    final Pixel pixel = updateFilter(currentH, currentS, currentV, x, y, detectShots);

                    if (pixel != null)
                        thresholdPixels.add(pixel);
                }
            }
        }
    });

    return thresholdPixels;
}

From source file:com.shootoff.camera.shotdetection.PixelCluster.java

License:Open Source License

public double getColorDifference(final Mat workingFrame, final int[][] colorDistanceFromRed) {
    final Map<Pixel, byte[]> visited = new HashMap<Pixel, byte[]>();
    int avgSaturation = 0;

    for (final Pixel pixel : this) {
        if (pixel.getConnectedness() < MAXIMUM_CONNECTEDNESS) {
            for (int h = -1; h <= 1; h++) {
                for (int w = -1; w <= 1; w++) {
                    if (h == 0 && w == 0)
                        continue;

                    final int rx = pixel.x + w;
                    final int ry = pixel.y + h;

                    if (rx < 0 || ry < 0 || rx >= workingFrame.cols() || ry >= workingFrame.rows())
                        continue;

                    final Pixel nearPoint = new Pixel(rx, ry);

                    if (!visited.containsKey(nearPoint) && !this.contains(nearPoint)) {
                        byte[] np = { 0, 0, 0 };
                        workingFrame.get(ry, rx, np);
                        final int npSaturation = np[1] & 0xFF;

                        avgSaturation += npSaturation;

                        visited.put(nearPoint, np);
                    }/*from   w  ww  .  j  av  a  2  s. c om*/
                }
            }
        }
    }

    final int pixelCount = visited.size();
    if (pixelCount == 0)
        return 0;

    avgSaturation /= pixelCount;

    int colorDistance = 0;
    int avgColorDistance = 0;
    int tempColorDistance = 0;

    for (final Entry<Pixel, byte[]> pixelEntry : visited.entrySet()) {
        byte[] np = pixelEntry.getValue();
        final int npSaturation = np[1] & 0xFF;

        if (npSaturation > avgSaturation) {
            final int npColor = np[0] & 0xFF;
            final int npLum = np[2] & 0xFF;

            final int thisDFromRed = Math.min(npColor, Math.abs(180 - npColor)) * npLum * npSaturation;
            final int thisDFromGreen = Math.abs(60 - npColor) * npLum * npSaturation;

            final int currentCol = thisDFromRed - thisDFromGreen;

            final Pixel pixel = pixelEntry.getKey();
            colorDistance += currentCol
                    - (int) (CURRENT_COLOR_BIAS_MULTIPLIER * colorDistanceFromRed[pixel.x][pixel.y]);

            if (logger.isTraceEnabled()) {
                tempColorDistance += currentCol;
                avgColorDistance += colorDistanceFromRed[pixel.x][pixel.y];
            }
        }
    }

    if (logger.isTraceEnabled())
        logger.trace("Pixels {} Color {} avg {} sum {}", pixelCount, colorDistance / pixelCount,
                avgColorDistance / pixelCount, tempColorDistance / pixelCount);

    return colorDistance;
}

From source file:com.sikulix.core.Finder.java

License:Open Source License

private static void printMatI(Mat mat) {
    int[] data = new int[mat.channels()];
    for (int r = 0; r < mat.rows(); r++) {
        for (int c = 0; c < mat.cols(); c++) {
            mat.get(r, c, data);//  w w  w  .  j  a  v  a  2s  . c o  m
            log.trace("(%d, %d) %s", r, c, Arrays.toString(data));
        }
    }
}

From source file:com.trandi.opentld.tld.BoundingBox.java

License:Apache License

BoundingBox intersect(final Mat img) {
    final BoundingBox result = new BoundingBox();
    result.x = Math.max(x, 0);//from www  .j  av  a  2 s  .c om
    result.y = Math.max(y, 0);
    result.width = (int) Math.min(Math.min(img.cols() - x, width), Math.min(width, br().x));
    result.height = (int) Math.min(Math.min(img.rows() - y, height), Math.min(height, br().y));
    return result;
}

From source file:com.trandi.opentld.tld.Grid.java

License:Apache License

Grid(Mat img, Rect trackedBox, int minWinSide) {
    // TODO why do we generate so many BAD boxes, only to remove them later on !?
    // OR do we need them to re-asses which ones are bad later on ?
    for (int s = 0; s < SCALES.length; s++) {
        final int width = Math.round(trackedBox.width * SCALES[s]);
        final int height = Math.round(trackedBox.height * SCALES[s]);
        final int minBbSide = Math.min(height, width);

        // continue ONLY if the future box is "reasonable": bigger than the min window and smaller than the full image !
        if (minBbSide >= minWinSide && width <= img.cols() && height <= img.rows()) {
            trackedBoxScales.add(new Size(width, height));
            final int shift = Math.round(SHIFT * minBbSide);

            for (int row = 1; row < (img.rows() - height); row += shift) {
                for (int col = 1; col < (img.cols() - width); col += shift) {
                    final BoundingBox bbox = new BoundingBox();
                    bbox.x = col;/*w  w  w  .  j  ava  2  s  . c o  m*/
                    bbox.y = row;
                    bbox.width = width;
                    bbox.height = height;
                    bbox.scaleIdx = trackedBoxScales.size() - 1; // currently last one in this list

                    grid.add(bbox);
                }
            }
        }
    }
}

From source file:com.trandi.opentld.tld.Tld.java

License:Apache License

public void init(Mat frame1, Rect trackedBox) {
    // get Bounding boxes
    if (Math.min(trackedBox.width, trackedBox.height) < _params.min_win) {
        throw new IllegalArgumentException(
                "Provided trackedBox: " + trackedBox + " is too small (min " + _params.min_win + ")");
    }/*  w  ww  . j a v a2 s . com*/
    _grid = new Grid(frame1, trackedBox, _params.min_win);
    Log.i(Util.TAG, "Init Created " + _grid.getSize() + " bounding boxes.");
    _grid.updateGoodBadBoxes(trackedBox, _params.num_closest_init);

    _iiRows = frame1.rows();
    _iiCols = frame1.cols();
    _iisum.create(_iiRows, _iiCols, CvType.CV_32F);
    _iisqsum.create(_iiRows, _iiCols, CvType.CV_64F);

    // correct bounding box
    _lastbox = _grid.getBestBox();

    _classifierFern.init(_grid.getTrackedBoxScales(), _rng);

    // generate DATA
    // generate POSITIVE DATA
    generatePositiveData(frame1, _params.num_warps_init, _grid);

    // Set variance threshold
    MatOfDouble stddev = new MatOfDouble();
    Core.meanStdDev(frame1.submat(_grid.getBestBox()), new MatOfDouble(), stddev);
    updateIntegralImgs(frame1);
    // this is directly half of the variance of the initial box, which will be used the the 1st stage of the classifier
    _var = (float) Math.pow(stddev.toArray()[0], 2d) * 0.5f;
    // check variance
    final double checkVar = Util.getVar(_grid.getBestBox(), _iisumJava, _iisqsumJava, _iiCols) * 0.5;
    Log.i(Util.TAG, "Variance: " + _var + " / Check variance: " + checkVar);

    // generate NEGATIVE DATA
    final Pair<List<Pair<int[], Boolean>>, List<Mat>> negData = generateNegativeData(frame1);

    // Split Negative Ferns <features, labels=false> into Training and Testing sets (they are already shuffled)
    final int nFernsSize = negData.first.size();
    final List<Pair<int[], Boolean>> nFernsTest = new ArrayList<Pair<int[], Boolean>>(
            negData.first.subList(0, nFernsSize / 2));
    final List<Pair<int[], Boolean>> nFerns = new ArrayList<Pair<int[], Boolean>>(
            negData.first.subList(nFernsSize / 2, nFernsSize));

    // Split Negative NN Examples into Training and Testing sets
    final int nExSize = negData.second.size();
    final List<Mat> nExamplesTest = new ArrayList<Mat>(negData.second.subList(0, nExSize / 2));
    _nExamples = new ArrayList<Mat>(negData.second.subList(nExSize / 2, nExSize));

    //MERGE Negative Data with Positive Data and shuffle it
    final List<Pair<int[], Boolean>> fernsData = new ArrayList<Pair<int[], Boolean>>(_pFerns);
    fernsData.addAll(nFerns);
    Collections.shuffle(fernsData);

    // TRAINING
    Log.i(Util.TAG, "Init Start Training with " + fernsData.size() + " ferns, " + _nExamples.size()
            + " nExamples, " + nFernsTest.size() + " nFernsTest, " + nExamplesTest.size() + " nExamplesTest");
    _classifierFern.trainF(fernsData, 10);
    _classifierNN.trainNN(_pExample, _nExamples);
    // Threshold evaluation on testing sets
    _classifierFern.evaluateThreshold(nFernsTest);
    _classifierNN.evaluateThreshold(nExamplesTest);
}

From source file:com.trandi.opentld.tld.Tld.java

License:Apache License

private TrackingStruct track(final Mat lastImg, final Mat currentImg, final BoundingBox lastBox) {
    Log.i(Util.TAG, "[TRACK]");

    // Generate points
    final Point[] lastPoints = lastBox.points();
    if (lastPoints.length == 0) {
        Log.e(Util.TAG, "Points not generated from lastBox: " + lastBox);
        return null;
    }/*  w  ww  .  j  a v a 2  s. c  o m*/

    // Frame-to-frame tracking with forward-backward error checking
    final Pair<Point[], Point[]> trackedPoints = _tracker.track(lastImg, currentImg, lastPoints);
    if (trackedPoints == null) {
        Log.e(Util.TAG, "No points could be tracked.");
        return null;
    }
    if (_tracker.getMedianErrFB() > _params.tracker_stability_FBerrMax) {
        Log.w(Util.TAG, "TRACKER too unstable. FB Median error: " + _tracker.getMedianErrFB() + " > "
                + _params.tracker_stability_FBerrMax);
        // return null;  // we hope the detection will find the pattern again
    }

    // bounding box prediction
    final BoundingBox predictedBB = lastBox.predict(trackedPoints.first, trackedPoints.second);
    if (predictedBB.x > currentImg.cols() || predictedBB.y > currentImg.rows() || predictedBB.br().x < 1
            || predictedBB.br().y < 1) {
        Log.e(Util.TAG, "TRACKER Predicted bounding box out of range !");
        return null;
    }

    // estimate Confidence
    Mat pattern = new Mat();
    try {
        resizeZeroMeanStdev(currentImg.submat(predictedBB.intersect(currentImg)), pattern, _params.patch_size);
    } catch (Throwable t) {
        Log.e(Util.TAG, "PredBB when failed: " + predictedBB);
    }
    //Log.i(Util.TAG, "Confidence " + pattern.dump());      

    //Conservative Similarity
    final NNConfStruct nnConf = _classifierNN.nnConf(pattern);
    Log.i(Util.TAG, "Tracking confidence: " + nnConf.conservativeSimilarity);

    Log.i(Util.TAG, "[TRACK END]");
    return new TrackingStruct(nnConf.conservativeSimilarity, predictedBB, trackedPoints.first,
            trackedPoints.second);
}

From source file:com.trandi.opentld.tld.Tld.java

License:Apache License

/**
 * Structure the classifier into 3 stages:
 * a) patch variance/*  w  w  w . j  ava2  s  . c o m*/
 * b) ensemble of ferns classifier
 * c) nearest neighbour
 */
private Pair<List<DetectionStruct>, List<DetectionStruct>> detect(final Mat frame) {
    Log.i(Util.TAG, "[DETECT]");

    final List<DetectionStruct> fernClassDetected = new ArrayList<Tld.DetectionStruct>(); //dt
    final List<DetectionStruct> nnMatches = new ArrayList<Tld.DetectionStruct>(); //dbb

    // 0. Cleaning
    _boxClusterMap.clear();

    // 1. DETECTION
    final Mat img = new Mat(frame.rows(), frame.cols(), CvType.CV_8U);
    updateIntegralImgs(frame);
    Imgproc.GaussianBlur(frame, img, new Size(9, 9), 1.5);

    // Apply the Variance filter TODO : Bottleneck
    int a = 0;
    for (BoundingBox box : _grid) {
        // a) speed up by doing the features/ferns check ONLY if the variance is high enough !
        if (Util.getVar(box, _iisumJava, _iisqsumJava, _iiCols) >= _var) {
            a++;
            final Mat patch = img.submat(box);
            final int[] allFernsHashCodes = _classifierFern.getAllFernsHashCodes(patch, box.scaleIdx);
            final double averagePosterior = _classifierFern.averagePosterior(allFernsHashCodes);
            _fernDetectionNegDataForLearning.put(box, allFernsHashCodes);// store for later use in learning

            // b)
            if (averagePosterior > _classifierFern.getFernPosThreshold()) {
                fernClassDetected.add(new DetectionStruct(box, allFernsHashCodes, averagePosterior, patch));
            }
        }
    }

    Log.i(Util.TAG, a + " Bounding boxes passed the variance filter (" + _var + ")");
    Log.i(Util.TAG, fernClassDetected.size() + " Initial detected from Fern Classifier");
    if (fernClassDetected.size() == 0) {
        Log.i(Util.TAG, "[DETECT END]");
        return null;
    }

    // keep only the best
    Util.keepBestN(fernClassDetected, MAX_DETECTED, new Comparator<DetectionStruct>() {
        @Override
        public int compare(DetectionStruct detS1, DetectionStruct detS2) {
            return Double.compare(detS1.averagePosterior, detS2.averagePosterior);
        }
    });

    // 2. MATCHING using the NN classifier  c)
    for (DetectionStruct detStruct : fernClassDetected) {
        // update detStruct.patch to params.patch_size and normalise it
        Mat pattern = new Mat();
        resizeZeroMeanStdev(detStruct.patch, pattern, _params.patch_size);
        detStruct.nnConf = _classifierNN.nnConf(pattern);

        Log.i(Util.TAG, "NNConf: " + detStruct.nnConf.relativeSimilarity + " / "
                + detStruct.nnConf.conservativeSimilarity + " Threshold: " + _classifierNN.getNNThreshold());
        // only keep valid boxes
        if (detStruct.nnConf.relativeSimilarity > _classifierNN.getNNThreshold()) {
            nnMatches.add(detStruct);
        }
    }

    Log.i(Util.TAG, "[DETECT END]");
    return new Pair<List<DetectionStruct>, List<DetectionStruct>>(fernClassDetected, nnMatches);
}