uom.research.thalassemia.logic.BloodCellData.java Source code

Java tutorial

Introduction

Here is the source code for uom.research.thalassemia.logic.BloodCellData.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package uom.research.thalassemia.logic;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.RotatedRect;
import org.opencv.imgproc.Imgproc;

/**
 *
 * @author nadeera
 */
public class BloodCellData {

    /**
     * Frame height.
     */
    private static final double FI = 22.0 / 7.0;

    /**
     * FOUR (4) as constant.
     */
    private static final int FOUR = 4;

    /**
     * min diameter.
     */
    private double minDiameter;

    /**
     * max diameter.
     */
    private double maxDiameter;

    /**
     * pallor Blood Cells set.
     */
    private final Mat pallorBloodCells;

    /**
     * circular Blood Cells set.
     */
    private final Mat circularBloodCells;

    /**
     * keeps list of blood related classes.
     */
    private final Map<String, Integer> classes;

    public Map<String, Integer> getClasses() {
        return classes;
    }

    public double getX() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }

    public double getR() {
        return r;
    }

    public void setR(double r) {
        this.r = r;
    }

    public double getArea() {
        return area;
    }

    public void setArea(double area) {
        this.area = area;
    }

    public double getPerimeter() {
        return perimeter;
    }

    public void setPerimeter(double perimeter) {
        this.perimeter = perimeter;
    }

    public double getDiameter() {
        return diameter;
    }

    public void setDiameter(double diameter) {
        this.diameter = diameter;
    }

    public double getDeviationValue() {
        return deviationValue;
    }

    public void setDeviationValue(double deviationValue) {
        this.deviationValue = deviationValue;
    }

    public double getAreaPreparation() {
        return areaPreparation;
    }

    public void setAreaPreparation(double areaPreparation) {
        this.areaPreparation = areaPreparation;
    }

    public double getSGF() {
        return sgf;
    }

    public void setSGF(double psgf) {
        this.sgf = psgf;
    }

    private double x, y, r, area, perimeter, diameter, deviationValue, areaPreparation, sgf;
    /**
     *
     */
    private final boolean tf;

    public BloodCellData(final Mat circleSet, final Mat ellipseSet, final Mat pallorSet) {
        pallorBloodCells = pallorSet;
        circularBloodCells = circleSet;
        tf = true;
        classes = new HashMap<>();
        process(circleSet);
    }

    private void process(final Mat currentSelection) {
        sgf = 0;
        getMinMaxDiameter(currentSelection);
        if (minDiameter != 0) {
            //calculate shape geometric factor
            sgf = maxDiameter / minDiameter;
        }
        double[] circles;

        for (int a = 0; a < currentSelection.cols(); a++) {

            Map<Point, Double> points = getPallorBloodCellsPointList();
            areaPreparation = 0;
            circles = currentSelection.get(0, a);
            x = circles[0];
            y = circles[1];
            r = Math.round(circles[2]);

            //get area value
            area = calculateArea(r);
            //get perimeter value
            perimeter = calculatePerimeter(r);
            //get diameter value
            diameter = calculateDiameter(area, perimeter);
            // calculate deviational value
            deviationValue = sgf / area;

            Point point = new Point(x, y);
            if (points.containsKey(point)) {
                areaPreparation = calculateArea(points.get(point)) / area;
            }
            getAbnormalCellTypes();
        }
    }

    /**
     * get min and max diameters.
     *
     * @param currentSelection currentSelection of Mat
     */
    private void getMinMaxDiameter(final Mat currentSelection) {
        double[] circles;
        List<Double> diameters = new ArrayList<>();
        double r, diameter;
        for (int a = 0; a < currentSelection.cols(); a++) {
            circles = currentSelection.get(0, a);
            r = Math.round(circles[2]);
            diameter = calculateDiameter(r);
            diameters.add(diameter);
        }
        if (diameters.size() > 1) {
            diameters.sort(null);
        }
        minDiameter = diameters.get(0);
        maxDiameter = diameters.get(diameters.size() - 1);
    }

    /**
     * Calculate Area of a Circle.
     *
     * @param radius double radius value
     * @return area as double
     */
    private double calculateArea(final double radius) {
        return FI * radius * radius;
    }

    /**
     * Calculate Area of a Ellipse.
     *
     * @param width double width value
     * @param height double height value
     * @return area as double
     */
    private double calculateArea(final double width, final double height) {
        return FI * (height / 2) * (width / 2);
    }

    /**
     * Calculate Perimeter of a Circle.
     *
     * @param radius double perimeter value
     * @return perimeter as double
     */
    private double calculatePerimeter(final double radius) {
        return 2 * FI * radius;
    }

    /**
     * Calculate Perimeter of a Ellipse.
     *
     * @param width double perimeter value
     * @param height double perimeter value
     * @return perimeter as double
     */
    private double calculatePerimeter(final double width, final double height) {
        return 0; //Math.
    }

    /**
     * Calculate Diameter of a Circle.
     *
     * @param area double area value
     * @param perimeter double perimeter value
     * @return diameter as double
     */
    private double calculateDiameter(final double area, final double perimeter) {
        return (FOUR * area) / perimeter;
    }

    /**
     * Calculate Diameter of a Circle.
     *
     * @param radius double diameter value
     * @return diameter as double
     */
    private double calculateDiameter(final double radius) {
        return FOUR * (FI * radius * radius) / (2 * FI * radius);
    }

    /**
     * Calculate Area Proportion of Circle.
     *
     * @param parea double area value
     * @param cpArea double centralPallorArea value
     * @return areaProporation as double
     */
    private double calculateAreaProporation(final double parea, final double cpArea) {
        return cpArea / parea;
    }

    /**
     * get min and max diameters.
     *
     * @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);
    }

    /**
     * get Pallor Blood cells point list.
     *
     * @return List<Point> List
     */
    private Map<Point, Double> getPallorBloodCellsPointList() {
        double[] circles;
        Map<Point, Double> points = new HashMap<>();
        double xx, yy, rr;
        for (int a = 0; a < pallorBloodCells.cols(); a++) {
            circles = pallorBloodCells.get(0, a);
            xx = circles[0];
            yy = circles[1];
            rr = Math.round(circles[2]);
            points.put(new Point(xx, yy), rr);
        }
        return points;
    }

    /**
     * identify abnormal cell types.
     *
     */
    private void getAbnormalCellTypes() {
        //System.out.println("sgf " + sgf + " | deviationVal " + deviationValue + " | diameter " + diameter + " | area " + area + " | AP " + areaPreparation);
        if (sgf > 1.2) {
            //sgf true
            if (deviationValue > 0.2) {
                //dv true
                fillClasses("Class 12");
            } else {
                //dv false
                fillClasses("Class 5");
            }
        } else {
            System.out.print("");
            if ((6.5 < diameter) && (8.5 > diameter)) {
                if (area > 0) {
                    if (tf) {
                        fillClasses("Class 6");
                    } else if (areaPreparation > 0.2) {
                        fillClasses("Class 9");
                    } else {
                        fillClasses("Class 1");
                    }
                } else {
                    fillClasses("Class 2");
                }
            } else {
                System.out.print("");
                if (deviationValue > 8.5) {
                    if (area > 0) {
                        //cpArea true
                        if (areaPreparation > 0.2) {
                            //ap true
                            fillClasses("Class 8");
                        } else {
                            //ap false
                            fillClasses("Class 9");
                        }
                    } else {
                        fillClasses("Class 3");
                    }
                } else {
                    System.out.print("");
                    if (area > 0) {
                        //cpArea true
                        if (areaPreparation > 0.2) {
                            fillClasses("Class 7");
                        } else {
                            //cpArea false
                            fillClasses("Class 10");
                        }
                    } else {
                        //cpArea false
                        fillClasses("Class 4");
                    }
                }
            }
        }
    }

    /**
     * get cell type count.
     *
     * @param key key
     */
    private void fillClasses(final String key) {
        if (classes.containsKey(key)) {
            int value = classes.get(key);
            classes.put(key, ++value);
        } else {
            classes.put(key, 1);
        }
    }

}