List of usage examples for org.opencv.core MatOfPoint2f alloc
public void alloc(int elemNumber)
From source file:com.shootoff.camera.autocalibration.AutoCalibrationManager.java
License:Open Source License
private MatOfPoint2f estimateFullPatternSize(MatOfPoint2f rect) { // Result Mat final MatOfPoint2f result = new MatOfPoint2f(); result.alloc(4); // Get the sources as points final Point topLeft = new Point(rect.get(0, 0)[0], rect.get(0, 0)[1]); final Point topRight = new Point(rect.get(1, 0)[0], rect.get(1, 0)[1]); final Point bottomRight = new Point(rect.get(2, 0)[0], rect.get(2, 0)[1]); final Point bottomLeft = new Point(rect.get(3, 0)[0], rect.get(3, 0)[1]); // We need the heights and widths to estimate the square sizes final double topWidth = Math .sqrt(Math.pow(topRight.x - topLeft.x, 2) + Math.pow(topRight.y - topLeft.y, 2)); final double leftHeight = Math .sqrt(Math.pow(bottomLeft.x - topLeft.x, 2) + Math.pow(bottomLeft.y - topLeft.y, 2)); final double bottomWidth = Math .sqrt(Math.pow(bottomRight.x - bottomLeft.x, 2) + Math.pow(bottomRight.y - bottomLeft.y, 2)); final double rightHeight = Math .sqrt(Math.pow(bottomRight.x - topRight.x, 2) + Math.pow(bottomRight.y - topRight.y, 2)); if (logger.isTraceEnabled()) { logger.trace("points {} {} {} {}", topLeft, topRight, bottomRight, bottomLeft); double angle = Math.atan((topRight.y - topLeft.y) / (topRight.x - topLeft.x)) * 180 / Math.PI; double angle2 = Math.atan((bottomRight.y - bottomLeft.y) / (bottomRight.x - bottomLeft.x)) * 180 / Math.PI;/*from www .j a v a2 s .c om*/ logger.trace("square size {} {} - angle {}", topWidth / (PATTERN_WIDTH - 1), leftHeight / (PATTERN_HEIGHT - 1), angle); logger.trace("square size {} {} - angle {}", bottomWidth / (PATTERN_WIDTH - 1), rightHeight / (PATTERN_HEIGHT - 1), angle2); } // Estimate the square widths, that is what we base the estimate of the // real corners on double squareTopWidth = (1 + BORDER_FACTOR) * (topWidth / (PATTERN_WIDTH - 1)); double squareLeftHeight = (1 + BORDER_FACTOR) * (leftHeight / (PATTERN_HEIGHT - 1)); double squareBottomWidth = (1 + BORDER_FACTOR) * (bottomWidth / (PATTERN_WIDTH - 1)); double squareRightHeight = (1 + BORDER_FACTOR) * (rightHeight / (PATTERN_HEIGHT - 1)); // The estimations double[] newTopLeft = { topLeft.x - squareTopWidth, topLeft.y - squareLeftHeight }; double[] newBottomLeft = { bottomLeft.x - squareBottomWidth, bottomLeft.y + squareLeftHeight }; double[] newTopRight = { topRight.x + squareTopWidth, topRight.y - squareRightHeight }; double[] newBottomRight = { bottomRight.x + squareBottomWidth, bottomRight.y + squareRightHeight }; // Populate the result result.put(0, 0, newTopLeft); result.put(1, 0, newTopRight); result.put(2, 0, newBottomRight); result.put(3, 0, newBottomLeft); // Calculate the new heights (We don't need the widths but I'll leave // the code here commented out) // double newTopWidth = Math.sqrt(Math.pow(newTopRight[0] - // newTopLeft[0],2) + Math.pow(newTopRight[1] - newTopLeft[1],2)); // double newBottomWidth = Math.sqrt(Math.pow(newBottomRight[0] - // newBottomLeft[0],2) + Math.pow(newBottomRight[1] - // newBottomLeft[1],2)); double newLeftHeight = Math.sqrt( Math.pow(newBottomLeft[0] - newTopLeft[0], 2) + Math.pow(newBottomLeft[1] - newTopLeft[1], 2)); double newRightHeight = Math.sqrt( Math.pow(newBottomRight[0] - newTopRight[0], 2) + Math.pow(newBottomRight[1] - newTopRight[1], 2)); // The minimum dimension is always from the height because the pattern // is shorter on that side // Technically it is possible that the pattern is super stretched out, // but in that case I think we're // better off failing minimumDimension = newLeftHeight < newRightHeight ? newLeftHeight : newRightHeight; return result; }
From source file:com.shootoff.camera.autocalibration.AutoCalibrationManager.java
License:Open Source License
private MatOfPoint2f rotateRect(Mat rotMat, MatOfPoint2f boardRect) { final MatOfPoint2f result = new MatOfPoint2f(); result.alloc(4); for (int i = 0; i < 4; i++) { final Point rPoint = rotPoint(rotMat, new Point(boardRect.get(i, 0)[0], boardRect.get(i, 0)[1])); final double[] rPointD = new double[2]; rPointD[0] = rPoint.x;/*from w w w . ja va 2 s.c o m*/ rPointD[1] = rPoint.y; result.put(i, 0, rPointD); } return result; }
From source file:com.shootoff.camera.autocalibration.AutoCalibrationManager.java
License:Open Source License
private Optional<MatOfPoint2f> findIdealCorners(final Mat frame, final MatOfPoint2f estimatedPatternRect) { Mat traceMat = null;/*from w w w . j a va 2 s . c om*/ if (logger.isTraceEnabled()) { Mat traceMatTemp = frame.clone(); traceMat = new Mat(); Imgproc.cvtColor(traceMatTemp, traceMat, Imgproc.COLOR_GRAY2BGR); } // pixel distance, dynamic because we want to allow any resolution or // distance from pattern final int toleranceThreshold = (int) (minimumDimension / (double) (PATTERN_HEIGHT - 1) / 1.5); // Grey scale conversion. //final Mat grey = new Mat(); //Imgproc.cvtColor(frame, grey, Imgproc.COLOR_BGR2GRAY); final Mat grey = frame; // Find edges Imgproc.Canny(grey, grey, CANNY_THRESHOLD_1, CANNY_THRESHOLD_2); // Blur the lines, otherwise the lines algorithm does not consider them Imgproc.GaussianBlur(grey, grey, gaussianBlurSize, GAUSSIANBLUR_SIGMA); if (logger.isTraceEnabled()) { logger.trace("tolerance threshold {} minimumDimension {}", toleranceThreshold, minimumDimension); String filename = String.format("calibrate-undist-grey-lines.png"); File file = new File(filename); filename = file.toString(); Highgui.imwrite(filename, grey); } if (logger.isDebugEnabled()) logger.debug("estimation {} {} {} {}", estimatedPatternRect.get(0, 0), estimatedPatternRect.get(1, 0), estimatedPatternRect.get(2, 0), estimatedPatternRect.get(3, 0)); // Easier to work off of Points final Point[] estimatedPoints = matOfPoint2fToPoints(estimatedPatternRect); if (logger.isTraceEnabled()) { Core.circle(traceMat, estimatedPoints[0], 1, new Scalar(0, 0, 255), -1); Core.circle(traceMat, estimatedPoints[1], 1, new Scalar(0, 0, 255), -1); Core.circle(traceMat, estimatedPoints[2], 1, new Scalar(0, 0, 255), -1); Core.circle(traceMat, estimatedPoints[3], 1, new Scalar(0, 0, 255), -1); } // Find lines // These parameters are just guesswork right now final Mat mLines = new Mat(); final int minLineSize = (int) (minimumDimension * .90); final int lineGap = toleranceThreshold; // Do it Imgproc.HoughLinesP(grey, mLines, HOUGHLINES_RHO, HOUGHLINES_THETA, HOUGHLINES_THRESHOLD, minLineSize, lineGap); // Find the lines that match our estimates final Set<double[]> verifiedLines = new HashSet<double[]>(); for (int x = 0; x < mLines.cols(); x++) { final double[] vec = mLines.get(0, x); final double x1 = vec[0], y1 = vec[1], x2 = vec[2], y2 = vec[3]; final Point start = new Point(x1, y1); final Point end = new Point(x2, y2); if (nearPoints(estimatedPoints, start, toleranceThreshold) && nearPoints(estimatedPoints, end, toleranceThreshold)) { verifiedLines.add(vec); if (logger.isTraceEnabled()) { Core.line(traceMat, start, end, new Scalar(255, 0, 0), 1); } } } if (logger.isTraceEnabled()) logger.trace("verifiedLines: {}", verifiedLines.size()); // Reduce the lines to possible corners final Set<Point> possibleCorners = new HashSet<Point>(); for (double[] line1 : verifiedLines) { for (double[] line2 : verifiedLines) { if (line1 == line2) continue; Optional<Point> intersection = computeIntersect(line1, line2); if (intersection.isPresent()) possibleCorners.add(intersection.get()); } } // Reduce the possible corners to ideal corners Point[] idealCorners = new Point[4]; final double[] idealDistances = { toleranceThreshold, toleranceThreshold, toleranceThreshold, toleranceThreshold }; for (Point pt : possibleCorners) { for (int i = 0; i < 4; i++) { final double distance = euclideanDistance(pt, estimatedPoints[i]); if (distance < idealDistances[i]) { idealDistances[i] = distance; idealCorners[i] = pt; } } } if (logger.isTraceEnabled()) { logger.trace("idealDistances {} {} {} {}", idealDistances[0], idealDistances[1], idealDistances[2], idealDistances[3]); String filename = String.format("calibrate-lines.png"); File file = new File(filename); filename = file.toString(); Highgui.imwrite(filename, traceMat); } // Verify that we have the corners we need for (Point pt : idealCorners) { if (pt == null) return Optional.empty(); if (logger.isTraceEnabled()) { logger.trace("idealCorners {}", pt); Core.circle(traceMat, pt, 1, new Scalar(0, 255, 255), -1); } } if (logger.isTraceEnabled()) { String filename = String.format("calibrate-lines-with-corners.png"); File file = new File(filename); filename = file.toString(); Highgui.imwrite(filename, traceMat); } // Sort them into the correct order // 1st-------2nd // | | // | | // | | // 3rd-------4th idealCorners = sortCorners(idealCorners); // build the MatofPoint2f final MatOfPoint2f sourceCorners = new MatOfPoint2f(); sourceCorners.alloc(4); for (int i = 0; i < 4; i++) { sourceCorners.put(i, 0, new double[] { idealCorners[i].x, idealCorners[i].y }); } return Optional.of(sourceCorners); }
From source file:com.shootoff.camera.autocalibration.AutoCalibrationManager.java
License:Open Source License
private void initializeWarpPerspective(final Mat frame, final MatOfPoint2f sourceCorners) { final MatOfPoint2f destCorners = new MatOfPoint2f(); destCorners.alloc(4); // 1st-------2nd // | |//from w w w.j ava 2s .c o m // | | // | | // 3rd-------4th destCorners.put(0, 0, new double[] { boundsRect.boundingRect().x, boundsRect.boundingRect().y }); destCorners.put(1, 0, new double[] { boundsRect.boundingRect().x + boundsRect.boundingRect().width, boundsRect.boundingRect().y }); destCorners.put(2, 0, new double[] { boundsRect.boundingRect().x, boundsRect.boundingRect().y + boundsRect.boundingRect().height }); destCorners.put(3, 0, new double[] { boundsRect.boundingRect().x + boundsRect.boundingRect().width, boundsRect.boundingRect().y + boundsRect.boundingRect().height }); if (logger.isDebugEnabled()) { logger.debug("initializeWarpPerspective {} {} {} {}", sourceCorners.get(0, 0), sourceCorners.get(1, 0), sourceCorners.get(2, 0), sourceCorners.get(3, 0)); logger.debug("initializeWarpPerspective {} {} {} {}", destCorners.get(0, 0), destCorners.get(1, 0), destCorners.get(2, 0), destCorners.get(3, 0)); } perspMat = Imgproc.getPerspectiveTransform(sourceCorners, destCorners); int width = boundsRect.boundingRect().width; int height = boundsRect.boundingRect().height; // Make them divisible by two for video recording purposes if ((width & 1) == 1) width++; if ((height & 1) == 1) height++; boundingBox = new BoundingBox(boundsRect.boundingRect().x, boundsRect.boundingRect().y, width, height); warpInitialized = true; if (logger.isTraceEnabled()) { Mat debugFrame = frame.clone(); Core.circle(debugFrame, new Point(sourceCorners.get(0, 0)[0], sourceCorners.get(0, 0)[1]), 1, new Scalar(255, 0, 255), -1); Core.circle(debugFrame, new Point(sourceCorners.get(1, 0)[0], sourceCorners.get(1, 0)[1]), 1, new Scalar(255, 0, 255), -1); Core.circle(debugFrame, new Point(sourceCorners.get(2, 0)[0], sourceCorners.get(2, 0)[1]), 1, new Scalar(255, 0, 255), -1); Core.circle(debugFrame, new Point(sourceCorners.get(3, 0)[0], sourceCorners.get(3, 0)[1]), 1, new Scalar(255, 0, 255), -1); Core.circle(debugFrame, new Point(destCorners.get(0, 0)[0], destCorners.get(0, 0)[1]), 1, new Scalar(255, 0, 0), -1); Core.circle(debugFrame, new Point(destCorners.get(1, 0)[0], destCorners.get(1, 0)[1]), 1, new Scalar(255, 0, 0), -1); Core.circle(debugFrame, new Point(destCorners.get(2, 0)[0], destCorners.get(2, 0)[1]), 1, new Scalar(255, 0, 0), -1); Core.circle(debugFrame, new Point(destCorners.get(3, 0)[0], destCorners.get(3, 0)[1]), 1, new Scalar(255, 0, 0), -1); Core.line(debugFrame, new Point(boundingBox.getMinX(), boundingBox.getMinY()), new Point(boundingBox.getMaxX(), boundingBox.getMinY()), new Scalar(0, 255, 0)); Core.line(debugFrame, new Point(boundingBox.getMinX(), boundingBox.getMinY()), new Point(boundingBox.getMinX(), boundingBox.getMaxY()), new Scalar(0, 255, 0)); Core.line(debugFrame, new Point(boundingBox.getMaxX(), boundingBox.getMaxY()), new Point(boundingBox.getMaxX(), boundingBox.getMinY()), new Scalar(0, 255, 0)); Core.line(debugFrame, new Point(boundingBox.getMaxX(), boundingBox.getMaxY()), new Point(boundingBox.getMinX(), boundingBox.getMaxY()), new Scalar(0, 255, 0)); String filename = String.format("calibrate-transformation.png"); File file = new File(filename); filename = file.toString(); Highgui.imwrite(filename, debugFrame); } }
From source file:com.shootoff.camera.autocalibration.AutoCalibrationManager.java
License:Open Source License
private MatOfPoint2f calcBoardRectFromCorners(MatOfPoint2f corners) { MatOfPoint2f result = new MatOfPoint2f(); result.alloc(4); Point topLeft = new Point(corners.get(0, 0)[0], corners.get(0, 0)[1]); Point topRight = new Point(corners.get(PATTERN_WIDTH - 1, 0)[0], corners.get(PATTERN_WIDTH - 1, 0)[1]); Point bottomRight = new Point(corners.get(PATTERN_WIDTH * PATTERN_HEIGHT - 1, 0)[0], corners.get(PATTERN_WIDTH * PATTERN_HEIGHT - 1, 0)[1]); Point bottomLeft = new Point(corners.get(PATTERN_WIDTH * (PATTERN_HEIGHT - 1), 0)[0], corners.get(PATTERN_WIDTH * (PATTERN_HEIGHT - 1), 0)[1]); result.put(0, 0, topLeft.x, topLeft.y, topRight.x, topRight.y, bottomRight.x, bottomRight.y, bottomLeft.x, bottomLeft.y);/*www. j a v a 2s.c om*/ return result; }