Example usage for org.opencv.imgproc Imgproc fitEllipse

List of usage examples for org.opencv.imgproc Imgproc fitEllipse

Introduction

In this page you can find the example usage for org.opencv.imgproc Imgproc fitEllipse.

Prototype

public static RotatedRect fitEllipse(MatOfPoint2f points) 

Source Link

Usage

From source file:OctoEye.java

License:Open Source License

private void detectPupil() {
    // min and max pupil radius
    int r_min = 2;
    int r_max = 45;

    // min and max pupil diameter
    int d_min = 2 * r_min;
    int d_max = 2 * r_max;

    // min and max pupil area
    double area;//from  www  . j  a  v a  2  s.  co  m
    double a_min = Math.PI * r_min * r_min;
    double a_max = Math.PI * r_max * r_max;

    // histogram stuff
    List<Mat> images;
    MatOfInt channels;
    Mat mask;
    Mat hist;
    MatOfInt mHistSize;
    MatOfFloat mRanges;

    // contour and circle stuff
    Rect rect = null;
    Rect rectMin;
    Rect rectMax;
    List<MatOfPoint> contours;
    MatOfPoint3 circles;

    // pupil center
    Point p;

    // ellipse test points
    Point v;
    Point r;
    Point s;

    // rect points
    Point tl;
    Point br;

    // pupil edge detection
    Vector<Point> pointsTest;
    Vector<Point> pointsEllipse;
    Vector<Point> pointsRemoved;

    // temporary variables
    double distance;
    double rad;
    double length;
    int x;
    int y;
    int tmp;
    byte buff[];

    // -------------------------------------------------------------------------------------------------------------
    // step 1
    // blur the image to reduce noise

    Imgproc.medianBlur(src, tmp1, 25);

    // -------------------------------------------------------------------------------------------------------------
    // step 2
    // locate the pupil with feature detection and compute a histogram for each,
    // the best feature will be used as rough pupil location (rectMin)

    int score = 0;
    int winner = 0;

    // feature detection
    MatOfKeyPoint matOfKeyPoints = new MatOfKeyPoint();
    FeatureDetector blobDetector = FeatureDetector.create(FeatureDetector.MSER); // Maximal Stable Extremal Regions
    blobDetector.detect(tmp1, matOfKeyPoints);
    List<KeyPoint> keyPoints = matOfKeyPoints.toList();

    // histogram calculation
    for (int i = 0; i < keyPoints.size(); i++) {
        x = (int) keyPoints.get(i).pt.x;
        y = (int) keyPoints.get(i).pt.y;
        tl = new Point(x - 5 >= 0 ? x - 5 : 0, y - 5 >= 0 ? y - 5 : 0);
        br = new Point(x + 5 < WIDTH ? x + 5 : WIDTH - 1, y + 5 < HEIGHT ? y + 5 : HEIGHT - 1);

        images = new ArrayList<Mat>();
        images.add(tmp1.submat(new Rect(tl, br)));
        channels = new MatOfInt(0);
        mask = new Mat();
        hist = new Mat();
        mHistSize = new MatOfInt(256);
        mRanges = new MatOfFloat(0f, 256f);
        Imgproc.calcHist(images, channels, mask, hist, mHistSize, mRanges);

        tmp = 0;
        for (int j = 0; j < 256 / 3; j++) {
            tmp += (256 / 3 - j) * (int) hist.get(j, 0)[0];
        }
        if (tmp >= score) {
            score = tmp;
            winner = i;
            rect = new Rect(tl, br);
        }

        if (debug) {
            // show features (orange)
            Core.circle(dbg, new Point(x, y), 3, ORANGE);
        }
    }
    if (rect == null) {
        return;
    }
    rectMin = rect.clone();

    if (debug) {
        // show rectMin (red)
        Core.rectangle(dbg, rectMin.tl(), rect.br(), RED, 1);
    }

    // -------------------------------------------------------------------------------------------------------------
    // step 3
    // compute a rectMax (blue) which is larger than the pupil

    int margin = 32;

    rect.x = rect.x - margin;
    rect.y = rect.y - margin;
    rect.width = rect.width + 2 * margin;
    rect.height = rect.height + 2 * margin;

    rectMax = rect.clone();

    if (debug) {
        // show features (orange)
        Core.rectangle(dbg, rectMax.tl(), rectMax.br(), BLUE);
    }

    // -------------------------------------------------------------------------------------------------------------
    // step 4
    // blur the image again

    Imgproc.medianBlur(src, tmp1, 7);
    Imgproc.medianBlur(tmp1, tmp1, 3);
    Imgproc.medianBlur(tmp1, tmp1, 3);
    Imgproc.medianBlur(tmp1, tmp1, 3);

    // -------------------------------------------------------------------------------------------------------------
    // step 5
    // detect edges

    Imgproc.Canny(tmp1, tmp2, 40, 50);

    // -------------------------------------------------------------------------------------------------------------
    // step 6
    // from pupil center to maxRect borders, find all edge points, compute a first ellipse

    p = new Point(rectMin.x + rectMin.width / 2, rectMin.y + rectMin.height / 2);
    pointsTest = new Vector<Point>();
    pointsEllipse = new Vector<Point>();
    pointsRemoved = new Vector<Point>();
    buff = new byte[tmp2.rows() * tmp2.cols()];
    tmp2.get(0, 0, buff);

    length = Math.min(p.x - rectMax.x - 3, p.y - rectMax.y - 3);
    length = Math.sqrt(2 * Math.pow(length, 2));
    Point z = new Point(p.x, p.y - length);
    for (int i = 0; i < 360; i += 15) {
        rad = Math.toRadians(i);
        x = (int) (p.x + Math.cos(rad) * (z.x - p.x) - Math.sin(rad) * (z.y - p.y));
        y = (int) (p.y + Math.sin(rad) * (z.x - p.x) - Math.cos(rad) * (z.y - p.y));
        pointsTest.add(new Point(x, y));
    }

    if (debug) {
        for (int i = 0; i < pointsTest.size(); i++) {
            Core.line(dbg, p, pointsTest.get(i), GRAY, 1);
            Core.rectangle(dbg, rectMin.tl(), rectMin.br(), GREEN, 1);
            Core.rectangle(dbg, rectMax.tl(), rectMax.br(), BLUE, 1);
        }
        Core.rectangle(dbg, rectMin.tl(), rectMin.br(), BLACK, -1);
        Core.rectangle(dbg, rectMin.tl(), rectMin.br(), RED, 1);
        Core.rectangle(dbg, rectMax.tl(), rectMax.br(), BLUE);
    }

    // p: Ursprung ("Mittelpunkt" der Ellipse)
    // v: Zielpunkt (Testpunkt)
    // r: Richtungsvektor PV
    for (int i = 0; i < pointsTest.size(); i++) {
        v = new Point(pointsTest.get(i).x, pointsTest.get(i).y);
        r = new Point(v.x - p.x, v.y - p.y);
        length = Math.sqrt(Math.pow(p.x - v.x, 2) + Math.pow(p.y - v.y, 2));
        boolean found = false;
        for (int j = 0; j < Math.round(length); j++) {
            s = new Point(Math.rint(p.x + (double) j / length * r.x),
                    Math.rint(p.y + (double) j / length * r.y));
            s.x = Math.max(1, Math.min(s.x, WIDTH - 2));
            s.y = Math.max(1, Math.min(s.y, HEIGHT - 2));
            tl = new Point(s.x - 1, s.y - 1);
            br = new Point(s.x + 1, s.y + 1);
            buff = new byte[3 * 3];
            rect = new Rect(tl, br);
            try {
                (tmp2.submat(rect)).get(0, 0, buff);
                for (int k = 0; k < 3 * 3; k++) {
                    if (Math.abs(buff[k]) == 1) {
                        pointsEllipse.add(s);
                        found = true;
                        break;
                    }
                }
            } catch (Exception e) {
                break;
            }
            if (found) {
                break;
            }
        }
    }

    double e_min = Double.POSITIVE_INFINITY;
    double e_max = 0;
    double e_med = 0;
    for (int i = 0; i < pointsEllipse.size(); i++) {
        v = pointsEllipse.get(i);
        length = Math.sqrt(Math.pow(p.x - v.x, 2) + Math.pow(p.y - v.y, 2));
        e_min = (length < e_min) ? length : e_min;
        e_max = (length > e_max) ? length : e_max;
        e_med = e_med + length;
    }
    e_med = e_med / pointsEllipse.size();
    if (pointsEllipse.size() >= 5) {
        Point[] points1 = new Point[pointsEllipse.size()];
        for (int i = 0; i < pointsEllipse.size(); i++) {
            points1[i] = pointsEllipse.get(i);
        }
        MatOfPoint2f points2 = new MatOfPoint2f();
        points2.fromArray(points1);
        pupil = Imgproc.fitEllipse(points2);
    }
    if (pupil.center.x == 0 && pupil.center.y == 0) {
        // something went wrong, return null
        reset();
        return;
    }

    if (debug) {
        Core.ellipse(dbg, pupil, PURPLE, 2);
    }

    // -------------------------------------------------------------------------------------------------------------
    // step 7
    // remove some outlier points and compute the ellipse again

    try {
        for (int i = 1; i <= 4; i++) {
            distance = 0;
            int remove = 0;
            for (int j = pointsEllipse.size() - 1; j >= 0; j--) {
                v = pointsEllipse.get(j);
                length = Math.sqrt(Math.pow(v.x - pupil.center.x, 2) + Math.pow(v.y - pupil.center.y, 2));
                if (length > distance) {
                    distance = length;
                    remove = j;
                }
            }
            v = pointsEllipse.get(remove);
            pointsEllipse.removeElementAt(remove);
            pointsRemoved.add(v);
        }
    } catch (Exception e) {
        // something went wrong, return null
        reset();
        return;
    }
    if (pointsEllipse.size() >= 5) {
        Point[] points1 = new Point[pointsEllipse.size()];
        for (int i = 0; i < pointsEllipse.size(); i++) {
            points1[i] = pointsEllipse.get(i);
        }
        MatOfPoint2f points2 = new MatOfPoint2f();
        points2.fromArray(points1);
        pupil = Imgproc.fitEllipse(points2);

        Point[] vertices = new Point[4];
        pupil.points(vertices);
        double d1 = Math
                .sqrt(Math.pow(vertices[1].x - vertices[0].x, 2) + Math.pow(vertices[1].y - vertices[0].y, 2));
        double d2 = Math
                .sqrt(Math.pow(vertices[2].x - vertices[1].x, 2) + Math.pow(vertices[2].y - vertices[1].y, 2));

        if (d1 >= d2) {
            pupilMajorAxis = (int) (d1 / 2);
            pupilMinorAxis = (int) (d2 / 2);
            axisA = new Point(vertices[1].x + (vertices[2].x - vertices[1].x) / 2,
                    vertices[1].y + (vertices[2].y - vertices[1].y) / 2);
            axisB = new Point(vertices[0].x + (vertices[1].x - vertices[0].x) / 2,
                    vertices[0].y + (vertices[1].y - vertices[0].y) / 2);
        } else {
            pupilMajorAxis = (int) (d2 / 2);
            pupilMinorAxis = (int) (d1 / 2);
            axisB = new Point(vertices[1].x + (vertices[2].x - vertices[1].x) / 2,
                    vertices[1].y + (vertices[2].y - vertices[1].y) / 2);
            axisA = new Point(vertices[0].x + (vertices[1].x - vertices[0].x) / 2,
                    vertices[0].y + (vertices[1].y - vertices[0].y) / 2);
        }
    }

    double ratio = (double) pupilMinorAxis / (double) pupilMajorAxis;
    if (ratio < 0.75 || 2 * pupilMinorAxis <= d_min || 2 * pupilMajorAxis >= d_max) {
        // something went wrong, return null
        reset();
        return;
    }

    // pupil found
    if (debug) {
        Core.ellipse(dbg, pupil, GREEN, 2);
        Core.line(dbg, pupil.center, axisA, RED, 2);
        Core.line(dbg, pupil.center, axisB, BLUE, 2);
        Core.circle(dbg, pupil.center, 1, GREEN, 0);

        x = 5;
        y = 5;
        Core.rectangle(dbg, new Point(x, y), new Point(x + 80 + 4, y + 10), BLACK, -1);
        Core.rectangle(dbg, new Point(x + 2, y + 2), new Point(x + 2 + pupilMajorAxis, y + 4), RED, -1);
        Core.rectangle(dbg, new Point(x + 2, y + 6), new Point(x + 2 + pupilMinorAxis, y + 8), BLUE, -1);

        for (int i = pointsEllipse.size() - 1; i >= 0; i--) {
            Core.circle(dbg, pointsEllipse.get(i), 2, ORANGE, -1);
        }
        for (int i = pointsRemoved.size() - 1; i >= 0; i--) {
            Core.circle(dbg, pointsRemoved.get(i), 2, PURPLE, -1);
        }
    }
    Core.ellipse(dst, pupil, GREEN, 2);
    Core.circle(dst, pupil.center, 1, GREEN, 0);
}

From source file:OCV_FitEllipse.java

License:Open Source License

@Override
public void run(ImageProcessor ip) {
    byte[] byteArray = (byte[]) ip.getPixels();
    int w = ip.getWidth();
    int h = ip.getHeight();
    int num_slice = ip.getSliceNumber();

    ArrayList<Point> lstPt = new ArrayList<Point>();
    MatOfPoint2f pts = new MatOfPoint2f();

    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            if (byteArray[x + w * y] != 0) {
                lstPt.add(new Point((double) x, (double) y));
            }/* www.j  a  v a  2 s. c  om*/
        }
    }

    if (lstPt.isEmpty()) {
        return;
    }

    pts.fromList(lstPt);
    RotatedRect rect = Imgproc.fitEllipse(pts);
    showData(rect, num_slice);
}

From source file:dfmDrone.examples.fitEllipseExample.java

private static Mat findAndDrawEllipse(Mat sourceImg) {
    Mat grayScaleImg = new Mat();
    Mat hsvImg = new Mat();
    Imgproc.cvtColor(sourceImg, hsvImg, Imgproc.COLOR_BGR2HSV);
    Mat lower_hue_range = new Mat();
    Mat upper_hue_range = new Mat();
    Core.inRange(hsvImg, new Scalar(0, 100, 45), new Scalar(15, 255, 255), lower_hue_range);
    Core.inRange(hsvImg, new Scalar(160, 100, 45), new Scalar(180, 255, 255), upper_hue_range);
    Mat red_hue_image = new Mat();
    Core.addWeighted(lower_hue_range, 1.0, upper_hue_range, 1.0, 0, red_hue_image);
    Mat dilateElement = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(24, 24));
    Mat erodeElement = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(10, 10));

    Imgproc.blur(red_hue_image, red_hue_image, new Size(11, 11));
    // init//  w w  w  .  jav a2s  .  c o m
    List<MatOfPoint> contours = new ArrayList<>();
    Mat hierarchy = new Mat();

    // find contours
    Imgproc.findContours(red_hue_image, contours, hierarchy, Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_SIMPLE);
    System.out.println("After findcontours");
    // if any contour exist...
    if (hierarchy.size().height > 0 && hierarchy.size().width > 0) {
        // for each contour, display it in blue
        for (int idx = 0; idx >= 0; idx = (int) hierarchy.get(0, idx)[0]) {
            System.out.println(idx);
            //   Imgproc.drawContours(frame, contours, idx, new Scalar(250, 0, 0), 3);

        }
    }
    MatOfPoint2f approxCurve = new MatOfPoint2f();

    //For each contour found
    MatOfPoint2f contour2f = null;
    RotatedRect rotatedrect = null;
    for (MatOfPoint contour : contours) {
        //Convert contours(i) from MatOfPoint to MatOfPoint2f
        if (contour2f == null)
            contour2f = new MatOfPoint2f(contour.toArray());
        if (contour.size().area() > contour2f.size().area()) {
            contour2f = new MatOfPoint2f(contour.toArray());
        }
    }
    try {
        Imgproc.fitEllipse(contour2f);
        rotatedrect = Imgproc.fitEllipse(contour2f);

        double approxDistance = Imgproc.arcLength(contour2f, true) * 0.02;
        Imgproc.approxPolyDP(contour2f, approxCurve, approxDistance, true);

        //Convert back to MatOfPoint
        MatOfPoint points = new MatOfPoint(approxCurve.toArray());

        // Get bounding rect of contour
        Rect rect = Imgproc.boundingRect(points);

        // draw enclosing rectangle (all same color, but you could use variable i to make them unique)
        Imgproc.rectangle(sourceImg, rect.tl(), rect.br(), new Scalar(255, 0, 0), 1, 8, 0);
        Imgproc.ellipse(sourceImg, rotatedrect, new Scalar(255, 192, 203), 4, 8);
    } catch (CvException e) {
        e.printStackTrace();
        System.out.println("Ingen ellipse fundet");
    }
    return sourceImg;
}

From source file:org.lasarobotics.vision.detection.PrimitiveDetection.java

License:Open Source License

/**
 * Locate ellipses within an image//from w  w w . j  av  a 2  s  .c o m
 *
 * @param grayImage Grayscale image
 * @return Ellipse locations
 */
public static EllipseLocationResult locateEllipses(Mat grayImage) {
    Mat gray = grayImage.clone();

    Filter.downsample(gray, 2);
    Filter.upsample(gray, 2);

    Imgproc.Canny(gray, gray, 5, 75, 3, true);
    Filter.dilate(gray, 2);

    Mat cacheHierarchy = new Mat();

    List<MatOfPoint> contoursTemp = new ArrayList<>();
    //Find contours - the parameters here are very important to compression and retention
    Imgproc.findContours(gray, contoursTemp, cacheHierarchy, Imgproc.CV_RETR_TREE,
            Imgproc.CHAIN_APPROX_TC89_KCOS);

    //List contours
    List<Contour> contours = new ArrayList<>();
    for (MatOfPoint co : contoursTemp) {
        contours.add(new Contour(co));
    }

    //Find ellipses by finding fit
    List<Ellipse> ellipses = new ArrayList<>();
    for (MatOfPoint co : contoursTemp) {
        contours.add(new Contour(co));
        //Contour must have at least 6 points for fitEllipse
        if (co.toArray().length < 6)
            continue;
        //Copy MatOfPoint to MatOfPoint2f
        MatOfPoint2f matOfPoint2f = new MatOfPoint2f(co.toArray());
        //Fit an ellipse to the current contour
        Ellipse ellipse = new Ellipse(Imgproc.fitEllipse(matOfPoint2f));

        //Draw ellipse
        ellipses.add(ellipse);
    }

    return new EllipseLocationResult(contours, ellipses);
}

From source file:uom.research.thalassemia.logic.BloodCellData.java

/**
 * get min and max diameters.//from  w  w w .j  a va2  s  .  c om
 *
 * @param pcontours contours
 */
private void getMinMaxDiameter(final List<MatOfPoint> pcontours) {
    MatOfPoint allcontours = new MatOfPoint();
    List<Double> diameters = new ArrayList<>();
    for (MatOfPoint mat : pcontours) {
        mat.copyTo(allcontours);
        RotatedRect boundingEllipse;
        if (allcontours.toArray().length > 4) {
            MatOfPoint2f newMat2 = new MatOfPoint2f(allcontours.toArray());
            boundingEllipse = Imgproc.fitEllipse(newMat2);
            //ellipse centre x cordination
            double xx = boundingEllipse.center.x;
            //ellipse centre y cordination
            double yy = boundingEllipse.center.y;
            //ellipse width
            double width = boundingEllipse.size.width;
            //ellipse height
            double height = boundingEllipse.size.height;
            diameters.add(width);
        }
    }
    if (diameters.size() > 1) {
        diameters.sort(null);
    }
    minDiameter = diameters.get(0);
    maxDiameter = diameters.get(diameters.size() - 1);
}

From source file:uom.research.thalassemia.logic.BloodCellDataProcessor.java

/**
 * process circular blood cell data including both pallor and red blood
 * cells./*from  w  w w  . j a v  a 2  s.  co  m*/
 *
 */
public void ellipseBloodCellsProcesser() {
    ellipseBloodCellsArray = new ArrayList<>();
    int index = 0;
    MatOfPoint allcontours = new MatOfPoint();
    for (MatOfPoint mat : contours) {
        mat.copyTo(allcontours);
        RotatedRect boundingEllipse;
        if (allcontours.toArray().length > FOUR) {
            MatOfPoint2f newMat2 = new MatOfPoint2f(allcontours.toArray());
            boundingEllipse = Imgproc.fitEllipse(newMat2);
            //ellipse centre x cordination
            double xx, yy, rr, width, height, area, perimeter, diameter, deviationValue, areaPreparation, sgf;

            xx = boundingEllipse.center.x;
            //ellipse centre y cordination
            yy = boundingEllipse.center.y;
            //ellipse width
            width = boundingEllipse.size.width;
            //ellipse height
            height = boundingEllipse.size.height;
            // assume radius is width. width is the hightest length.
            rr = width;
            sgf = width / height;
            //get area value
            area = calculateArea(width, height);
            //get perimeter value
            perimeter = calculatePerimeter(width, height);
            //get diameter value
            diameter = calculateDiameter(area, perimeter);
            // calculate deviational value
            if (rr > 0) {
                deviationValue = sgf / area;

                Map<Point, Double> points = getPallorBloodCellsPointList();
                areaPreparation = 0;

                Point point = new Point(xx, yy);
                if (points.containsKey(point)) {
                    areaPreparation = calculateArea(points.get(point)) / area;
                }

                Object[] ob = { (++index), xx, yy, rr, Validator.formatDouble(perimeter),
                        Validator.formatDouble(area), Validator.formatDouble(diameter),
                        Validator.formatDouble(deviationValue), Validator.formatDouble(areaPreparation) };

                totalEllipseArea += area;
                ellipseBloodCellsArray.add(ob);
            }
        }
    }
}

From source file:uom.research.thalassemia.logic.BloodCellDataProcessor.java

/**
 * get min and max diameters./*from  ww  w  . j a v a 2s .co  m*/
 *
 * @param pcontours contours
 */
private void getMinMaxDiameter(final List<MatOfPoint> pcontours) {
    MatOfPoint allcontours = new MatOfPoint();
    List<Double> diameters = new ArrayList<>();
    for (MatOfPoint mat : pcontours) {
        mat.copyTo(allcontours);
        RotatedRect boundingEllipse;
        if (allcontours.toArray().length > 4) {
            MatOfPoint2f newMat2 = new MatOfPoint2f(allcontours.toArray());
            boundingEllipse = Imgproc.fitEllipse(newMat2);
            //ellipse centre x cordination
            double x = boundingEllipse.center.x;
            //ellipse centre y cordination
            double y = boundingEllipse.center.y;
            //ellipse width
            double width = boundingEllipse.size.width;
            //ellipse height
            double height = boundingEllipse.size.height;
            diameters.add(width);
        }
    }
    if (diameters.size() > 1) {
        diameters.sort(null);
    }
    minDiameter = diameters.get(0);
    maxDiameter = diameters.get(diameters.size() - 1);
}

From source file:uom.research.thalassemia.logic.BloodCellsManipulationImpl.java

/**
 * do Blood Cell Processing.//from   w  w  w  .  j  a  va2 s .c o m
 *
 * @throws Exception Exception
 */
@Override
public void doBloodCellProcessing() throws Exception {
    if (imageFile.isFile()) {
        // Load Native Library
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

        // Load Selected File onto Original Mat
        original = Imgcodecs.imread(imageFile.getAbsolutePath(), Imgcodecs.CV_LOAD_IMAGE_UNCHANGED);

        // Create Mats with Original Mat's Size
        gray = original.clone();
        smooth = original.clone();
        canny = original.clone();
        threshold = original.clone();
        red = original.clone();
        laplacian = original.clone();
        circularsMat = original.clone();
        ellipsesMat = original.clone();

        // Sets Gray Scale to gray Map
        Imgproc.cvtColor(original, gray, Imgproc.COLOR_BGR2HSV);

        grayImage = convertMapToImage(gray);

        // Sest Red Colour Range Min and Max
        Scalar minc = new Scalar(95, 150, 75, 0);
        Scalar maxc = new Scalar(145, 255, 255, 0);

        // Sets Red Colour Mat for Given Range
        Core.inRange(original, maxc, maxc, red);

        redImage = convertMapToImage(red);

        int type = BufferedImage.TYPE_INT_RGB;
        //gray = Imgcodecs.imdecode(original, type);
        image = new BufferedImage(original.cols(), original.rows(), type);

        //Imgproc.GaussianBlur(mGray, mGray, new Size(15,15),50);
        //redImage = new BufferedImage(original.width(), original.height(), BufferedImage.TYPE_INT_RGB);
        //byte[] data2 = ((DataBufferByte) redImage.getRaster().getDataBuffer()).getData();
        Imgproc.threshold(gray, threshold, 155, 255, Imgproc.THRESH_BINARY);

        //Imgproc.Laplacian(gray, laplacian, CvType.CV_8UC3);//CV_8UC1);
        //laplacianImage = convertMapToImage(laplacian);
        thresholdImage = convertMapToImage(threshold);

        Imgproc.Canny(threshold, canny, 50, 100, 3, false);
        cannyImage = convertMapToImage(canny);

        //Imgproc.cvtColor(canny, canny, Imgproc.COLOR_BGR2GRAY);
        circles = new Mat();

        int imageArea = original.width() * original.height();

        if (imageArea > 5100000) {
            Imgproc.HoughCircles(canny, circles, Imgproc.CV_HOUGH_GRADIENT, 8, //Inverse ratio
                    220, //Minimum distance between the centers of the detected circles. default 100
                    100, //Higher threshold for canny edge detector. default100
                    200, //Threshold at the center detection stage. default 200
                    90, //min radius. default 50
                    130 //max radius. default 90
            );
        } else if (imageArea > 1309500) {
            Imgproc.HoughCircles(canny, circles, Imgproc.CV_HOUGH_GRADIENT, 8, //Inverse ratio
                    110, //Minimum distance between the centers of the detected circles. default 100
                    100, //Higher threshold for canny edge detector. default100
                    150, //Threshold at the center detection stage. default 200
                    50, //min radius. default 50
                    67 //max radius. default 90
            );
        } else if (imageArea > 540000) {
            Imgproc.HoughCircles(canny, circles, Imgproc.CV_HOUGH_GRADIENT, 8, //Inverse ratio
                    110, //Minimum distance between the centers of the detected circles. default 100
                    100, //Higher threshold for canny edge detector. default100
                    200, //Threshold at the center detection stage. default 200
                    30, //min radius. default 50
                    65 //max radius. default 90
            );
        } else if (imageArea > 400000) {
            Imgproc.HoughCircles(canny, circles, Imgproc.CV_HOUGH_GRADIENT, 8, //Inverse ratio
                    50, //Minimum distance between the centers of the detected circles. default 100
                    60, //Higher threshold for canny edge detector. default100
                    100, //Threshold at the center detection stage. default 200
                    25, //min radius. default 50
                    40 //max radius. default 90
            );
        }

        if (circles.cols() > 0) {
            for (int x = 0; x < circles.cols(); x++) {
                double vCircle[] = circles.get(0, x);
                if (vCircle == null) {
                    break;
                }
                Point pt = new Point(Math.round(vCircle[0]), Math.round(vCircle[1]));
                int radius = (int) Math.round(vCircle[2]);
                radiusList.add(radius);
                // draw the found circle
                Imgproc.circle(circularsMat, pt, radius, new Scalar(0, 255, 0), 3);
            }
        }

        // set Pallor circles
        circlesPallor = new Mat();
        if (imageArea > 5100000) {
            Imgproc.HoughCircles(canny, circlesPallor, Imgproc.CV_HOUGH_GRADIENT, 8, //Inverse ratio
                    220, //Minimum distance between the centers of the detected circles
                    100, //Higher threshold for canny edge detector
                    150, //Threshold at the center detection stage
                    0, //min radius
                    70 //max radius
            );
        } else if (imageArea > 1309500) {
            Imgproc.HoughCircles(canny, circlesPallor, Imgproc.CV_HOUGH_GRADIENT, 8, //Inverse ratio
                    110, //Minimum distance between the centers of the detected circles
                    50, //Higher threshold for canny edge detector
                    100, //Threshold at the center detection stage
                    0, //min radius
                    45 //max radius
            );
        } else if (imageArea > 540000) {
            Imgproc.HoughCircles(canny, circlesPallor, Imgproc.CV_HOUGH_GRADIENT, 8, //Inverse ratio
                    100, //Minimum distance between the centers of the detected circles
                    50, //Higher threshold for canny edge detector
                    100, //Threshold at the center detection stage
                    0, //min radius
                    35 //max radius
            );

        } else if (imageArea > 400000) {
            Imgproc.HoughCircles(canny, circlesPallor, Imgproc.CV_HOUGH_GRADIENT, 8, //Inverse ratio
                    50, //Minimum distance between the centers of the detected circles
                    10, //Higher threshold for canny edge detector
                    30, //Threshold at the center detection stage
                    0, //min radius
                    25 //max radius
            );

        }
        if (circlesPallor.cols() > 0) {
            for (int x = 0; x < circlesPallor.cols(); x++) {
                double vCircle[] = circlesPallor.get(0, x);
                if (vCircle == null) {
                    break;
                }
                Point pt = new Point(Math.round(vCircle[0]), Math.round(vCircle[1]));
                int radius = (int) Math.round(vCircle[2]);
                //radiusList.add(radius);
                // draw the found circle
                Imgproc.circle(circularsMat, pt, radius, new Scalar(0, 0, 255), 0);
            }
        }

        // set Ellipses
        contours = new ArrayList<>();
        Imgproc.findContours(canny, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
        MatOfPoint allcontours = new MatOfPoint();
        for (MatOfPoint mat : contours) {
            mat.copyTo(allcontours);
            RotatedRect boundingEllipse = null;
            if (allcontours.toArray().length > 4) {
                MatOfPoint newMat1 = new MatOfPoint(allcontours.toArray());
                MatOfPoint2f newMat2 = new MatOfPoint2f(allcontours.toArray());
                Rect boundingRect = Imgproc.boundingRect(newMat1);
                boundingEllipse = Imgproc.fitEllipse(newMat2);
            }

            if (boundingEllipse != null) {
                Imgproc.ellipse(ellipsesMat, boundingEllipse, new Scalar(255, 0, 0), 2);
            }
        }

        circleCount = circles.cols();
        circularsImage = convertMapToImage(circularsMat);
        ellipsesImage = convertMapToImage(ellipsesMat);
    }
}