public void processImage(Mat imageToProcess) { try { final Mat processedImage = imageToProcess.clone(); // red final Mat redUpper = new Mat(); final Mat redLower = new Mat(); Core.inRange(processedImage, new Scalar(170, 100, 20), new Scalar(180, 255, 255), redUpper); Core.inRange(processedImage, new Scalar(0, 100, 20), new Scalar(20, 255, 255), redLower); Core.bitwise_or(redLower, redUpper, processedImage); // refining the binary image Imgproc.erode(processedImage, processedImage, new Mat(), new Point(-1, -1), 1); Imgproc.dilate(processedImage, processedImage, new Mat(), new Point(-1, -1), 0); // create a clone for the processedImage to be used in finding contours final Mat clone = processedImage.clone(); Imgproc.cvtColor(processedImage, processedImage, Imgproc.COLOR_GRAY2RGB); // finds list of contours and draw the biggest on the processedImage final Scalar color1 = new Scalar(0, 0, 255); final Scalar color2 = new Scalar(255, 255, 0); final Scalar color3 = new Scalar(255, 255, 255); final List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); Imgproc.findContours( clone, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_NONE); final List<MatOfPoint> contour = new ArrayList<MatOfPoint>(1); double maxArea = 0.0; for (int index = 0; index < contours.size(); index++) { double area = Imgproc.contourArea(contours.get(index)); if (area > maxArea && area > 25 && Imgproc.boundingRect(contours.get(index)).y > 40) { maxArea = area; contour.add(0, contours.get(index)); } } // finds bounding Rectangle and draws contours Rect boundingRect = new Rect(); if (contour.size() > 0) { Imgproc.drawContours(processedImage, contour, -2, color1); boundingRect = Imgproc.boundingRect(contour.get(0)); final double x = boundingRect.x; final double y = boundingRect.y; final double width = boundingRect.width; final double height = boundingRect.height; Core.rectangle(processedImage, new Point(x, y), new Point(x + width, y + height), color3); } // finding bounding Circle and draws it final Point center = new Point(); final float[] radius = new float[1]; if (contour.size() > 0) { final MatOfPoint2f contour2f = new MatOfPoint2f(contour.get(0).toArray()); Imgproc.minEnclosingCircle(contour2f, center, radius); Core.circle(processedImage, center, (int) radius[0], color2); } final BallStruct redBallStruct = new BallStruct(boundingRect, center, (double) radius[0]); final BallTargeting ballTargeting = new BallTargeting(redBallStruct); synchronized (this) { distanceToRed = ballTargeting.getDistance(); angleToRedInDegrees = ballTargeting.getAngle() * (180 / Math.PI); this.processedImage = processedImage; } } catch (Exception e) { } }
/** * Extracts and classifies colour bands for each Resistor. Each ColourBand object is instantiated * and linked to their parent Resistor object. * * @param resistorList A list of Resistor objects from which to extract the colour bands * @param paintDebugInfo If ture, the extracted colour band ROIs are displayed on the GUI */ private void extractColourBandsAndClassify(List<Resistor> resistorList, boolean paintDebugInfo) { if (resistorList.size() > 0) { for (int r = 0; r < resistorList.size(); r++) { Mat resImg = resistorList.get(r).resistorMat; Mat imgHSV = new Mat(); Mat satImg = new Mat(); Mat hueImg = new Mat(); // convert to HSV Imgproc.cvtColor(resImg, imgHSV, Imgproc.COLOR_BGR2HSV); ArrayList<Mat> channels = new ArrayList<Mat>(); Core.split(imgHSV, channels); // extract channels satImg = channels.get(1); // saturation hueImg = channels.get(0); // hue // threshold saturation channel Mat threshedROISatBands = new Mat(); // ~130 sat thresh val Imgproc.threshold(satImg, threshedROISatBands, SAT_BAND_THRESH, 255, Imgproc.THRESH_BINARY); // threshold hue channel Mat threshedROIHueBands = new Mat(); // ~50 hue thresh val Imgproc.threshold(hueImg, threshedROIHueBands, HUE_BAND_THRESH, 255, Imgproc.THRESH_BINARY); // combine the thresholded binary images Mat bandROI = new Mat(); Core.bitwise_or(threshedROIHueBands, threshedROISatBands, bandROI); // find contours in binary ROI image ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>(); Mat hierarchy = new Mat(); Imgproc.findContours( bandROI, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0)); // remove any remaining noise by only keeping contours which area > threshold for (int i = 0; i < contours.size(); i++) { double area = Imgproc.contourArea(contours.get(i)); if (area < MIN_BAND_AREA) { contours.remove(i); i--; } } // create a ColourBand object for each detected band // storing its center, the contour and the bandROI for (int i = 0; i < contours.size(); i++) { MatOfPoint contour = contours.get(i); // extract this colour band and store in a Mat Rect boundingRect = Imgproc.boundingRect(contour); Mat mask = Mat.zeros(bandROI.size(), CvType.CV_8U); Imgproc.drawContours(mask, contours, i, new Scalar(255), Core.FILLED); Mat imageROI = new Mat(); resImg.copyTo(imageROI, mask); Mat colourBandROI = new Mat(imageROI, boundingRect); // instantiate new ColourBand object ColourBand cb = new ColourBand(findCenter(contour), contour, colourBandROI); // cluster the band colour cb.clusterBandColour(BAND_COLOUR_K_MEANS); // classify using the Lab colourspace as feature vector Mat sampleMat = new Mat(1, 3, CvType.CV_32FC1); // create a Mat contacting the clustered band colour sampleMat.put(0, 0, cb.clusteredColourLAB[0]); sampleMat.put(0, 1, cb.clusteredColourLAB[1]); sampleMat.put(0, 2, cb.clusteredColourLAB[2]); Mat classifiedValue = new Mat(1, 1, CvType.CV_32FC1); Mat neighborResponses = new Mat(); // dont actually use this Mat dists = new Mat(); // dont actually use this // classify knn.find_nearest(sampleMat, 3, classifiedValue, neighborResponses, dists); // cast classified value into Colour enum and store cb.classifiedColour = ColourEnumVals[(int) classifiedValue.get(0, 0)[0]]; // add the band to the parent resistor resistorList.get(r).bands.add(cb); } // paint the extracted band ROIs if (paintDebugInfo) { Mat finalBandROIMask = Mat.zeros(bandROI.size(), CvType.CV_8U); for (int i = 0; i < contours.size(); i++) { Scalar color = new Scalar(255, 255, 255); Imgproc.drawContours( finalBandROIMask, contours, i, color, -1, 4, hierarchy, 0, new Point()); } Mat colourROI = new Mat(); resImg.copyTo(colourROI, finalBandROIMask); paintResistorSubRegion(colourROI, r); } } } }
private Mat InRangeCircles(Mat src) { Core.inRange(src, new Scalar(148, 40, 50), new Scalar(179, 255, 255), img_bw1); Core.inRange(src, new Scalar(0, 50, 50), new Scalar(10, 255, 255), img_bw2); Core.bitwise_or(img_bw1, img_bw2, temp); return temp; }