@Override
  public void apply(Mat src, Mat dst) {
    Core.split(src, mChannels);

    final Mat r = mChannels.get(0);
    final Mat g = mChannels.get(1);
    final Mat b = mChannels.get(2);

    Core.min(b, r, b);
    Core.min(b, g, b);

    Core.merge(mChannels, dst);
  }
  /**
   * Generates a mask of all resistors present in the given Mat. Also displays this mask in the
   * Bottom Left frame of the GUI.
   *
   * @param imgCap The Mat image to generate the mask for
   * @param type The threshold operation type
   * @return The mask as a Mat
   */
  private Mat generateResistorMask(Mat imgCap, int type) {
    Mat imgHSV = new Mat();
    Mat satImg = new Mat();

    // convert the input image from BGR to HSV
    Imgproc.cvtColor(imgCap, imgHSV, Imgproc.COLOR_BGR2HSV);

    ArrayList<Mat> channels = new ArrayList<Mat>();
    Core.split(imgHSV, channels);
    // extract the saturation channel
    satImg = channels.get(1);

    // remove the background and the resistor leads (combined with previous blurring)
    // thresh ~86
    Imgproc.threshold(satImg, satImg, RESISTOR_MASK_THRESHOLD, 255, type);

    paintBL(satImg);

    return satImg;
  }
  public static Mat Histogram(Mat im) {

    Mat img = im;

    Mat equ = new Mat();
    img.copyTo(equ);
    // Imgproc.blur(equ, equ, new Size(3, 3));

    Imgproc.cvtColor(equ, equ, Imgproc.COLOR_BGR2YCrCb);
    List<Mat> channels = new ArrayList<Mat>();
    Core.split(equ, channels);
    Imgproc.equalizeHist(channels.get(0), channels.get(0));
    Core.merge(channels, equ);
    Imgproc.cvtColor(equ, equ, Imgproc.COLOR_YCrCb2BGR);

    Mat gray = new Mat();
    Imgproc.cvtColor(equ, gray, Imgproc.COLOR_BGR2GRAY);
    Mat grayOrig = new Mat();
    Imgproc.cvtColor(img, grayOrig, Imgproc.COLOR_BGR2GRAY);
    System.out.println("Histogram work ///");
    return grayOrig;
  }
  /**
   * @param inputImg
   * @param minValue
   * @param maxValue
   * @return Mat
   */
  public static Mat thresholding(Mat inputImg, Integer minValue, Integer maxValue) {

    Mat frame = inputImg;
    // яскравість
    // frame.convertTo(frame , -1, 10d * 33 / 100, 0);
    // Imgproc.medianBlur(frame,frame, 17);

    // Core.bitwise_not(frame,frame );

    // Mat frame = new Mat(image.rows(), image.cols(), image.type());

    // frame.convertTo(frame, -1, 10d * 20 / 100, 0);

    Mat hsvImg = new Mat();
    List<Mat> hsvPlanes = new ArrayList<>();
    Mat thresholdImg = new Mat();

    int thresh_type = Imgproc.THRESH_BINARY_INV;

    // if (this.inverse.isSelected())
    // thresh_type = Imgproc.THRESH_BINARY;

    // threshold the image with the average hue value
    // System.out.println("size " +frame.size());
    hsvImg.create(frame.size(), CvType.CV_8U);
    // Imgproc.cvtColor(frame, hsvImg, Imgproc.COLOR_BGR2HSV);
    Core.split(hsvImg, hsvPlanes);

    // get the average hue value of the image
    // double threshValue = PreProcessingOperation.getHistAverage(hsvImg, hsvPlanes.get(0));
    // System.out.println(threshValue);
    /*
    if(threshValue > 40){
        maxValue = 160;
    }else{
        maxValue = 40;
    }*/

    //        Imgproc.threshold(hsvPlanes.get(1), thresholdImg, minValue , maxValue , thresh_type);

    Imgproc.blur(thresholdImg, thresholdImg, new Size(27, 27));

    // dilate to fill gaps, erode to smooth edges
    Imgproc.dilate(thresholdImg, thresholdImg, new Mat(), new Point(-1, -1), 1);
    Imgproc.erode(thresholdImg, thresholdImg, new Mat(), new Point(-1, -1), 1);

    Imgproc.threshold(thresholdImg, thresholdImg, minValue, maxValue, Imgproc.THRESH_BINARY);

    // create the new image
    Mat foreground = new Mat(frame.size(), CvType.CV_8UC3, new Scalar(255, 255, 255));
    Core.bitwise_not(thresholdImg, foreground);

    frame.copyTo(foreground, thresholdImg);

    ///////////////////////////////////////////////////////////////////////////////////////
    ///
    ////

    return foreground;
    /*Mat hsvImg = new Mat();
    List<Mat> hsvPlanes = new ArrayList<>();
    Mat thresholdImg = new Mat();
    int thresh_type = Imgproc.THRESH_BINARY_INV;
    // threshold the image with the average hue value
    hsvImg.create(inputImg.size(), CvType.CV_8U);
    Imgproc.cvtColor(inputImg, hsvImg, Imgproc.COLOR_BGR2HSV);
    Core.split(hsvImg, hsvPlanes);
    // get the average hue value of the image
    double threshValue = PreProcessingOperation.getHistAverage(hsvImg, hsvPlanes.get(0));
    Imgproc.threshold(hsvPlanes.get(0), thresholdImg, minValue,
            maxValue, thresh_type);
    Imgproc.blur(thresholdImg, thresholdImg, new Size(3, 3));
    // dilate to fill gaps, erode to smooth edges
    Imgproc.dilate(thresholdImg, thresholdImg, new Mat(), new Point(-1, -1), 3);
    Imgproc.erode(thresholdImg, thresholdImg, new Mat(), new Point(-1, -1), 1);
    Imgproc.threshold(thresholdImg, thresholdImg, minValue,
            maxValue, Imgproc.THRESH_BINARY);
    // create the new image
    Mat foreground = new Mat(inputImg.size(), CvType.CV_8UC3, new Scalar(255, 255, 255));
    inputImg.copyTo(foreground, thresholdImg);
    Core.bitwise_not(foreground,foreground);
    return foreground;*/
  }
  /**
   * @param inputImg
   * @return Mat
   */
  public static Mat kmeans(Mat inputImg) {

    Mat rgba = inputImg;
    Mat tempMat = inputImg;
    rgba = new Mat(inputImg.cols(), inputImg.rows(), CvType.CV_8UC3);
    inputImg.copyTo(rgba);

    List<Mat> hsv_planes_temp = new ArrayList<Mat>(3);
    Core.split(tempMat, hsv_planes_temp);

    double threshValue1 = PreProcessingOperation.getHistAverage(inputImg, hsv_planes_temp.get(0));
    sample.util.Estimate.setFirstHistAverageValue(threshValue1);
    System.out.println("Defore eqau " + threshValue1);

    System.out.println(
        Estimate.getBlueAverage() + " ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;");

    if (threshValue1 > 140) {
      if (Estimate.getBlueAverage() > 110) {
        rgba.convertTo(rgba, -1, 10d * 31 / 100, 0);
        System.out.println("11");
      } else {
        rgba.convertTo(rgba, -1, 10d * 40 / 100, 0);
        System.out.println("12");
      }
    } else if (threshValue1 > 135) {
      rgba.convertTo(rgba, -1, 10d * 32 / 100, 0);
      System.out.println("21");
    } else if (threshValue1 > 125) {
      if (Estimate.getBlueAverage() > 110) {
        rgba.convertTo(rgba, -1, 10d * 30 / 100, 0);
        rgba = PreProcessing.Dilate(rgba, 5);
        System.out.println("31");
      } else {
        rgba.convertTo(rgba, -1, 10d * 37 / 100, 0);
        System.out.println("32");
      }
    } else if (threshValue1 > 120) {
      rgba.convertTo(rgba, -1, 10d * 35 / 100, 0);
      System.out.println("41");
    } else if (threshValue1 > 110) {
      if (Estimate.getBlueAverage() > 110) {
        rgba.convertTo(rgba, -1, 10d * 35 / 100, 0);
        rgba = PreProcessing.Dilate(rgba, 5);
        System.out.println("51");
      }
    } else if (threshValue1 > 100) {
      if (Estimate.getBlueAverage() > 107) {
        rgba.convertTo(rgba, -1, 10d * 24 / 100, 0);
        rgba = PreProcessing.Dilate(rgba, 5);
        System.out.println("61");
      } else if (Estimate.getBlueAverage() > 90) {
        rgba.convertTo(rgba, -1, 10d * 30 / 100, 0);
        rgba = PreProcessing.Dilate(rgba, 5);
        System.out.println("62");
      }
    } else if (threshValue1 > 50) {

      if (Estimate.getBlueAverage() > 160) {
        rgba.convertTo(rgba, -1, 10d * 30 / 100, 0);
        rgba = PreProcessing.Dilate(rgba, 3);
        System.out.println("81");
      } else if (Estimate.getBlueAverage() > 160) {
        rgba.convertTo(rgba, -1, 10d * 27 / 100, 0);
        rgba = PreProcessing.Dilate(rgba, 9);
        System.out.println("82");
      } else if (Estimate.getBlueAverage() > 130) {
        rgba.convertTo(rgba, -1, 10d * 30 / 100, 0);
        rgba = PreProcessing.Dilate(rgba, 9);
        System.out.println("83");
      } else if (Estimate.getBlueAverage() > 70) {
        rgba.convertTo(rgba, -1, 10d * 29 / 100, 0);
        rgba = PreProcessing.Dilate(rgba, 9);
        System.out.println("84");
      }
    } else if (threshValue1 > 30) {
      if (Estimate.getBlueAverage() > 190) {
        rgba.convertTo(rgba, -1, 10d * 25 / 100, 0);
        System.out.println("91");
      } else if (Estimate.getBlueAverage() > 160) {
        rgba.convertTo(rgba, -1, 10d * 35 / 100, 0);
        System.out.println("92");
      }
    } else {
      if (Estimate.getBlueAverage() > 240) {
        rgba.convertTo(rgba, -1, 10d * 24 / 100, 0);
        System.out.println("7");
      } else {
        rgba.convertTo(rgba, -1, 10d * 17 / 100, 0);
        System.out.println("7");
      }
    }
    tempMat.release();

    Mat mHSV = new Mat();
    Imgproc.cvtColor(rgba, mHSV, Imgproc.COLOR_RGBA2RGB, 3);
    Imgproc.cvtColor(rgba, mHSV, Imgproc.COLOR_RGB2HSV, 3);
    List<Mat> hsv_planes = new ArrayList<Mat>(3);
    Core.split(mHSV, hsv_planes);

    Mat channel = hsv_planes.get(0);
    channel = Mat.zeros(mHSV.rows(), mHSV.cols(), CvType.CV_8UC1);
    hsv_planes.set(2, channel);
    Core.merge(hsv_planes, mHSV);

    mHSV.convertTo(mHSV, CvType.CV_8UC1);
    mHSV = Histogram(mHSV);

    /*
    Mat clusteredHSV = new Mat();
    mHSV.convertTo(mHSV, CvType.CV_32FC3);
    TermCriteria criteria = new TermCriteria(TermCriteria.EPS + TermCriteria.MAX_ITER,100,0.1);
    Core.kmeans(mHSV, 1, clusteredHSV, criteria, 20, Core.KMEANS_PP_CENTERS);
    Mat hsvImg = new Mat();
    List<Mat> hsvPlanes = new ArrayList<>();
    Mat thresholdImg = new Mat();
    int thresh_type = Imgproc.THRESH_BINARY_INV;
    hsvImg.create(mHSV.size(), CvType.CV_8U);
    Imgproc.cvtColor(mHSV, hsvImg, Imgproc.COLOR_BGR2HSV);
    Core.split(hsvImg, hsvPlanes);
    Imgproc.threshold(hsvPlanes.get(1), thresholdImg, 0 , 200 , thresh_type);
    double threshValue = PreProcessingOperation.getHistAverage(hsvImg, hsvPlanes.get(0));
    Estimate.setSecondHistAverageValue(threshValue);
    System.out.println("After equa " + Estimate.getSecondHistAverageValue());*/

    Imgproc.threshold(mHSV, mHSV, 0, 150, Imgproc.THRESH_BINARY_INV);
    // mHSV.convertTo(mHSV, CvType.CV_8UC1);
    return mHSV;
  }
  /**
   * 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);
        }
      }
    }
  }
示例#7
0
  /**
   * Identifies the color in the frame
   *
   * @param in the Mat image in the region of interest
   * @return the color
   */
  public char identifyColor(Mat in) {
    // Mat blue = new Mat(in.rows(), in.cols(), CvType.CV_8UC1);
    // Mat green = new Mat(in.rows(), in.cols(), CvType.CV_8UC1);
    // Mat red = new Mat(in.rows(), in.cols(), CvType.CV_8UC1);

    // split the channels of the image
    Mat blue = new Mat(); // default is CV_8UC3
    Mat green = new Mat();
    Mat red = new Mat();
    List<Mat> channels = new ArrayList<Mat>(3);
    Core.split(in, channels);
    blue = channels.get(0); // makes all 3 CV_8UC1
    green = channels.get(1);
    red = channels.get(2);
    // System.out.println(blue.toString());

    // add the intensities
    Mat intensity = new Mat(in.rows(), in.cols(), CvType.CV_32F);
    // Mat mask = new Mat();
    Core.add(blue, green, intensity); // , mask, CvType.CV_32F);
    Core.add(intensity, red, intensity); // , mask, CvType.CV_32F);

    // not sure if correct from here to ...

    Mat inten = new Mat();
    Core.divide(intensity, Scalar.all(3.0), inten);
    // System.out.println(intensity.toString());
    // Core.divide(3.0, intensity, inten);
    // if intensity = intensity / 3.0; means element-wise division
    // use intensity.muls(Mat m)
    // so make new Mat m of same size that has each element of 1/3

    /*
    * or
    * About per-element division you can use Core.divide()

    Core.divide(A,Scalar.all(d), B);

    It's equivalent to B=A/d
    */

    // find normalized values
    Mat bnorm = new Mat();
    Mat gnorm = new Mat();
    Mat rnorm = new Mat();
    // blue.convertTo(blue, CvType.CV_32F);
    // green.convertTo(green, CvType.CV_32F);
    // red.convertTo(red, CvType.CV_32F);

    Core.divide(blue, inten, bnorm);
    Core.divide(green, inten, gnorm);
    Core.divide(red, inten, rnorm);

    // find average norm values
    Scalar val = new Scalar(0);
    val = Core.mean(bnorm);
    String value[] = val.toString().split(",");
    String s = value[0].substring(1);
    double bavg = Double.parseDouble(s);
    val = Core.mean(gnorm);
    String value1[] = val.toString().split(",");
    String s1 = value1[0].substring(1);
    double gavg = Double.parseDouble(s1);
    val = Core.mean(rnorm);
    String value2[] = val.toString().split(",");
    String s2 = value2[0].substring(1);
    double ravg = Double.parseDouble(s2);

    // ... here

    // original values
    /*
    // define the reference color values
    //double RED[] = {0.4, 0.5, 1.8};
    //double GREEN[] = {1.0, 1.2, 1.0};
    double BLUE[] = {1.75, 1.0, 0.5};
    //double YELLOW[] = {0.82, 1.7, 1.7};
    double ORANGE[] = {0.2, 1.0, 2.0};
    double WHITE[] = {2.0, 1.7, 1.7};
    //double BLACK[] = {0.0, 0.3, 0.3};
    */

    // define the reference color values
    // double RED[] = {0.4, 0.5, 1.8};
    // double GREEN[] = {1.0, 1.2, 1.0};
    double BLUE[] = {1.75, 1.0, 0.5};
    // double YELLOW[] = {0.82, 1.7, 1.7};
    double ORANGE[] = {0.2, 1.0, 2.0};
    double WHITE[] = {2.0, 1.7, 1.7};
    // double BLACK[] = {0.0, 0.3, 0.3};

    // compute the square error relative to the reference color values
    // double minError = 3.0;
    double minError = 2.0;
    double errorSqr;
    char bestFit = 'x';

    // test++;
    // System.out.print("\n\n" + test + "\n\n");

    // check BLUE fitness
    errorSqr = normSqr(BLUE[0], BLUE[1], BLUE[2], bavg, gavg, ravg);
    System.out.println("Blue: " + errorSqr);
    if (errorSqr < minError) {
      minError = errorSqr;
      bestFit = COLOR_BLUE;
    }
    // check ORANGE fitness
    errorSqr = normSqr(ORANGE[0], ORANGE[1], ORANGE[2], bavg, gavg, ravg);
    System.out.println("Orange: " + errorSqr);
    if (errorSqr < minError) {
      minError = errorSqr;
      bestFit = COLOR_ORANGE;
    }
    // check WHITE fitness
    errorSqr = normSqr(WHITE[0], WHITE[1], WHITE[2], bavg, gavg, ravg);
    System.out.println("White: " + errorSqr);
    if (errorSqr < minError) {
      minError = errorSqr;
      bestFit = COLOR_WHITE;
    }
    // check BLACK fitness
    /*errorSqr = normSqr(BLACK[0], BLACK[1], BLACK[2], bavg, gavg, ravg);
    System.out.println("Black: " + errorSqr);
    if(errorSqr < minError)
    {
    	minError = errorSqr;
    	bestFit = COLOR_BLACK;
    }*/

    // return the best fit color label
    return bestFit;
  }