Permalink
Cannot retrieve contributors at this time
Fetching contributors…
| package Team4450.Robot9; | |
| import java.io.File; | |
| import java.io.FileWriter; | |
| import java.io.IOException; | |
| import java.util.ArrayList; | |
| import java.util.List; | |
| import java.util.Map; | |
| import java.util.stream.Collectors; | |
| import java.util.HashMap; | |
| import edu.wpi.first.wpilibj.vision.VisionPipeline; | |
| import org.opencv.core.*; | |
| import org.opencv.core.Core.*; | |
| import org.opencv.features2d.FeatureDetector; | |
| import org.opencv.imgcodecs.Imgcodecs; | |
| import org.opencv.imgproc.*; | |
| import org.opencv.objdetect.*; | |
| /** | |
| * GripPipeline class. | |
| * | |
| * <p>An OpenCV pipeline generated by GRIP. | |
| * | |
| * @author GRIP | |
| */ | |
| public class GripPipeline implements VisionPipeline { | |
| //Outputs | |
| private Mat hsvThresholdOutput = new Mat(); | |
| private Mat blurOutput = new Mat(); | |
| private ArrayList<MatOfPoint> findContoursOutput = new ArrayList<MatOfPoint>(); | |
| private ArrayList<MatOfPoint> filterContoursOutput = new ArrayList<MatOfPoint>(); | |
| static { | |
| System.loadLibrary(Core.NATIVE_LIBRARY_NAME); | |
| } | |
| /** | |
| * This is the primary method that runs the entire pipeline and updates the outputs. | |
| */ | |
| @Override public void process(Mat source0) { | |
| // Step HSV_Threshold0: | |
| Mat hsvThresholdInput = source0; | |
| double[] hsvThresholdHue = {12.695608530345735, 128.80546270376993}; | |
| double[] hsvThresholdSaturation = {0.0, 30.170651230795784}; | |
| double[] hsvThresholdValue = {220.14386739662223, 255.0}; | |
| hsvThreshold(hsvThresholdInput, hsvThresholdHue, hsvThresholdSaturation, hsvThresholdValue, hsvThresholdOutput); | |
| // Step Blur0: | |
| Mat blurInput = hsvThresholdOutput; | |
| BlurType blurType = BlurType.get("Box Blur"); | |
| double blurRadius = 1.2011996260634414; | |
| blur(blurInput, blurType, blurRadius, blurOutput); | |
| // Step Find_Contours0: | |
| Mat findContoursInput = blurOutput; | |
| boolean findContoursExternalOnly = false; | |
| findContours(findContoursInput, findContoursExternalOnly, findContoursOutput); | |
| // Step Filter_Contours0: | |
| ArrayList<MatOfPoint> filterContoursContours = findContoursOutput; | |
| double filterContoursMinArea = 750.0; | |
| double filterContoursMinPerimeter = 0.0; | |
| double filterContoursMinWidth = 50.0; | |
| double filterContoursMaxWidth = 75.0; | |
| double filterContoursMinHeight = 30.0; | |
| double filterContoursMaxHeight = 50.0; | |
| double[] filterContoursSolidity = {28.579395806507247, 54.842541944534375}; | |
| double filterContoursMaxVertices = 1000000.0; | |
| double filterContoursMinVertices = 0.0; | |
| double filterContoursMinRatio = 0.0; | |
| double filterContoursMaxRatio = 1000.0; | |
| filterContours(filterContoursContours, filterContoursMinArea, filterContoursMinPerimeter, filterContoursMinWidth, filterContoursMaxWidth, filterContoursMinHeight, filterContoursMaxHeight, filterContoursSolidity, filterContoursMaxVertices, filterContoursMinVertices, filterContoursMinRatio, filterContoursMaxRatio, filterContoursOutput); | |
| } | |
| /** | |
| * This method is a generated getter for the output of a HSV_Threshold. | |
| * @return Mat output from HSV_Threshold. | |
| */ | |
| public Mat hsvThresholdOutput() { | |
| return hsvThresholdOutput; | |
| } | |
| /** | |
| * This method is a generated getter for the output of a Blur. | |
| * @return Mat output from Blur. | |
| */ | |
| public Mat blurOutput() { | |
| return blurOutput; | |
| } | |
| /** | |
| * This method is a generated getter for the output of a Find_Contours. | |
| * @return ArrayList<MatOfPoint> output from Find_Contours. | |
| */ | |
| public ArrayList<MatOfPoint> findContoursOutput() { | |
| return findContoursOutput; | |
| } | |
| /** | |
| * This method is a generated getter for the output of a Filter_Contours. | |
| * @return ArrayList<MatOfPoint> output from Filter_Contours. | |
| */ | |
| public ArrayList<MatOfPoint> filterContoursOutput() { | |
| return filterContoursOutput; | |
| } | |
| /** | |
| * Segment an image based on hue, saturation, and value ranges. | |
| * | |
| * @param input The image on which to perform the HSL threshold. | |
| * @param hue The min and max hue | |
| * @param sat The min and max saturation | |
| * @param val The min and max value | |
| * @param output The image in which to store the output. | |
| */ | |
| private void hsvThreshold(Mat input, double[] hue, double[] sat, double[] val, | |
| Mat out) { | |
| Imgproc.cvtColor(input, out, Imgproc.COLOR_BGR2HSV); | |
| Core.inRange(out, new Scalar(hue[0], sat[0], val[0]), | |
| new Scalar(hue[1], sat[1], val[1]), out); | |
| } | |
| /** | |
| * An indication of which type of filter to use for a blur. | |
| * Choices are BOX, GAUSSIAN, MEDIAN, and BILATERAL | |
| */ | |
| enum BlurType{ | |
| BOX("Box Blur"), GAUSSIAN("Gaussian Blur"), MEDIAN("Median Filter"), | |
| BILATERAL("Bilateral Filter"); | |
| private final String label; | |
| BlurType(String label) { | |
| this.label = label; | |
| } | |
| public static BlurType get(String type) { | |
| if (BILATERAL.label.equals(type)) { | |
| return BILATERAL; | |
| } | |
| else if (GAUSSIAN.label.equals(type)) { | |
| return GAUSSIAN; | |
| } | |
| else if (MEDIAN.label.equals(type)) { | |
| return MEDIAN; | |
| } | |
| else { | |
| return BOX; | |
| } | |
| } | |
| @Override | |
| public String toString() { | |
| return this.label; | |
| } | |
| } | |
| /** | |
| * Softens an image using one of several filters. | |
| * @param input The image on which to perform the blur. | |
| * @param type The blurType to perform. | |
| * @param doubleRadius The radius for the blur. | |
| * @param output The image in which to store the output. | |
| */ | |
| private void blur(Mat input, BlurType type, double doubleRadius, | |
| Mat output) { | |
| int radius = (int)(doubleRadius + 0.5); | |
| int kernelSize; | |
| switch(type){ | |
| case BOX: | |
| kernelSize = 2 * radius + 1; | |
| Imgproc.blur(input, output, new Size(kernelSize, kernelSize)); | |
| break; | |
| case GAUSSIAN: | |
| kernelSize = 6 * radius + 1; | |
| Imgproc.GaussianBlur(input,output, new Size(kernelSize, kernelSize), radius); | |
| break; | |
| case MEDIAN: | |
| kernelSize = 2 * radius + 1; | |
| Imgproc.medianBlur(input, output, kernelSize); | |
| break; | |
| case BILATERAL: | |
| Imgproc.bilateralFilter(input, output, -1, radius, radius); | |
| break; | |
| } | |
| } | |
| /** | |
| * Sets the values of pixels in a binary image to their distance to the nearest black pixel. | |
| * @param input The image on which to perform the Distance Transform. | |
| * @param type The Transform. | |
| * @param maskSize the size of the mask. | |
| * @param output The image in which to store the output. | |
| */ | |
| private void findContours(Mat input, boolean externalOnly, | |
| List<MatOfPoint> contours) { | |
| Mat hierarchy = new Mat(); | |
| contours.clear(); | |
| int mode; | |
| if (externalOnly) { | |
| mode = Imgproc.RETR_EXTERNAL; | |
| } | |
| else { | |
| mode = Imgproc.RETR_LIST; | |
| } | |
| int method = Imgproc.CHAIN_APPROX_SIMPLE; | |
| Imgproc.findContours(input, contours, hierarchy, mode, method); | |
| } | |
| /** | |
| * Filters out contours that do not meet certain criteria. | |
| * @param inputContours is the input list of contours | |
| * @param output is the the output list of contours | |
| * @param minArea is the minimum area of a contour that will be kept | |
| * @param minPerimeter is the minimum perimeter of a contour that will be kept | |
| * @param minWidth minimum width of a contour | |
| * @param maxWidth maximum width | |
| * @param minHeight minimum height | |
| * @param maxHeight maximimum height | |
| * @param Solidity the minimum and maximum solidity of a contour | |
| * @param minVertexCount minimum vertex Count of the contours | |
| * @param maxVertexCount maximum vertex Count | |
| * @param minRatio minimum ratio of width to height | |
| * @param maxRatio maximum ratio of width to height | |
| */ | |
| private void filterContours(List<MatOfPoint> inputContours, double minArea, | |
| double minPerimeter, double minWidth, double maxWidth, double minHeight, double | |
| maxHeight, double[] solidity, double maxVertexCount, double minVertexCount, double | |
| minRatio, double maxRatio, List<MatOfPoint> output) { | |
| final MatOfInt hull = new MatOfInt(); | |
| output.clear(); | |
| //operation | |
| for (int i = 0; i < inputContours.size(); i++) { | |
| final MatOfPoint contour = inputContours.get(i); | |
| final Rect bb = Imgproc.boundingRect(contour); | |
| if (bb.width < minWidth || bb.width > maxWidth) continue; | |
| if (bb.height < minHeight || bb.height > maxHeight) continue; | |
| final double area = Imgproc.contourArea(contour); | |
| if (area < minArea) continue; | |
| if (Imgproc.arcLength(new MatOfPoint2f(contour.toArray()), true) < minPerimeter) continue; | |
| Imgproc.convexHull(contour, hull); | |
| MatOfPoint mopHull = new MatOfPoint(); | |
| mopHull.create((int) hull.size().height, 1, CvType.CV_32SC2); | |
| for (int j = 0; j < hull.size().height; j++) { | |
| int index = (int)hull.get(j, 0)[0]; | |
| double[] point = new double[] { contour.get(index, 0)[0], contour.get(index, 0)[1]}; | |
| mopHull.put(j, 0, point); | |
| } | |
| final double solid = 100 * area / Imgproc.contourArea(mopHull); | |
| if (solid < solidity[0] || solid > solidity[1]) continue; | |
| if (contour.rows() < minVertexCount || contour.rows() > maxVertexCount) continue; | |
| final double ratio = bb.width / (double)bb.height; | |
| if (ratio < minRatio || ratio > maxRatio) continue; | |
| output.add(contour); | |
| } | |
| } | |
| } | |