/** * Computes a score (0-100) comparing the aspect ratio to the ideal aspect ratio for the target. * This method uses the equivalent rectangle sides to determine aspect ratio as it performs better * as the target gets skewed by moving to the left or right. The equivalent rectangle is the * rectangle with sides x and y where particle area= x*y and particle perimeter= 2x+2y * * @param image The image containing the particle to score, needed to perform additional * measurements * @param report The Particle Analysis Report for the particle, used for the width, height, and * particle number * @param outer Indicates whether the particle aspect ratio should be compared to the ratio for * the inner target or the outer * @return The aspect ratio score (0-100) */ public double scoreAspectRatio( BinaryImage image, ParticleAnalysisReport report, int particleNumber, boolean outer) throws NIVisionException { double rectLong, rectShort, aspectRatio, idealAspectRatio; rectLong = NIVision.MeasureParticle( image.image, particleNumber, false, MeasurementType.IMAQ_MT_EQUIVALENT_RECT_LONG_SIDE); rectShort = NIVision.MeasureParticle( image.image, particleNumber, false, MeasurementType.IMAQ_MT_EQUIVALENT_RECT_SHORT_SIDE); idealAspectRatio = outer ? (62 / 29) : (62 / 20); // Dimensions of goal opening + 4 inches on all 4 sides for reflective tape // Divide width by height to measure aspect ratio if (report.boundingRectWidth > report.boundingRectHeight) { // particle is wider than it is tall, divide long by short aspectRatio = 100 * (1 - Math.abs((1 - ((rectLong / rectShort) / idealAspectRatio)))); } else { // particle is taller than it is wide, divide short by long aspectRatio = 100 * (1 - Math.abs((1 - ((rectShort / rectLong) / idealAspectRatio)))); } return (Math.max(0, Math.min(aspectRatio, 100.0))); // force to be in range 0-100 }
/** * Computes the distance away from the target * * @param image The image containing the particle to score * @param report The Particle Analysis Report for the particle * @param particleNumber Particle number in the analysis * @param outer Indicates whether the particle aspect ratio should be compared to the ratio for * the inner target or the outer * @return Approximate distance from the target * @throws NIVisionException */ double computeDistance( BinaryImage image, ParticleAnalysisReport report, int particleNumber, boolean outer) throws NIVisionException { double rectShort, height; int targetHeight; angle = CommandBase.shooterPitch.getPosition(); rectShort = NIVision.MeasureParticle( image.image, particleNumber, false, MeasurementType.IMAQ_MT_EQUIVALENT_RECT_SHORT_SIDE); // using the smaller of the estimated rectangle short side and the bounding rectangle height // results in better performance // on skewed rectangles height = Math.min(report.boundingRectHeight, rectShort); targetHeight = outer ? 29 : 21; return X_IMAGE_RES * targetHeight / (height * 12 * 2 * Math.tan(angle * Math.PI / (180 * 2))); }
/** * Computes a score based on the match between a template profile and the particle profile in the * Y direction. This method uses the the row averages and the profile defined at the top of the * sample to look for the solid horizontal edges with a hollow center * * @param image The image to use, should be the image before the convex hull is performed * @param report The Particle Analysis Report for the particle * @return The Y Edge score (0-100) */ public double scoreYEdge(BinaryImage image, ParticleAnalysisReport report) throws NIVisionException { double total = 0; LinearAverages averages; Rect rect = new Rect( report.boundingRectTop, report.boundingRectLeft, report.boundingRectHeight, report.boundingRectWidth); averages = NIVision.getLinearAverages( image.image, LinearAverages.LinearAveragesMode.IMAQ_ROW_AVERAGES, rect); float rowAverages[] = averages.getRowAverages(); for (int i = 0; i < (rowAverages.length); i++) { if (yMin[(i * (YMINSIZE - 1) / rowAverages.length)] < rowAverages[i] && rowAverages[i] < yMax[i * (YMAXSIZE - 1) / rowAverages.length]) { total++; } } total = 100 * total / (rowAverages.length); return total; }