// Catalano Imaging Library
// The Catalano Framework
//
// Copyright © Diego Catalano, 2012-2016
// diego.catalano at live.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
/*
* Shape Descriptors.
* Total: 11
*/
package Catalano.Imaging.Tools;
import Catalano.Core.IntPoint;
import Catalano.Imaging.FastBitmap;
import Catalano.Imaging.Filters.DistanceTransform;
import Catalano.Imaging.Filters.Invert;
import Catalano.Math.Distances.Distance;
import Catalano.Math.Matrix;
import java.util.ArrayList;
import java.util.List;
/**
* Shape Descriptors.
* @author Diego Catalano
*/
public final class ShapeDescriptors {
/**
* Don't let anyone instantiate this class.
*/
private ShapeDescriptors(){};
/**
* Area.
* Total of pixels white.
* Equation: Sum(Image).
* @param fastBitmap Image to be processed.
* @return Area.
*/
public static int Area(FastBitmap fastBitmap){
int area = 0;
for (int x = 0; x < fastBitmap.getHeight(); x++) {
for (int y = 0; y < fastBitmap.getWidth(); y++) {
if (fastBitmap.getGray(x, y) == 255) {
area++;
}
}
}
return area;
}
/**
* Area equivalent diameter.
* Equation: sqrt((4 / Pi) * Area)
* @param area Area.
* @return Area equivalent diameter.
*/
public static double AreaEquivalentDiameter(int area){
double v = 1.2732395447351626861510701069801;
return Math.sqrt(v*area);
}
/**
* Circularity.
* Equation: 4 * Pi * Area / (Perimeter ^ 2)
* @param area Area.
* @param perimeter Perimeter.
* @return Circularity.
*/
public double Circularity(int area, int perimeter){
double v = 12.566370614359172953850573533118;
return (v*area) / (perimeter*perimeter);
}
/**
* Compactness.
* Equation: AreaEquivalentDiameter / feretDiameter
* @param area Area
* @param feretDiameter Feret diameter.
* @return Compactness.
*/
public double Compactness(int area, double feretDiameter){
return AreaEquivalentDiameter(area) / feretDiameter;
}
/**
* Euler number.
* Number of holes in the shape.
* @param fastBitmap Image to be processed.
* @return Euler number.
*/
public static int EulerNumber(FastBitmap fastBitmap){
Invert inv = new Invert();
inv.applyInPlace(fastBitmap);
BlobDetection bd = new BlobDetection();
List blobs = bd.ProcessImage(fastBitmap);
int size = blobs.size() - 1;
if(size < 0) return 0;
return size;
}
/**
* Feret Diameter.
* Feret diameter is also called the maximum diameter in image.
* @param contour Contour of the image.
* @return Feret diameter.
*/
public static double FeretDiameter(List contour){
double maxDiameter = 0;
for (IntPoint p : contour) {
for (IntPoint pp : contour) {
double d = Distance.SquaredEuclidean(p.x, p.y, pp.x, pp.y);
if (d > maxDiameter) {
maxDiameter = d;
}
}
}
return Math.sqrt(maxDiameter);
}
/**
* Feret Points
* @param contour Contour of the shape.
* @return Feret Points.
*/
public static List FeretPoints(List contour){
List lst = new ArrayList();
IntPoint p1 = new IntPoint();
IntPoint p2 = new IntPoint();
double maxDiameter = 0;
for (IntPoint p : contour) {
for (IntPoint pp : contour) {
double d = Distance.SquaredEuclidean(p.x, p.y, pp.x, pp.y);
if (d > maxDiameter) {
maxDiameter = d;
p1 = p;
p2 = pp;
}
}
}
lst.add(p1);
lst.add(p2);
return lst;
}
public static double Irregularity(double thinnessRatio){
return 1/thinnessRatio;
}
/**
* Maximum error circularity.
* @param mcc Minimum Circumscribed Circle.
* @param mic Maximum Inscribed Circle.
* @return Maximum error circularity.
*/
public static double MaximumErrorCircularity(double mcc, double mic){
return mcc - mic;
}
/**
* Maximum inscribed circle.
* @param fastBitmap Image to be processed.
* @return Maximum inscribed circle.
*/
public static double MaximumInscribedCircle(FastBitmap fastBitmap){
DistanceTransform dt = new DistanceTransform();
float[][] dist = dt.Compute(fastBitmap);
return Matrix.Max(dist);
}
/**
* Minimum circumscribed circle.
* @param starPoint The point where is the most distance from nearest boundary.
* @param contour Contour of the shape.
* @return Minimum circumscribed circle.
*/
public static double MinimumCircumscribedCircle(IntPoint starPoint, List contour){
double max = Double.MIN_VALUE;
for (IntPoint p : contour) {
double d = Distance.SquaredEuclidean(p, starPoint);
if (d > max){
max = d;
}
}
return Math.sqrt(max);
}
/**
* Star Point.
* @param fastBitmap Image to be processed.
* @return IntPoint The point where is the most distance from nearest boundary.
*/
public static IntPoint StarPoint (FastBitmap fastBitmap){
DistanceTransform dt = new DistanceTransform();
float[][] dist = dt.Compute(fastBitmap);
return Matrix.MaxIndex(dist);
}
/**
* Perimeter Equivalent Diameter.
* Equation: area / PI
* @param area Area.
* @return Perimeter Equivalent Diameter.
*/
public static double PerimeterEquivalentDiameter(int area){
return area / Math.PI;
}
/**
* Roughness.
* Equation: (width / height)
* @param width Width of the object.
* @param height Height of the object.
* @return Roughness.
*/
public static double Roughness(int width, int height){
return width/height;
}
/**
* Roundness.
* Equation: (4 * area) / (PI * (feretDiameter ^ 2)
* @param area Area.
* @param feretDiameter Feret diameter.
* @return Roundness.
*/
public static double Roundness(int area, double feretDiameter){
return (4 * area) / (Math.PI * (feretDiameter * feretDiameter));
}
/**
* Shape.
* Equation: (perimeter ^ 2) / area
* @param area Area.
* @param perimeter Perimeter.
* @return Shape.
*/
public static double Shape(int area, int perimeter){
return (perimeter * perimeter) / area;
}
/**
* Thinness Ratio.
* Equation: 4 * Pi * (area/perimeter).
* @param area Area.
* @param perimeter Perimeter.
* @return Thinness ratio.
*/
public static double ThinnessRatio(int area, int perimeter){
double v = 12.566370614359172953850573533118;
return v * (area/perimeter);
}
/**
* Ultimate Eroded Points.
* Computes the ultimate points from erosion operation.
* @param fastBitmap Image to be processed.
* @return List of points contains
*/
public static List UltimateErodedPoints(FastBitmap fastBitmap){
ArrayList points = new ArrayList();
DistanceTransform dt = new DistanceTransform();
float[][] dist = dt.Compute(fastBitmap);
BlobDetection bd = new BlobDetection();
List blobs = bd.ProcessImage(fastBitmap);
for (Blob blob : blobs) {
List lst = blob.getPoints();
float max = 0;
for (IntPoint p : lst) {
if(dist[p.x][p.y] > max){
max = dist[p.x][p.y];
}
}
for (IntPoint p : lst) {
if(dist[p.x][p.y] == max){
points.add(new IntPoint(p));
}
}
}
return points;
}
}
Ads help maintain this website.