/** * Constructor records the calling instance of DisplayWindow and loads and trains the knn * classifier. * * @param instance The instace of DisplayWindow which instantiated this class */ public ImageProcessor(DisplayWindow instance) { this.callingInstance = instance; // Load and train knn classifier TrainingData td = new TrainingData(); knn = new CvKNearest(); knn.train(td.trainingData, td.trainingLabels); }
/** * 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); } } } }