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

Java tutorial

Introduction

Here is the source code for uom.research.thalassemia.logic.BloodCellDataProcessor.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.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
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;
import uom.research.thalassemia.util.FillData;
import uom.research.thalassemia.util.Validator;

/**
 *
 * @author anupama
 */
public final class BloodCellDataProcessor {

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

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

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

    /**
     * elliptical Blood Cells set.
     */
    private final Mat ellipticalBloodCells;

    /**
     * rotatedRect Blood Cells set.
     */
    private final List<MatOfPoint> contours;

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

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

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

    /**
     * keeps total blood cell area.
     */
    private double totalBloodCellArea = 1.0;

    /**
     * keeps total pallor area.
     */
    private double totalPallarArea = 0.0;

    /**
     * ellipse total Ellipse cell area.
     */
    private double totalEllipseArea = 0.0;

    /**
     * keeps all red blood cell data in array.
     */
    private List<Object[]> circularBloodCellsArray;

    /**
     * keeps all pallor cell data in array.
     */
    private List<Object[]> pallorBloodCellsArray;

    /**
     * keeps all ellipse cell data in array.
     */
    private List<Object[]> ellipseBloodCellsArray;

    /**
     * Creates new form CircleData.
     *
     * @param circleSet circularBloodCells
     * @param ellipseSet ellipticalBloodCells
     * @param pallorSet pallorBloodCells
     */
    public BloodCellDataProcessor(final Mat circleSet, final Mat ellipseSet, final Mat pallorSet) {
        this.circularBloodCells = circleSet;
        this.ellipticalBloodCells = ellipseSet;
        this.pallorBloodCells = pallorSet;
        this.contours = null;
    }

    /**
     * Creates new form CircleData.
     *
     * @param circleSet circularBloodCells
     * @param ellipseSet contours
     * @param pallorSet pallorBloodCells
     */
    public BloodCellDataProcessor(final Mat circleSet, final List<MatOfPoint> ellipseSet, final Mat pallorSet) {
        this.circularBloodCells = circleSet;
        this.contours = ellipseSet;
        this.pallorBloodCells = pallorSet;
        this.ellipticalBloodCells = null;
    }

    /**
     * process circular blood cell data including both pallor and red blood
     * cells.
     *
     * @param currentSelection Mat of selected
     */
    public void circularBloodCellsProcesser(final Mat currentSelection) {

        if (currentSelection != null) {
            if (currentSelection == circularBloodCells) {
                circularBloodCellsArray = new ArrayList<>();
            } else if (currentSelection == pallorBloodCells) {
                pallorBloodCellsArray = new ArrayList<>();
            }
            getMinMaxDiameter(currentSelection);
            double sgf = 0;
            if (minDiameter != 0) {
                //calculate shape geometric factor
                sgf = maxDiameter / minDiameter;
            }
            Map<Point, Double> points = getPallorBloodCellsPointList();
            double[] circles;
            double x, y, r, area, perimeter, diameter, deviationValue, areaPreparation;
            for (int a = 0; a < currentSelection.cols(); a++) {
                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;
                }
                Object[] ob = { (a + 1), x, y, r, Validator.formatDouble(perimeter), Validator.formatDouble(area),
                        Validator.formatDouble(diameter), Validator.formatDouble(deviationValue),
                        Validator.formatDouble(areaPreparation) };

                if (currentSelection == circularBloodCells) {
                    totalBloodCellArea += area;
                    circularBloodCellsArray.add(ob);
                } else if (currentSelection == pallorBloodCells) {
                    totalPallarArea += area;
                    pallorBloodCellsArray.add(ob);
                } else {
                    totalEllipseArea += area;
                }
            }
        }
    }

    /**
     * process circular blood cell data including both pallor and red blood
     * cells.
     *
     */
    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);
                }
            }
        }
    }

    /**
     * fill table.
     *
     * @param jTable1 jTable1
     * @param currentSelection currentSelection
     */
    public void fillTable(final JTable jTable1, final Mat currentSelection) {
        FillData.doEmptyTable(jTable1);
        DefaultTableModel dtm = (DefaultTableModel) jTable1.getModel();
        if (currentSelection == circularBloodCells) {
            circularBloodCellsArray.stream().forEach((circularBloodCell) -> {
                dtm.addRow(circularBloodCell);
            });
        } else if (currentSelection == pallorBloodCells) {
            pallorBloodCellsArray.stream().forEach((circularBloodCell) -> {
                dtm.addRow(circularBloodCell);
            });
        }
    }

    /**
     * fill Table.
     *
     * @param jTable1 jTable1
     * @param pcontours contours
     */
    public void fillTable(final JTable jTable1, final List<MatOfPoint> pcontours) {
        FillData.doEmptyTable(jTable1);
        DefaultTableModel dtm = (DefaultTableModel) jTable1.getModel();
        ellipseBloodCellsArray.stream().forEach((ellipseBloodCell) -> {
            dtm.addRow(ellipseBloodCell);
        });
    }

    /**
     * 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 FI * ((3 * (width + height)) - Math.sqrt(((3 * width) + height) + (width + (3 * height))));
    }

    /**
     * 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 area double area value
     * @param cpArea double centralPallorArea value
     * @return areaProporation as double
     */
    private double calculateAreaProporation(final double area, final double cpArea) {
        return cpArea / area;
    }

    /**
     * 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 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);
    }

    /**
     * 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);
    }

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

    /**
     * keeps total blood cell area.
     *
     * @return the totalBloodCellArea
     */
    public double getTotalBloodCellArea() {
        return totalBloodCellArea;
    }

    /**
     * keeps total pallor area.
     *
     * @return the totalPallarArea
     */
    public double getTotalPallarArea() {
        return totalPallarArea;
    }

    /**
     * ellipse total Ellipse cell area.
     *
     * @return the totalEllipseArea
     */
    public double getTotalEllipseArea() {
        return totalEllipseArea;
    }
}