// Path: desktop/src/main/java/com/cv4j/core/datamodel/MeasureData.java
// public class MeasureData {
// 
//     private Point cp; // center x of the contour and center y of the contour
//     private double angle; // angle of the contour rotated
//     private double area; // measure the area of contour
//     private double roundness; // measure the possible circle of the contour
// 
//     @Override
//     public String toString() {
// 
//         NumberFormat format = new DecimalFormat("#.00");
//         StringBuilder sb = new StringBuilder();
//         sb.append("Point:").append(cp.x).append(",").append(cp.y).append("\n")
//                 .append("angle:").append((Math.abs(angle) == 0 ? 0.0 :format.format(angle))).append("\n")
//                 .append("area:").append((int)area).append("\n")
//                 .append("roundness:").append(format.format(roundness));
//         return sb.toString();
//     }
// 
// 	public Point getCp() {
// 		return cp;
// 	}
// 
// 	public void setCp(Point cp) {
// 		this.cp = cp;
// 	}
// 
// 	public double getAngle() {
// 		return angle;
// 	}
// 
// 	public void setAngle(double angle) {
// 		this.angle = angle;
// 	}
// 
// 	public double getArea() {
// 		return area;
// 	}
// 
// 	public void setArea(double area) {
// 		this.area = area;
// 	}
// 
// 	public double getRoundness() {
// 		return roundness;
// 	}
// 
// 	public void setRoundness(double roundness) {
// 		this.roundness = roundness;
// 	}
//     
//     
// }
// 
// Path: desktop/src/main/java/com/cv4j/core/datamodel/Point.java
// public class Point {
// 
//     public int x;
//     public int y;
//     
//     public Point(int x, int y) {
//     	this.x = x;
//     	this.y = y;
//     }
//     
//     public Point() {
//     	this.x = 0;
//     	this.y = 0;
//     }
// }


import com.cv4j.core.datamodel.MeasureData;
import com.cv4j.core.datamodel.Point;
import java.util.List;
/*
 * Copyright (c) 2017-present, CV4J Contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.cv4j.core.binary;



public class GeoMoments {

    /***
     *
     * @param pixelList - the tagged pixel of this contours
     * @return some benchmark data for the contour
     */
    public MeasureData calculate(List<PixelNode> pixelList) {
        MeasureData measures = new MeasureData();
        measures.setArea(pixelList.size());
        measures.setCp(getCenterPoint(pixelList));

        double m11 = centralMoments(pixelList, 1, 1);
        double m02 = centralMoments(pixelList, 0, 2);
        double m20 = centralMoments(pixelList, 2, 0);
        double m112 = m11 * m11;
        double dd = Math.pow((m20-m02), 2);
        double sum1 = Math.sqrt(dd + 4*m112);
        double sum2 = m02 + m20;
        double a1 = sum2 + sum1;
        double a2 = sum2 - sum1;

        double ra = Math.sqrt((2*a1)/Math.abs(pixelList.size()));
        double rb = Math.sqrt((2*a2)/Math.abs(pixelList.size()));
        double angle = ((m20 - m02) == 0) ? Math.PI/4.0 : Math.atan((2*m11)/(m20 - m02))/2.0;
        measures.setAngle(angle);
        measures.setRoundness(rb == 0? Double.MAX_VALUE : ra/rb);
        return measures;
    }

    private Point getCenterPoint(List<PixelNode> pixelList)
    {
        double m00 = moments(pixelList, 0, 0);
        double yCr = moments(pixelList, 1, 0) / m00; // row
        double xCr = moments(pixelList, 0, 1) / m00; // column
// Path: desktop/src/main/java/com/cv4j/core/datamodel/MeasureData.java
// public class MeasureData {
// 
//     private Point cp; // center x of the contour and center y of the contour
//     private double angle; // angle of the contour rotated
//     private double area; // measure the area of contour
//     private double roundness; // measure the possible circle of the contour
// 
//     @Override
//     public String toString() {
// 
//         NumberFormat format = new DecimalFormat("#.00");
//         StringBuilder sb = new StringBuilder();
//         sb.append("Point:").append(cp.x).append(",").append(cp.y).append("\n")
//                 .append("angle:").append((Math.abs(angle) == 0 ? 0.0 :format.format(angle))).append("\n")
//                 .append("area:").append((int)area).append("\n")
//                 .append("roundness:").append(format.format(roundness));
//         return sb.toString();
//     }
// 
// 	public Point getCp() {
// 		return cp;
// 	}
// 
// 	public void setCp(Point cp) {
// 		this.cp = cp;
// 	}
// 
// 	public double getAngle() {
// 		return angle;
// 	}
// 
// 	public void setAngle(double angle) {
// 		this.angle = angle;
// 	}
// 
// 	public double getArea() {
// 		return area;
// 	}
// 
// 	public void setArea(double area) {
// 		this.area = area;
// 	}
// 
// 	public double getRoundness() {
// 		return roundness;
// 	}
// 
// 	public void setRoundness(double roundness) {
// 		this.roundness = roundness;
// 	}
//     
//     
// }
// 
// Path: desktop/src/main/java/com/cv4j/core/datamodel/Point.java
// public class Point {
// 
//     public int x;
//     public int y;
//     
//     public Point(int x, int y) {
//     	this.x = x;
//     	this.y = y;
//     }
//     
//     public Point() {
//     	this.x = 0;
//     	this.y = 0;
//     }
// }


// Path: desktop/src/main/java/com/cv4j/core/binary/GeoMoments.java
import com.cv4j.core.datamodel.MeasureData;
import com.cv4j.core.datamodel.Point;
import java.util.List;

/*
 * Copyright (c) 2017-present, CV4J Contributors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.cv4j.core.binary;



public class GeoMoments {

    /***
     *
     * @param pixelList - the tagged pixel of this contours
     * @return some benchmark data for the contour
     */
    public MeasureData calculate(List<PixelNode> pixelList) {
        MeasureData measures = new MeasureData();
        measures.setArea(pixelList.size());
        measures.setCp(getCenterPoint(pixelList));

        double m11 = centralMoments(pixelList, 1, 1);
        double m02 = centralMoments(pixelList, 0, 2);
        double m20 = centralMoments(pixelList, 2, 0);
        double m112 = m11 * m11;
        double dd = Math.pow((m20-m02), 2);
        double sum1 = Math.sqrt(dd + 4*m112);
        double sum2 = m02 + m20;
        double a1 = sum2 + sum1;
        double a2 = sum2 - sum1;

        double ra = Math.sqrt((2*a1)/Math.abs(pixelList.size()));
        double rb = Math.sqrt((2*a2)/Math.abs(pixelList.size()));
        double angle = ((m20 - m02) == 0) ? Math.PI/4.0 : Math.atan((2*m11)/(m20 - m02))/2.0;
        measures.setAngle(angle);
        measures.setRoundness(rb == 0? Double.MAX_VALUE : ra/rb);
        return measures;
    }

    private Point getCenterPoint(List<PixelNode> pixelList)
    {
        double m00 = moments(pixelList, 0, 0);
        double yCr = moments(pixelList, 1, 0) / m00; // row
        double xCr = moments(pixelList, 0, 1) / m00; // column
        return new Point((int)xCr, (int)yCr);