├── .mvn └── wrapper │ ├── maven-wrapper.jar │ ├── maven-wrapper.properties │ └── MavenWrapperDownloader.java ├── src ├── main │ └── java │ │ └── javax │ │ └── visrec │ │ ├── ml │ │ ├── detection │ │ │ ├── package-info.java │ │ │ ├── ObjectDetector.java │ │ │ └── BoundingBox.java │ │ ├── data │ │ │ ├── preprocessing │ │ │ │ ├── package-info.java │ │ │ │ └── Scaler.java │ │ │ ├── package-info.java │ │ │ ├── Column.java │ │ │ ├── BasicDataSet.java │ │ │ └── DataSet.java │ │ ├── classification │ │ │ ├── package-info.java │ │ │ ├── BinaryClassifier.java │ │ │ ├── MultiClassClassifier.java │ │ │ ├── AbstractMultiClassClassifier.java │ │ │ ├── ClassificationException.java │ │ │ ├── LogisticRegression.java │ │ │ ├── Classifiable.java │ │ │ ├── ImageClassifier.java │ │ │ ├── Classifier.java │ │ │ ├── EnsambleClassifier.java │ │ │ ├── NeuralNetBinaryClassifier.java │ │ │ └── NeuralNetImageClassifier.java │ │ ├── model │ │ │ ├── ModelProvider.java │ │ │ ├── InvalidConfigurationException.java │ │ │ ├── ModelCreationException.java │ │ │ └── ModelBuilder.java │ │ ├── regression │ │ │ ├── Regressor.java │ │ │ └── SimpleLinearRegression.java │ │ └── eval │ │ │ ├── Evaluator.java │ │ │ ├── RegressionMetrics.java │ │ │ ├── ClassificationMetrics.java │ │ │ └── EvaluationMetrics.java │ │ ├── package-info.java │ │ ├── spi │ │ ├── ImageClassifierFactory.java │ │ ├── BinaryClassifierFactory.java │ │ ├── ImageFactoryService.java │ │ ├── ImplementationService.java │ │ ├── ServiceRegistry.java │ │ ├── ClassifierFactoryService.java │ │ └── ServiceProvider.java │ │ └── ImageFactory.java └── test │ └── resources │ └── META-INF │ └── services │ └── javax.visrec.util.ImageFactory ├── .gitignore ├── .github └── workflows │ ├── build.yml │ ├── snapshot.yml │ └── staging.yml ├── settings.xml ├── README.md ├── gradlew.bat ├── pom.xml ├── gradlew ├── mvnw.cmd ├── mvnw └── LICENSE.md /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaVisRec/visrec-api/HEAD/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/detection/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Object detection algorithms. 3 | */ 4 | package javax.visrec.ml.detection; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.iml 3 | .gradle/ 4 | gradle/ 5 | */build/** 6 | */target/** 7 | target/ 8 | build/ 9 | *.class 10 | target/ 11 | *.lst 12 | *.log 13 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/data/preprocessing/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Data preprocessing techniques used to prepare data for building machine learning models. 3 | */ 4 | package javax.visrec.ml.data.preprocessing; -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.1/apache-maven-3.6.1-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /src/test/resources/META-INF/services/javax.visrec.util.ImageFactory: -------------------------------------------------------------------------------- 1 | javax.visrec.util.BufferedImageFactory 2 | javax.visrec.internal.ExampleImageFactory 3 | javax.visrec.internal.InvalidExampleImageFactory 4 | javax.visrec.internal.MissingAnnotationImageFactory -------------------------------------------------------------------------------- /src/main/java/javax/visrec/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Reusable abstractions for visual recognition tasks based on machine learning, 3 | * that simplify implementation and integration of various machine learning models and image types. 4 | */ 5 | package javax.visrec; -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/data/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * A collection of example data used to build/train machine learning model. 3 | * The goal of this package is to have reusable data abstractions with common operations for building machine learning models. 4 | */ 5 | package javax.visrec.ml.data; -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/classification/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Classification represents task of determining a category of a given object. 3 | * Machine learning classifiers are able to learn from examples how to determine 4 | * a category (or a label) for a given input object, that has not seen before 5 | * (although it should be similar to examples that were used to build a classifier). 6 | */ 7 | package javax.visrec.ml.classification; -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Set up JDK 1.8 16 | uses: actions/setup-java@v1 17 | with: 18 | java-version: 1.8 19 | #settings-path: ${{ github.workspace }} # location for the settings.xml 20 | #server-id: github # Value of the distributionManagement/repository/id field of the pom.xml 21 | - name: Build with Maven 22 | run: ./mvnw package 23 | -------------------------------------------------------------------------------- /settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | ossrh 9 | ${env.OSSRH_USERNAME} 10 | ${env.OSSRH_PASSWORD} 11 | 12 | 13 | 14 | 15 | 16 | ossrh 17 | 18 | true 19 | 20 | 21 | gpg 22 | ${env.GPG_PASSPHRASE} 23 | 24 | 25 | 26 | 27 | ossrh 28 | 29 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/model/ModelProvider.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.model; 21 | 22 | /** 23 | * This interface should be implemented by classes which expose access to underlying ML model 24 | * 25 | * @param Type of the underlying ML model 26 | */ 27 | public interface ModelProvider { 28 | 29 | T getModel(); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/classification/BinaryClassifier.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.classification; 21 | 22 | /** 23 | * Binary classifier classifies input object into one of two possible categories 24 | * (for example: true/false, yes/no, red/blue, positive/negative, spam/not-spam, fraud/not-fraud). 25 | * Returns a probability (float value [0..1]) that input object belongs to the positive class. 26 | */ 27 | public interface BinaryClassifier extends Classifier { 28 | 29 | } -------------------------------------------------------------------------------- /src/main/java/javax/visrec/spi/ImageClassifierFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.spi; 21 | 22 | import javax.visrec.ml.model.ModelCreationException; 23 | import javax.visrec.ml.classification.ImageClassifier; 24 | import javax.visrec.ml.classification.NeuralNetImageClassifier; 25 | 26 | public interface ImageClassifierFactory { 27 | 28 | Class getImageClass(); 29 | 30 | ImageClassifier create(NeuralNetImageClassifier.BuildingBlock block) throws ModelCreationException; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/spi/BinaryClassifierFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.spi; 21 | 22 | import javax.visrec.ml.model.ModelCreationException; 23 | import javax.visrec.ml.classification.BinaryClassifier; 24 | import javax.visrec.ml.classification.NeuralNetBinaryClassifier; 25 | 26 | public interface BinaryClassifierFactory { 27 | 28 | Class getTargetClass(); 29 | 30 | BinaryClassifier create(NeuralNetBinaryClassifier.BuildingBlock block) throws ModelCreationException; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/regression/Regressor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.regression; 21 | 22 | /** 23 | * Regressor tries to predict a numeric value based on a given set of inputs. 24 | * This is a base interface for all regressors. 25 | * Implementations should specify specific type of inputs and outputs that 26 | * specific algorithm expects and returns. 27 | * 28 | * @param type of inputs / features 29 | * @param return/result type 30 | */ 31 | public interface Regressor { 32 | 33 | R predict(I inputs); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/model/InvalidConfigurationException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.model; 21 | 22 | /** 23 | * The Builder is able to attempt to invoke setter methods of the implemented Builder interface. If the 24 | * declared setter method can't be invoked it will throw this exception because the configuration 25 | * doesn't match the method to invoke. 26 | * 27 | */ 28 | public class InvalidConfigurationException extends ModelCreationException { 29 | 30 | InvalidConfigurationException(String msg, Throwable throwable) { 31 | super(msg, throwable); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /.github/workflows/snapshot.yml: -------------------------------------------------------------------------------- 1 | name: snapshot 2 | 3 | # To trigger this workflow manually, you can use the following curl command: 4 | # curl -XPOST -u "USERNAME:PERSONAL_TOKEN" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" https://api.github.com/repos/JavaVisRec/visrec-api/dispatches --data '{"event_type": "snapshot-pub"}' 5 | 6 | on: 7 | repository_dispatch: 8 | types: [snapshot-pub] 9 | pull_request: 10 | branches: 11 | - master 12 | 13 | jobs: 14 | build: 15 | 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | - name: Set up JDK 1.8 21 | uses: actions/setup-java@v1 22 | with: 23 | java-version: 1.8 24 | #settings-path: ${{ github.workspace }} # location for the settings.xml 25 | #server-id: github # Value of the distributionManagement/repository/id field of the pom.xml 26 | - name: Build with Maven 27 | run: ./mvnw package 28 | 29 | - name: Add private key to keyring 30 | run: | 31 | echo "${PRIVATE_KEY}" > private.key 32 | gpg --import --batch private.key 33 | env: 34 | PRIVATE_KEY: ${{ secrets.GPG_SECRET_KEY }} 35 | 36 | - name: Publish to repository 37 | run: ./mvnw deploy -s settings.xml 38 | env: 39 | OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} 40 | OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} 41 | GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} 42 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/classification/MultiClassClassifier.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.classification; 21 | 22 | import java.util.Map; 23 | 24 | /** 25 | * Machine learning algorithms that provide multi class classification. 26 | * Multi class classification assigns input object to one of several possible category/class. 27 | * For example: is it a cat, a dog or a bird? 28 | * 29 | * @param Type of input objects (which are being classified) 30 | * @param Type of classifier return value - type of object which represent category class. 31 | */ 32 | public interface MultiClassClassifier extends Classifier> { 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/data/preprocessing/Scaler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.data.preprocessing; 21 | 22 | import javax.visrec.ml.data.DataSet; 23 | 24 | /** 25 | * Interface to perform scaling of a data set. 26 | * Scaling generally means to change the range of the values, while the shape of the distribution doesn’t change. 27 | * Scaling data set features to range [0, 1] or similar is a common practice 28 | * in order to prepare data for machine learning training and reduce influence of different value ranges among data. 29 | * 30 | * @param Data set class (that implements DataSet interface) 31 | */ 32 | public interface Scaler> { 33 | public void apply(T dataSet); 34 | } 35 | 36 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/eval/Evaluator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.eval; 21 | 22 | /** 23 | * Evaluation method for specified types of machine learning model and data set. 24 | * All evaluators implement this interface. 25 | * 26 | * @param Model class 27 | * @param Data set class 28 | * 29 | * @since 1.0 30 | */ 31 | @FunctionalInterface 32 | public interface Evaluator { 33 | 34 | /** 35 | * Evaluate a model with specified test set. 36 | * 37 | * @param model A model to evaluate 38 | * @param testSet Data to use for evaluation 39 | * @return evaluation metrics for the model for the specified test set 40 | */ 41 | public EvaluationMetrics evaluate(MODEL_CLASS model, DATASET_CLASS testSet); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # visrec-api 2 | ![build](https://github.com/JavaVisRec/visrec-api/workflows/build/badge.svg) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/javax.visrec/visrec-api/badge.svg)](https://maven-badges.herokuapp.com/maven-central/javax.visrec/visrec-api) 3 | 4 | This repo contains specification of standard Visual Recognition API for Java (JSR381) 5 | 6 | The Visual Recognition API JSR #381 is a software development standard recognized by the Java Community Process (JCP) that simplifies and standardizes a set of APIs familiar to Java developers for classifying and recognizing objects in images using machine learning. Beside classes specific for visual recognition tasks, it provides general abstractions for machine learning tasks like classification, regression and data set, and reusable design which can be applied for machine learning systems in other domains. 7 | At the current stage it provides basic hello world examples for supported machine learning tasks (classification and regression) and image classification. 8 | 9 | Reference implementation of specification is available at 10 | 11 | https://github.com/JavaVisRec/visrec-ri/ 12 | 13 | ## Getting Started Guide 14 | For step by step guide and additional info see getting started guide at 15 | 16 | https://github.com/JavaVisRec/visrec-api/wiki/Getting-Started-Guide 17 | 18 | ## Quick Start with Examples 19 | 20 | Introductory examples are available at 21 | 22 | https://github.com/JavaVisRec/jsr381-examples 23 | 24 | Quick start with commands: 25 | 26 | git clone https://github.com/JavaVisRec/jsr381-examples.git 27 | cd jsr381-examples 28 | mvn clean install 29 | mvn exec:java -Dexec.mainClass=jsr381.example.ImplementationExample 30 | 31 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/detection/ObjectDetector.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.detection; 21 | 22 | import java.util.List; 23 | import java.util.Map; 24 | 25 | /** 26 | * Interface to perform object detection in image. 27 | * Returns a map of object labels/classes and corresponding location in image outlined by BoundingBox-es 28 | * 29 | * @param Class used to represent image that will be analyzed 30 | * @since 1.0 31 | */ 32 | @FunctionalInterface 33 | public interface ObjectDetector { 34 | 35 | /** 36 | * Detects object in specified image and returns a map with detected objects in bounding boxes. 37 | * 38 | * @param image image to search for object 39 | * @return a map of multiple {@link BoundingBox} 40 | */ 41 | Map> detectObject(T image); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/classification/AbstractMultiClassClassifier.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.classification; 21 | 22 | import javax.visrec.ml.model.ModelProvider; 23 | 24 | /** 25 | * Skeleton base class for implementations of multi class classifiers. 26 | * 27 | * @param class of machine learning model back-end 28 | * @param type of classifier's input 29 | * @param type of classifier's results/class 30 | */ 31 | public abstract class AbstractMultiClassClassifier implements MultiClassClassifier, ModelProvider { 32 | 33 | private MODEL_CLASS model; 34 | 35 | @Override 36 | public MODEL_CLASS getModel() { 37 | return model; 38 | } 39 | 40 | protected void setModel(MODEL_CLASS model) { 41 | this.model = model; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/model/ModelCreationException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.model; 21 | 22 | /** 23 | * Exception thrown if anything fails in the creation of a classifier. 24 | * 25 | * @since 1.0 26 | */ 27 | public class ModelCreationException extends Exception { 28 | 29 | /** 30 | * Creates a new instance of the exception 31 | * @param message additional message of the cause. 32 | */ 33 | public ModelCreationException(String message) { 34 | super(message); 35 | } 36 | 37 | /** 38 | * Creates a new instance of the exception 39 | * @param message additional message of the cause. 40 | * @param throwable caused by throwable. 41 | */ 42 | public ModelCreationException(String message, Throwable throwable) { 43 | super(message, throwable); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/spi/ImageFactoryService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.spi; 21 | 22 | import javax.visrec.ImageFactory; 23 | import java.util.Optional; 24 | 25 | /** 26 | * The service to locate and find implementations of the {@link ImageFactory} interface. 27 | * 28 | * @since 1.0 29 | */ 30 | public interface ImageFactoryService { 31 | 32 | /** 33 | * Get the {@link ImageFactory} implementation by its image type. 34 | * 35 | * @param imageCls image type in {@link Class} object which is able to 36 | * be processed by the image factory implementation. 37 | * @param image type 38 | * @return {@link Optional} with possible {@link ImageFactory} implementation 39 | * if found. 40 | */ 41 | Optional> getByImageType(Class imageCls); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/spi/ImplementationService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.spi; 21 | 22 | /** 23 | * Returns information about the used implementation of visual recognition API 24 | * 25 | * @since 1.0 26 | */ 27 | public abstract class ImplementationService { 28 | 29 | /** 30 | * Get the name of the implementation 31 | * @return name as {@code String} 32 | */ 33 | public abstract String getName(); 34 | 35 | /** 36 | * Get the version of the implementation 37 | * @return version as {@code String} 38 | */ 39 | public abstract String getVersion(); 40 | 41 | /** 42 | * Returns the name, major and minor version of the implementation 43 | * @return combined information in a {@code String} 44 | */ 45 | @Override 46 | public final String toString() { 47 | return getName() + " " + getVersion(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/classification/ClassificationException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.classification; 21 | 22 | /** 23 | * Exception thrown if anything fails in the execution of a classifier. 24 | * 25 | * @since 1.0 26 | */ 27 | public class ClassificationException extends RuntimeException { 28 | 29 | /** 30 | * Creates a new instance of the exception 31 | * 32 | * @param message additional message of the cause. 33 | */ 34 | public ClassificationException(String message) { 35 | super(message); 36 | } 37 | 38 | /** 39 | * Creates a new instance of the exception 40 | * 41 | * @param message additional message of the cause. 42 | * @param throwable caused by throwable. 43 | */ 44 | public ClassificationException(String message, Throwable throwable) { 45 | super(message, throwable); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /.github/workflows/staging.yml: -------------------------------------------------------------------------------- 1 | name: staging 2 | 3 | on: 4 | # To trigger this workflow manually, you can use the following curl command: 5 | # curl -XPOST -u "USERNAME:PERSONAL_TOKEN" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" https://api.github.com/repos/JavaVisRec/visrec-api/dispatches --data '{"event_type": "staging-pub"}' 6 | 7 | # Make sure you create your personal token with repo access. Follow steps in 8 | # https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line 9 | # to create your personal token. 10 | 11 | # Special thanks to AWS Labs & AWS DJL project for this approach 12 | repository_dispatch: 13 | types: [staging-pub] 14 | 15 | 16 | jobs: 17 | build: 18 | 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | - name: Set up JDK 1.8 24 | uses: actions/setup-java@v1 25 | with: 26 | java-version: 1.8 27 | #settings-path: ${{ github.workspace }} # location for the settings.xml 28 | #server-id: github # Value of the distributionManagement/repository/id field of the pom.xml 29 | - name: Build with Maven 30 | run: ./mvnw package 31 | 32 | - name: Add private key to keyring 33 | run: | 34 | echo "${PRIVATE_KEY}" > private.key 35 | gpg --import --batch private.key 36 | env: 37 | PRIVATE_KEY: ${{ secrets.GPG_SECRET_KEY }} 38 | 39 | - name: Publish to repository 40 | run: | 41 | sed -i "s/-SNAPSHOT//g" pom.xml 42 | ./mvnw deploy -s settings.xml 43 | env: 44 | OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} 45 | OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} 46 | GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} 47 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/spi/ServiceRegistry.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.spi; 21 | 22 | import java.util.HashMap; 23 | import java.util.Iterator; 24 | import java.util.Map; 25 | 26 | /** 27 | * Registry for all ML algorithms provided by this implementation. 28 | * 29 | */ 30 | public class ServiceRegistry { 31 | 32 | private final Map, Object> providers = new HashMap(); 33 | 34 | public void registerServiceProvider(Class service, T provider) { 35 | providers.put(service, provider); 36 | } 37 | 38 | public void deregisterServiceProvider(Class service, T provider) { 39 | providers.remove(service, provider); 40 | } 41 | 42 | public Iterator getAllProviders() { 43 | return providers.values().iterator(); 44 | } 45 | 46 | public T getProvider(Class service) { 47 | return service.cast(providers.get(service)); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/classification/LogisticRegression.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.classification; 21 | 22 | import java.util.Objects; 23 | import javax.visrec.ml.model.ModelProvider; 24 | 25 | /** 26 | * This class performs basic binary classification - mapping of specified input to true/false with probability 27 | * using logistic regression algorithm. 28 | * Subclasses should use specific logistic regression implementation to provide that functionality. 29 | * 30 | * @param Implementation class of underlying machine learning model 31 | */ 32 | public abstract class LogisticRegression implements BinaryClassifier, ModelProvider { 33 | 34 | private MODEL_CLASS model; 35 | 36 | @Override 37 | public MODEL_CLASS getModel() { 38 | return model; 39 | } 40 | 41 | protected final void setModel(MODEL_CLASS model) { 42 | this.model = Objects.requireNonNull(model, "Model cannot be null!"); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/eval/RegressionMetrics.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | 21 | package javax.visrec.ml.eval; 22 | 23 | /** 24 | * Commonly used metrics to estimate how good machine learning model solves some regression task. 25 | * This class is typed wrapper for EvaluationMetrics which uses map to store metrics, 26 | * and allows storing and accessing of custom metrics. 27 | */ 28 | public class RegressionMetrics extends EvaluationMetrics { 29 | 30 | /** 31 | * Portion of variation explained. 32 | * How much better is this than the average. 33 | * @return 34 | */ 35 | public double getRSquared() { 36 | return get(R_SQUARED); 37 | } 38 | 39 | public double getResidualSquareSum() { 40 | return get(RESIDUAL_SQUARE_SUM); 41 | } 42 | 43 | public double getFstat() { 44 | return get(F_STAT); 45 | } 46 | 47 | public double getMeanSquaredError() { 48 | return get(MEAN_SQUARED_ERROR); 49 | } 50 | 51 | public double getResidualStandardError() { 52 | return get(RESIDUAL_STANDARD_ERROR); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/classification/Classifiable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.classification; 21 | 22 | /** 23 | * Classes that implement this interface enable direct classification of Java objects, 24 | * no need to manually convert to data structures used internally by ML. 25 | * 26 | * This interface simplifies usage and integration of machine learning based classifiers with Java objects. 27 | * It should be implemented by classes whose objects we want to be able to classify. 28 | * Instances of classes that implement this interface can be used as examples 29 | * to build machine learning based classifiers. 30 | * Typical implementation scenario is to wrap domain specific class and implement this interface. 31 | * 32 | * Classifiable can be classified by the Classifier (with the same T and C) 33 | * 34 | * @param Type of input for classifier 35 | * @param Type of categories/labels (could be anything like enum, String, Integer or user defined class) 36 | */ 37 | public interface Classifiable { 38 | 39 | /** 40 | * Returns input for classifier. 41 | * Implementation of this method should convert attributes of an object for specific classifier. 42 | * @return 43 | */ 44 | T getClassifierInput(); 45 | 46 | /** 47 | * Returns target class for classifier. 48 | * @return 49 | */ 50 | C getTargetClass(); 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/classification/ImageClassifier.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.classification; 21 | 22 | 23 | import java.io.InputStream; 24 | import java.nio.file.Path; 25 | import java.util.Map; 26 | 27 | /** 28 | * Classifier interface specialized in image classification 29 | * 30 | * @param type of input objects to classify (eg. User, Product, Transaction, Image, etc.) 31 | * @since 1.0 32 | */ 33 | public interface ImageClassifier extends Classifier> { 34 | 35 | /** 36 | * Classify the input and get a map of classification results as output 37 | * 38 | * @param input {@link Path} to use as input 39 | * @return {@code Map} with key as classification label and with value as accuracy percentage of likelihood 40 | * @throws ClassificationException if the file couldn't be found or classified 41 | */ 42 | Map classify(Path input) throws ClassificationException; 43 | 44 | /** 45 | * Classify the input and get a map of classification results as output 46 | * 47 | * @param input {@link InputStream} to use as input 48 | * @return {@code Map} with key as classification label and with value as accuracy percentage of likelihood 49 | * @throws ClassificationException if input couldn't be classified 50 | */ 51 | Map classify(InputStream input) throws ClassificationException; 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/classification/Classifier.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.classification; 21 | 22 | /** 23 | * Generic classifier interface, that all classifiers should implement, and 24 | * it provides a method to classify given instances of some class. 25 | * Each category/type has corresponding label or class, which can be String, Enum or custom user defined class. 26 | * Machine learning based classifier can learn from examples how to determine a 27 | * category of an input object with high degree of confidence. 28 | * 29 | *

30 | * Implementations should specify input type of instances that are classified, 31 | * and type of the returned vales . 32 | *

33 | * Usually implementations predict category of instances with some probability, 34 | * and cannot guarantee 100% accuracy. 35 | * 36 | * @param type of input objects to classify (eg. User, Product, Transaction, Image, etc.) 37 | * @param type of classification result (String, Enum, custom class). 38 | * @see BinaryClassifier 39 | * @see MultiClassClassifier 40 | * @see ImageClassifier 41 | * @see Classifiable 42 | * @since 1.0 43 | */ 44 | @FunctionalInterface 45 | public interface Classifier { 46 | 47 | /** 48 | * Classifies specified input instance of type T and returns classification results of type R. 49 | * 50 | * @param input some instance to classify 51 | * @return classification results for the specified instance 52 | * @throws ClassificationException if the input could not be classified 53 | */ 54 | R classify(T input) throws ClassificationException; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/detection/BoundingBox.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.detection; 21 | 22 | /** 23 | * This class represents a bounding box over image at specified position, dimensions, label and score. 24 | * 25 | * @since 1.0 26 | */ 27 | public class BoundingBox { 28 | private int id; 29 | private final float x, y, width, height; 30 | private final String label; 31 | private final float score; 32 | 33 | 34 | public BoundingBox(String label, float score, int x, int y, float width, float height) { 35 | this.label =label; 36 | this.score = score; 37 | this.x = x; 38 | this.y = y; 39 | this.width = width; 40 | this.height = height; 41 | } 42 | 43 | public float getX() { 44 | return x; 45 | } 46 | 47 | public float getY() { 48 | return y; 49 | } 50 | 51 | public float getWidth() { 52 | return width; 53 | } 54 | 55 | public float getHeight() { 56 | return height; 57 | } 58 | 59 | public int getId() { 60 | return id; 61 | } 62 | 63 | public void setId(int id) { 64 | this.id = id; 65 | } 66 | 67 | public float getScore() { 68 | return score; 69 | } 70 | 71 | public String getLabel() { 72 | return label; 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return "BoundingBox{" + "id=" + id + ", x=" + x + ", y=" + y + ", width=" + width + ", height=" + height + ", label=" + label + ", score=" + score + '}'; 78 | } 79 | 80 | 81 | 82 | } -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/data/Column.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.data; 21 | 22 | /** 23 | * Column in a data set. 24 | * 25 | * @see DataSet 26 | */ 27 | public class Column { 28 | private String name; 29 | private Type type; 30 | private boolean isTarget; 31 | 32 | public Column(String name) { 33 | this.name = name; 34 | this.type = null; 35 | this.isTarget = false; 36 | } 37 | 38 | public Column(String name, Type type) { 39 | this.name = name; 40 | this.type = type; 41 | this.isTarget = false; 42 | } 43 | 44 | public Column(String name, Type type, boolean isTarget) { 45 | this.name = name; 46 | this.type = type; 47 | this.isTarget = isTarget; 48 | } 49 | 50 | public String getName() { 51 | return name; 52 | } 53 | 54 | public Type getType() { 55 | return type; 56 | } 57 | 58 | public boolean isTarget() { 59 | return isTarget; 60 | } 61 | 62 | public void setName(String name) { 63 | this.name = name; 64 | } 65 | 66 | public void setType(Type type) { 67 | this.type = type; 68 | } 69 | 70 | public void setAsTarget(boolean isTarget) { 71 | this.isTarget = isTarget; 72 | } 73 | 74 | /** 75 | * Column data type 76 | */ 77 | public static enum Type { 78 | DECIMAL, INTEGER, BINARY, ENUM, STRING; 79 | } 80 | } -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ImageFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec; 21 | 22 | import java.io.IOException; 23 | import java.io.InputStream; 24 | import java.net.URL; 25 | import java.nio.file.Path; 26 | 27 | /** 28 | * This interface provides a standard way to get/read different(specified) kinds of image from file, url or input stream. 29 | * 30 | * @param the type of object to be returned after getting image from {@link Path}, {@link URL} or {@link InputStream} 31 | * @since 1.0 32 | */ 33 | public interface ImageFactory { 34 | 35 | /** 36 | * Retrieve the source through a {@link Path} object and transform it into T. 37 | * 38 | * @param path The source file. 39 | * @return T object. 40 | * @throws IOException If the file I/O went wrong or couldn't transform 41 | * the source into a T object. 42 | */ 43 | T getImage(Path path) throws IOException; 44 | 45 | /** 46 | * Retrieve the source through a {@link URL} object and transform it into T. 47 | * 48 | * @param file The source. 49 | * @return T object. 50 | * @throws IOException If the I/O went wrong or couldn't transform 51 | * the source into a T object. 52 | */ 53 | T getImage(URL file) throws IOException; 54 | 55 | /** 56 | * Retrieve the source through an {@link InputStream} object and transform it into T. 57 | * 58 | * @param file The source. 59 | * @return T object. 60 | * @throws IOException If the I/O went wrong or couldn't transform 61 | * the source into a T object. 62 | */ 63 | T getImage(InputStream file) throws IOException; 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/eval/ClassificationMetrics.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.eval; 21 | 22 | /** 23 | * Commonly used metrics to estimate how good machine learning model solves some classification task. 24 | */ 25 | public class ClassificationMetrics extends EvaluationMetrics { 26 | 27 | /** 28 | * The percent of correct predictions of a classifier in total. 29 | * Tells how often the classifier is correct for some given test set. 30 | * Note that accuracy can be a misleading metric for imbalanced data sets. 31 | * 32 | * Formula: Accuracy = (TP+TN) / (TP+TN+FP+FN) 33 | * 34 | * @return classification accuracy metric 35 | */ 36 | public double getAccuracy() { 37 | return get(ACCURACY); 38 | } 39 | 40 | /** 41 | * The percent of correct positive predictions. 42 | * This metrics answers the question: when classifier gives positive prediction, how often is it correct? 43 | * Formula: Precision = TP/(TP+FP) 44 | * 45 | * @return classification precision metric 46 | */ 47 | public double getPrecision() { 48 | return get(PRECISION); 49 | } 50 | 51 | /** 52 | * The percent of the positive examples that were not recognized by the classifier. 53 | * This metric answers the question: when it is actually positive class, how often does it give positive prediction 54 | * Formula: Recall = TP / (TP+FN) 55 | * 56 | * @return classification recall 57 | */ 58 | public double getRecall() { 59 | return get(RECALL); 60 | } 61 | 62 | /** 63 | * The mean/balance of the recall and precision metrics. 64 | * 65 | * @return classification f score 66 | */ 67 | public double getF1score() { 68 | return get(F1SCORE); 69 | } 70 | 71 | } -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/regression/SimpleLinearRegression.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.regression; 21 | 22 | import java.util.Objects; 23 | import javax.visrec.ml.model.ModelProvider; 24 | 25 | /** 26 | * Simple linear regression finds the best possible straight line that tries to roughly describe given training set. 27 | * Mathematical formula for linear regression is: prediction = slope * x + intercept 28 | * which is a formula for linear function (straight line) and that's where the names comes from. 29 | * 30 | * @param Implementation class of the background model 31 | */ 32 | public abstract class SimpleLinearRegression implements Regressor, ModelProvider { 33 | 34 | private MODEL_CLASS model; 35 | 36 | @Override 37 | public MODEL_CLASS getModel() { 38 | return model; 39 | } 40 | 41 | protected final void setModel(MODEL_CLASS model) { 42 | this.model = Objects.requireNonNull(model, "Model cannot bu null!"); 43 | } 44 | 45 | @Override 46 | public abstract Float predict(Float input); 47 | 48 | /** 49 | * Slope parameter of the model tells how much on average output change when input changes by one. 50 | * 51 | * If it is zero there is no linear dependency between input and output, and data is probably scattered. 52 | * If it is less then one output grows slower then input. 53 | * If it is greater than one, then output is growing faster than input. 54 | * If its negative, then output is lowering as input grows. 55 | * 56 | * @return slope of the line produced by linear regression. 57 | */ 58 | public abstract float getSlope(); 59 | 60 | /** 61 | * Intercept tells us the value of prediction when input is zero. 62 | * 63 | * @return 64 | */ 65 | public abstract float getIntercept(); 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/model/ModelBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.model; 21 | 22 | import java.lang.reflect.InvocationTargetException; 23 | import java.lang.reflect.Method; 24 | import java.util.Map; 25 | 26 | /** 27 | * Generic model builder interface, that all builders for machine learning algorithms implement. 28 | * 29 | * @param type of the object to be returned by the builder. 30 | * @since 1.0 31 | */ 32 | public interface ModelBuilder { 33 | 34 | /** 35 | * Builds and returns an object using properties set using available builder methods. 36 | * 37 | * @return object specified by the builder to build 38 | * @throws javax.visrec.ml.model.ModelCreationException 39 | */ 40 | T build() throws ModelCreationException; 41 | 42 | /** 43 | * Builds an object using properties from the specified input argument 44 | * 45 | * @param configuration properties for the builder, a map of key, value pairs. 46 | * @return object specified by the builder to build 47 | * @throws javax.visrec.ml.model.ModelCreationException 48 | */ 49 | default T build(Map configuration) throws ModelCreationException { 50 | ModelBuilder thizz = this; 51 | Method[] methods = this.getClass().getDeclaredMethods(); 52 | for (Method method : methods) { 53 | if (!method.getName().equals("build") && method.getParameterCount() == 1 54 | && configuration.containsKey(method.getName())) { 55 | try { 56 | Object obj = method.invoke(thizz, configuration.get(method.getName())); 57 | if (thizz.getClass().isInstance(obj)) { 58 | thizz = (ModelBuilder) thizz.getClass().cast(obj); 59 | } 60 | } catch (IllegalAccessException | InvocationTargetException | IllegalArgumentException e) { 61 | throw new InvalidConfigurationException("Couldn't invoke '" + method.getName() + "'", e); 62 | } 63 | } 64 | } 65 | return thizz.build(); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/classification/EnsambleClassifier.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.classification; 21 | 22 | import java.util.ArrayList; 23 | import java.util.HashMap; 24 | import java.util.List; 25 | import java.util.Map; 26 | 27 | /** 28 | * EnsambleClassifier is a group of classifiers that provide common 29 | * classification result, which gives better accuracy then each individual 30 | * classifier. Usually average or most frequent answer is used as a final result. 31 | * 32 | * @param The input type which is to be classified. 33 | * @param Return type of the classifier. 34 | * @since 1.0 35 | */ 36 | public final class EnsambleClassifier implements Classifier { 37 | 38 | private final Map> classifiers = new HashMap<>(); 39 | 40 | @Override 41 | public R classify(T input) { 42 | List results = new ArrayList<>(); 43 | Map freqCount = new HashMap<>(); 44 | int maxFreq = 0; 45 | R maxClass = null; 46 | for (Map.Entry> classifier : classifiers.entrySet()) { 47 | R result = classifier.getValue().classify(input); 48 | results.add(result); 49 | // what if it is a binary classifier ? it should return class name with corresponding probability 50 | // if (instanceof BinaryClassifier) deal with binary classifiers using if statement 51 | if (freqCount.containsKey(result)) { 52 | freqCount.put(result.toString(), freqCount.get(result.toString())+1); 53 | } else { 54 | freqCount.put(result.toString(), 1); 55 | } 56 | 57 | if (freqCount.get(result.toString()) > maxFreq) { 58 | maxFreq = freqCount.get(result.toString()); 59 | maxClass = result; 60 | } 61 | } 62 | 63 | return maxClass; 64 | } 65 | 66 | public EnsambleClassifier addClassifier(String classifierId, Classifier classifier) { 67 | classifiers.put(classifierId, classifier); 68 | return this; 69 | } 70 | 71 | public Classifier getClassifier(String classiferId) { 72 | return classifiers.get(classiferId); 73 | } 74 | 75 | public void remove(String classifierId) { 76 | classifiers.remove(classifierId); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/eval/EvaluationMetrics.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | 21 | package javax.visrec.ml.eval; 22 | 23 | import java.util.HashMap; 24 | 25 | /** 26 | * Wrapper for constants and values for classifier and regressor evaluation metrics. 27 | * 28 | */ 29 | public class EvaluationMetrics { 30 | 31 | /** 32 | * Mean value of sum of squared errors. 33 | * Errors are squared in order to better explain variability, and take into account positive and negative errors. 34 | * Regression metrics 35 | */ 36 | public final static String MEAN_ABSOLUTE_ERROR = "MeanAbsoluteError"; 37 | public final static String MEAN_SQUARED_ERROR = "MeanSquaredError"; 38 | public final static String ROOT_MEAN_SQUARED_ERROR = "RootMeanSquaredError"; 39 | public final static String RESIDUAL_SQUARE_SUM = "ResidualSquareSum"; // RSS 40 | 41 | /** 42 | * Estimation of standard deviation of prediction errors for some given data set. 43 | * Smaller is better. 44 | */ 45 | public final static String RESIDUAL_STANDARD_ERROR = "ResidualStandardError"; 46 | 47 | /** 48 | * Percent of variation explained by the regression model. 49 | * 1 is good , 0 is bad, bigger is better. 50 | */ 51 | public final static String R_SQUARED = "RSquared"; 52 | 53 | /** 54 | * Is there a relationship between inputs and predictions(outputs) at all. 55 | * If there is a relationship, this value is greater then 1. 56 | * When there is now relationship, this value is around 1. 57 | */ 58 | public final static String F_STAT = "FStatistics"; 59 | 60 | // Classification Metrics 61 | public final static String ACCURACY = "Accuracy"; 62 | public final static String PRECISION = "Precision"; 63 | public final static String RECALL = "Recall"; 64 | public final static String F1SCORE = "F1Score"; 65 | 66 | // Hold values of relevant evaluation metrics 67 | private final HashMap values = new HashMap(); 68 | 69 | private final static HashMap description = new HashMap(); 70 | static { 71 | description.put(ACCURACY, "How often is classifier correct in total"); 72 | description.put(PRECISION, "How often is classifier correct when it gives positive prediction"); 73 | description.put(RECALL, "When it is actually positive class, how often does it give positive prediction"); 74 | description.put(F1SCORE, "Harmonic average (balance) of precision and recall"); 75 | } 76 | 77 | 78 | public float get(String key) { 79 | return values.get(key); 80 | } 81 | 82 | public void set(String key, float value) { 83 | values.put(key, value); 84 | } 85 | 86 | @Override 87 | public String toString() { 88 | StringBuilder sb = new StringBuilder(); 89 | values.entrySet().stream().forEach((e) -> { sb.append(e.getKey()).append(": ") 90 | .append(e.getValue()); 91 | if (description.get(e.getKey())!=null) 92 | sb.append(" (") 93 | .append(description.get(e.getKey())) 94 | .append(")"); 95 | sb.append(System.lineSeparator()); 96 | }); 97 | return sb.toString(); 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/spi/ClassifierFactoryService.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.spi; 21 | 22 | import javax.visrec.ml.model.ModelCreationException; 23 | import javax.visrec.ml.classification.*; 24 | import java.util.HashMap; 25 | import java.util.Map; 26 | import java.util.ServiceLoader; 27 | 28 | /** 29 | * Service to provide the correct {@link Classifier} implementation. 30 | * 31 | * @since 1.0 32 | */ 33 | public final class ClassifierFactoryService { 34 | 35 | private Map, ImageClassifierFactory> imageClassifierFactories; 36 | private Map, BinaryClassifierFactory> binaryClassifierFactories; 37 | 38 | private static ClassifierFactoryService instance; 39 | static ClassifierFactoryService getInstance() { 40 | if (instance == null) { 41 | instance = new ClassifierFactoryService(); 42 | } 43 | return instance; 44 | } 45 | 46 | private ClassifierFactoryService() { 47 | // Prevent instantiation 48 | } 49 | 50 | /** 51 | * Creates a new {@link ImageClassifier} by providing the {@link NeuralNetImageClassifier.BuildingBlock} to tune 52 | * the implementation's image classifier. 53 | * 54 | * @param block {@link NeuralNetImageClassifier.BuildingBlock} is provided to tune the building of the image classifier. 55 | * @return {@link ImageClassifier} 56 | * @throws ModelCreationException if the classifier can not be created due to any reason. 57 | */ 58 | public ImageClassifier createNeuralNetImageClassifier(NeuralNetImageClassifier.BuildingBlock block) throws ModelCreationException { 59 | if (imageClassifierFactories == null) { 60 | imageClassifierFactories = new HashMap<>(); 61 | for (ImageClassifierFactory classifierCreator : ServiceLoader.load(ImageClassifierFactory.class)) { 62 | imageClassifierFactories.put(classifierCreator.getImageClass(), classifierCreator); 63 | } 64 | } 65 | 66 | ImageClassifierFactory creator = imageClassifierFactories.get(block.getInputClass()); 67 | if (creator == null) { 68 | throw new ModelCreationException("Unsupported image class"); 69 | } 70 | 71 | @SuppressWarnings("unchecked") 72 | ImageClassifierFactory castedCreator = (ImageClassifierFactory) creator; 73 | return castedCreator.create(block); 74 | } 75 | 76 | /** 77 | * Creates a new {@link BinaryClassifier} by providing the {@link NeuralNetBinaryClassifier.BuildingBlock} to tune 78 | * the implementation's binary classifier. 79 | * 80 | * @param block {@link NeuralNetBinaryClassifier.BuildingBlock} is provided to tune the building of the binary classifier. 81 | * @return {@link BinaryClassifier} 82 | * @throws ModelCreationException if the classifier can not be created due to any reason. 83 | */ 84 | public BinaryClassifier createNeuralNetBinaryClassifier(NeuralNetBinaryClassifier.BuildingBlock block) throws ModelCreationException { 85 | if (binaryClassifierFactories == null) { 86 | binaryClassifierFactories = new HashMap<>(); 87 | for (BinaryClassifierFactory classifierCreator : ServiceLoader.load(BinaryClassifierFactory.class)) { 88 | binaryClassifierFactories.put(classifierCreator.getTargetClass(), classifierCreator); 89 | } 90 | } 91 | 92 | BinaryClassifierFactory creator = binaryClassifierFactories.get(block.getInputClass()); 93 | if (creator == null) { 94 | throw new ModelCreationException("Unsupported target class"); 95 | } 96 | 97 | @SuppressWarnings("unchecked") 98 | BinaryClassifierFactory castedCreator = (BinaryClassifierFactory) creator; 99 | return castedCreator.create(block); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/data/BasicDataSet.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.data; 21 | 22 | import java.util.ArrayList; 23 | import java.util.Arrays; 24 | import java.util.List; 25 | import java.util.stream.Collectors; 26 | 27 | /** 28 | * Basic implementation of {@link DataSet} interface. 29 | * Provides a list of data set items with column info. 30 | * 31 | * @param Type of elements in data set 32 | */ 33 | public class BasicDataSet implements DataSet { 34 | 35 | /** 36 | * List of data set items in this data set. 37 | */ 38 | protected List items; 39 | 40 | /** 41 | * List of data set columns. Each column provides info about it's name, type. 42 | */ 43 | private List columns = new ArrayList<>(); 44 | 45 | protected BasicDataSet() { 46 | items = new ArrayList<>(); 47 | } 48 | 49 | /** 50 | * Creates an instance of {@link BasicDataSet} 51 | * @param cols columns of the data set. 52 | */ 53 | public BasicDataSet(Column... cols) { 54 | this.columns = new ArrayList(); 55 | Arrays.stream(cols).forEach(col->columns.add(col)); 56 | items = new ArrayList<>(); 57 | } 58 | 59 | public BasicDataSet(String... cols) { 60 | this.columns = new ArrayList(); 61 | Arrays.stream(cols).forEach(col->columns.add(new Column(col))); 62 | items = new ArrayList<>(); 63 | } 64 | 65 | /** 66 | * Creates an instance of {@link BasicDataSet} 67 | * @param elements items of the data set. 68 | */ 69 | public BasicDataSet(List elements) { 70 | this.items = elements; 71 | } 72 | 73 | @Override 74 | public List getItems() { 75 | return items; 76 | } 77 | 78 | @Override 79 | public List getColumns() { 80 | return columns; 81 | } 82 | 83 | public void setColumnNames(String[] columnNames) { 84 | for(int i=0; ic.setAsTarget(false)); 100 | 101 | for(int idx : targetIdxs) { 102 | columns.get(idx).setAsTarget(true); 103 | } 104 | } 105 | 106 | public void setAsTargetColumns(String... targetColNames) { 107 | columns.stream().forEach( c->c.setAsTarget(false)); 108 | 109 | columns.stream().forEach(col-> { 110 | for(String name : targetColNames) { 111 | if (col.getName().equals(name)) col.setAsTarget(true); 112 | } 113 | }); 114 | } 115 | 116 | @Override 117 | public String[] getTargetColumnsNames() { 118 | List targetLabels = columns.stream() 119 | .filter((col) -> col.isTarget()) 120 | .map((col) -> col.getName() ) 121 | .collect(Collectors.toList()); 122 | return targetLabels.toArray(new String[0]); 123 | } 124 | 125 | 126 | // remove? 127 | @Override 128 | public DataSet[] split(double... parts) { 129 | throw new UnsupportedOperationException("Not supported yet."); 130 | } 131 | 132 | @Override 133 | public void setColumns(List columns) { 134 | this.columns = columns; 135 | } 136 | 137 | 138 | } -------------------------------------------------------------------------------- /.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import java.net.*; 17 | import java.io.*; 18 | import java.nio.channels.*; 19 | import java.util.Properties; 20 | 21 | public class MavenWrapperDownloader { 22 | 23 | private static final String WRAPPER_VERSION = "0.5.6"; 24 | /** 25 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 26 | */ 27 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 28 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 29 | 30 | /** 31 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 32 | * use instead of the default one. 33 | */ 34 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 35 | ".mvn/wrapper/maven-wrapper.properties"; 36 | 37 | /** 38 | * Path where the maven-wrapper.jar will be saved to. 39 | */ 40 | private static final String MAVEN_WRAPPER_JAR_PATH = 41 | ".mvn/wrapper/maven-wrapper.jar"; 42 | 43 | /** 44 | * Name of the property which should be used to override the default download url for the wrapper. 45 | */ 46 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 47 | 48 | public static void main(String args[]) { 49 | System.out.println("- Downloader started"); 50 | File baseDirectory = new File(args[0]); 51 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 52 | 53 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 54 | // wrapperUrl parameter. 55 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 56 | String url = DEFAULT_DOWNLOAD_URL; 57 | if(mavenWrapperPropertyFile.exists()) { 58 | FileInputStream mavenWrapperPropertyFileInputStream = null; 59 | try { 60 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 61 | Properties mavenWrapperProperties = new Properties(); 62 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 63 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 64 | } catch (IOException e) { 65 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 66 | } finally { 67 | try { 68 | if(mavenWrapperPropertyFileInputStream != null) { 69 | mavenWrapperPropertyFileInputStream.close(); 70 | } 71 | } catch (IOException e) { 72 | // Ignore ... 73 | } 74 | } 75 | } 76 | System.out.println("- Downloading from: " + url); 77 | 78 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 79 | if(!outputFile.getParentFile().exists()) { 80 | if(!outputFile.getParentFile().mkdirs()) { 81 | System.out.println( 82 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 83 | } 84 | } 85 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 86 | try { 87 | downloadFileFromURL(url, outputFile); 88 | System.out.println("Done"); 89 | System.exit(0); 90 | } catch (Throwable e) { 91 | System.out.println("- Error downloading"); 92 | e.printStackTrace(); 93 | System.exit(1); 94 | } 95 | } 96 | 97 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 98 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 99 | String username = System.getenv("MVNW_USERNAME"); 100 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 101 | Authenticator.setDefault(new Authenticator() { 102 | @Override 103 | protected PasswordAuthentication getPasswordAuthentication() { 104 | return new PasswordAuthentication(username, password); 105 | } 106 | }); 107 | } 108 | URL website = new URL(urlString); 109 | ReadableByteChannel rbc; 110 | rbc = Channels.newChannel(website.openStream()); 111 | FileOutputStream fos = new FileOutputStream(destination); 112 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 113 | fos.close(); 114 | rbc.close(); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/classification/NeuralNetBinaryClassifier.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.classification; 21 | 22 | import javax.visrec.ml.model.ModelCreationException; 23 | import javax.visrec.spi.ServiceProvider; 24 | import java.nio.file.Path; 25 | 26 | public interface NeuralNetBinaryClassifier extends BinaryClassifier { 27 | 28 | static NeuralNetBinaryClassifier.Builder builder() { 29 | return new NeuralNetBinaryClassifier.Builder<>(); 30 | } 31 | 32 | class BuildingBlock { 33 | private Class inputCls; 34 | private int inputsNum; 35 | private int[] hiddenLayers; 36 | private float maxError; 37 | private int maxEpochs; 38 | private float learningRate; 39 | private Path trainingPath; 40 | private float threshold; 41 | 42 | private BuildingBlock() { 43 | } 44 | 45 | public Class getInputClass() { 46 | return inputCls; 47 | } 48 | 49 | public int getInputsNum() { 50 | return inputsNum; 51 | } 52 | 53 | public int[] getHiddenLayers() { 54 | return hiddenLayers; 55 | } 56 | 57 | public float getMaxError() { 58 | return maxError; 59 | } 60 | 61 | public int getMaxEpochs() { 62 | return maxEpochs; 63 | } 64 | 65 | public float getLearningRate() { 66 | return learningRate; 67 | } 68 | 69 | public Path getTrainingPath() { 70 | return trainingPath; 71 | } 72 | 73 | public float getThreshold() { 74 | return threshold; 75 | } 76 | 77 | 78 | 79 | private static BuildingBlock copyWithNewTargetClass(BuildingBlock block, Class cls) { 80 | BuildingBlock newBlock = new BuildingBlock<>(); 81 | newBlock.inputCls = cls; 82 | newBlock.inputsNum = block.inputsNum; 83 | newBlock.hiddenLayers = block.hiddenLayers; 84 | newBlock.maxError = block.maxError; 85 | newBlock.maxEpochs = block.maxEpochs; 86 | newBlock.learningRate = block.learningRate; 87 | newBlock.trainingPath = block.trainingPath; 88 | newBlock.threshold = block.threshold; 89 | return newBlock; 90 | } 91 | } 92 | 93 | class Builder implements javax.visrec.ml.model.ModelBuilder> { 94 | 95 | private NeuralNetBinaryClassifier.BuildingBlock block; 96 | 97 | private Builder() { 98 | this(new NeuralNetBinaryClassifier.BuildingBlock<>()); 99 | } 100 | 101 | private Builder(BuildingBlock block) { 102 | this.block = block; 103 | } 104 | 105 | public Builder inputClass(Class cls) { 106 | BuildingBlock newBlock = BuildingBlock.copyWithNewTargetClass(block, cls); 107 | return new Builder<>(newBlock); 108 | } 109 | 110 | public Builder inputsNum(int inputsNum) { 111 | block.inputsNum = inputsNum; 112 | return this; 113 | } 114 | 115 | public Builder hiddenLayers(int... hiddenLayers) { 116 | block.hiddenLayers = hiddenLayers; 117 | return this; 118 | } 119 | 120 | public Builder maxError(float maxError) { 121 | block.maxError = maxError; 122 | return this; 123 | } 124 | 125 | public Builder maxEpochs(int maxEpochs) { 126 | block.maxEpochs = maxEpochs; 127 | return this; 128 | } 129 | 130 | public Builder learningRate(float learningRate) { 131 | block.learningRate = learningRate; 132 | return this; 133 | } 134 | 135 | public Builder trainingPath(Path trainingPath) { 136 | block.trainingPath = trainingPath; 137 | return this; 138 | } 139 | 140 | public Builder threshold(float threshold) { 141 | block.threshold = threshold; 142 | return this; 143 | } 144 | 145 | 146 | 147 | public NeuralNetBinaryClassifier.BuildingBlock getBuildingBlock() { 148 | return block; 149 | } 150 | 151 | public BinaryClassifier build() throws ModelCreationException { 152 | return ServiceProvider.current().getClassifierFactoryService().createNeuralNetBinaryClassifier(block); 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | javax.visrec 6 | visrec-api 7 | 1.0.5-SNAPSHOT 8 | jar 9 | 10 | javax.visrec:visrec-api 11 | Visual recognition specification for Java 12 | https://github.com/JavaVisRec/visrec-api 13 | 14 | 15 | 16 | The Apache License, Version 2.0 17 | http://www.apache.org/licenses/LICENSE-2.0.txt 18 | 19 | 20 | 21 | 22 | 23 | Zoran Sevarac 24 | sevarac@gmail.com 25 | 26 | 27 | Jyothiprasad Buddha 28 | jyothiprasadb@gmail.com 29 | 30 | 31 | Kevin Berendsen 32 | berendsen.kevin@gmail.com 33 | 34 | 35 | 36 | 37 | scm:git:git://github.com/JavaVisRec/visrec-api.git 38 | scm:git:ssh://github.com:JavaVisRec/visrec-api.git 39 | http://github.com/JavaVisRec/visrec-api/tree/master 40 | 41 | 42 | 43 | UTF-8 44 | 1.8 45 | 1.8 46 | 47 | 48 | 49 | 50 | junit 51 | junit 52 | 4.0 53 | test 54 | 55 | 56 | 57 | 58 | 59 | ossrh 60 | https://oss.sonatype.org/content/repositories/snapshots 61 | 62 | 63 | ossrh 64 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 65 | 66 | 67 | 68 | 69 | 70 | 71 | org.apache.maven.plugins 72 | maven-gpg-plugin 73 | 1.5 74 | 75 | 76 | sign-artifacts 77 | deploy 78 | 79 | sign 80 | 81 | 82 | 83 | 84 | --pinentry-mode 85 | loopback 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | org.sonatype.plugins 94 | nexus-staging-maven-plugin 95 | 1.6.7 96 | true 97 | 98 | ossrh 99 | https://oss.sonatype.org/ 100 | false 101 | 102 | 103 | 104 | 105 | true 106 | org.apache.maven.plugins 107 | maven-javadoc-plugin 108 | 3.1.0 109 | 110 | true 111 | none 112 | 113 | 114 | 115 | attach-javadoc 116 | 117 | jar 118 | 119 | 120 | 121 | 122 | 123 | 124 | org.apache.maven.plugins 125 | maven-source-plugin 126 | 2.2.1 127 | 128 | 129 | attach-sources 130 | 131 | jar-no-fork 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/spi/ServiceProvider.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.spi; 21 | 22 | import java.util.*; 23 | 24 | /* 25 | * Special thanks to Werner Keil and Martin Desruisseaux for the proven design of a service provider. 26 | * The ServiceProvider of JSR381 is heavily inspired by JSR 363/385. 27 | */ 28 | 29 | /** 30 | * The ServiceProvider is the centralized provider to provide API scoped services. 31 | * 32 | * @since 1.0 33 | */ 34 | public abstract class ServiceProvider { 35 | 36 | /** The lock to populate and mutate the providers list. */ 37 | private static final Object LOCK = new Object(); 38 | 39 | private static List providers; 40 | 41 | protected ServiceProvider() { 42 | // Prevent instantiation, only allowed by subclasses. 43 | } 44 | 45 | /** 46 | * If multiple implementations of the {@link ServiceProvider} are found on the classpath, then the 47 | * {@link ServiceProvider} with the highest value of priority will be used by default. 48 | * @return The priority (default = 0) 49 | */ 50 | public int getPriority() { 51 | return 0; 52 | } 53 | 54 | /** 55 | * Get the {@link ClassifierFactoryService} 56 | * @return classifier creator service 57 | */ 58 | public ClassifierFactoryService getClassifierFactoryService() { 59 | return ClassifierFactoryService.getInstance(); 60 | } 61 | 62 | /** 63 | * Get the {@link ImageFactoryService} 64 | * @return image factory service. 65 | */ 66 | public abstract ImageFactoryService getImageFactoryService(); 67 | 68 | /** 69 | * Get the {@link ImplementationService} 70 | * @return implementation service. 71 | */ 72 | public abstract ImplementationService getImplementationService(); 73 | 74 | /** 75 | * Get the current {@link ServiceProvider} 76 | * @return service provider. 77 | * @throws IllegalStateException If there are no service providers found. 78 | */ 79 | public static ServiceProvider current() { 80 | if (available().size() == 0) { 81 | throw new IllegalStateException("No service provider found"); 82 | } 83 | return available().get(0); 84 | } 85 | 86 | /** 87 | * Set the current {@link ServiceProvider} 88 | * @param provider The {@link ServiceProvider} to be set as current. 89 | * @throws IllegalStateException If there are no service providers found. 90 | * @throws IllegalArgumentException If the {@link ServiceProvider} given by the parameters is not known 91 | * in the existing list of providers. 92 | */ 93 | public static void setCurrent(final ServiceProvider provider) { 94 | Objects.requireNonNull(provider); 95 | 96 | synchronized (LOCK) { 97 | final List foundProviders = available(); 98 | if (foundProviders.isEmpty()) { 99 | throw new IllegalStateException("No providers found."); 100 | } 101 | if (!foundProviders.contains(provider)) { 102 | throw new IllegalArgumentException("ServiceProvider given through the parameters is not known."); 103 | } 104 | 105 | // Copying list, removes the provider from the arguments and prepends it upfront 106 | // on the copied list. 107 | final ArrayList copiedProviders = new ArrayList<>(); 108 | Collections.copy(copiedProviders, foundProviders); 109 | copiedProviders.remove(provider); 110 | copiedProviders.add(0, provider); 111 | copiedProviders.trimToSize(); 112 | 113 | // Make the list unmodifiable to prevent illegal modification 114 | providers = Collections.unmodifiableList(copiedProviders); 115 | } 116 | } 117 | 118 | /** 119 | * Gets a list of all available {@link ServiceProvider}s. 120 | * @return service providers. 121 | */ 122 | public static List available() { 123 | if (Objects.isNull(providers)) { 124 | synchronized(LOCK) { 125 | if (Objects.nonNull(providers)) { 126 | return providers; 127 | } 128 | 129 | // Searches for implementations of the ServiceProvider using the ServiceLoader API 130 | final ServiceLoader serviceLoader = ServiceLoader.load(ServiceProvider.class); 131 | final ArrayList localProviders = new ArrayList<>(); 132 | for (ServiceProvider provider : serviceLoader) { 133 | localProviders.add(provider); 134 | } 135 | localProviders.trimToSize(); 136 | 137 | // Sort the list based on priority. Highest priority comes first. 138 | localProviders.sort((p1, p2) -> p2.getPriority() - p1.getPriority()); 139 | 140 | // Make the list unmodifiable to prevent illegal modification 141 | providers = Collections.unmodifiableList(localProviders); 142 | } 143 | } 144 | return providers; 145 | } 146 | 147 | } 148 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=`expr $i + 1` 158 | done 159 | case $i in 160 | 0) set -- ;; 161 | 1) set -- "$args0" ;; 162 | 2) set -- "$args0" "$args1" ;; 163 | 3) set -- "$args0" "$args1" "$args2" ;; 164 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=`save "$@"` 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | exec "$JAVACMD" "$@" 184 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/classification/NeuralNetImageClassifier.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.classification; 21 | 22 | import javax.visrec.ml.model.ModelCreationException; 23 | import javax.visrec.spi.ServiceProvider; 24 | import java.nio.file.Path; 25 | 26 | public interface NeuralNetImageClassifier extends ImageClassifier { 27 | 28 | static NeuralNetImageClassifier.Builder builder() { 29 | return new Builder<>(); 30 | } 31 | 32 | class BuildingBlock { 33 | 34 | private int imageWidth; 35 | private int imageHeight; 36 | private Path networkArchitecture; 37 | private Path trainingPath; 38 | private Path labelsFile; 39 | private float maxError; 40 | private float learningRate; 41 | private Path exportPath; 42 | private Path importPath; 43 | private int maxEpochs; 44 | private float threshold; 45 | private Class inputCls; 46 | 47 | private BuildingBlock() { 48 | } 49 | 50 | public Path getNetworkArchitecture() { 51 | return networkArchitecture; 52 | } 53 | 54 | public int getImageWidth() { 55 | return imageWidth; 56 | } 57 | 58 | public int getImageHeight() { 59 | return imageHeight; 60 | } 61 | 62 | public Path getTrainingPath() { 63 | return trainingPath; 64 | } 65 | 66 | public Path getLabelsPath() { 67 | return labelsFile; 68 | } 69 | 70 | public float getMaxError() { 71 | return maxError; 72 | } 73 | 74 | public float getLearningRate() { 75 | return learningRate; 76 | } 77 | 78 | public Path getExportPath() { 79 | return exportPath; 80 | } 81 | 82 | public Path getImportPath() { 83 | return importPath; 84 | } 85 | 86 | 87 | public int getMaxEpochs() { 88 | return maxEpochs; 89 | } 90 | 91 | public float getThreshold() { 92 | return threshold; 93 | } 94 | 95 | 96 | 97 | public Class getInputClass() { 98 | return inputCls; 99 | } 100 | 101 | private static BuildingBlock copyWithNewInputClass(BuildingBlock block, Class cls) { 102 | BuildingBlock newBlock = new BuildingBlock<>(); 103 | newBlock.inputCls = cls; 104 | newBlock.imageHeight = block.imageHeight; 105 | newBlock.imageWidth = block.imageWidth; 106 | newBlock.labelsFile = block.labelsFile; 107 | newBlock.exportPath = block.exportPath; 108 | newBlock.importPath = block.importPath; 109 | newBlock.networkArchitecture = block.networkArchitecture; 110 | newBlock.maxError = block.maxError; 111 | newBlock.maxEpochs = block.maxEpochs; 112 | newBlock.learningRate = block.learningRate; 113 | newBlock.trainingPath = block.trainingPath; 114 | newBlock.threshold = block.threshold; 115 | return newBlock; 116 | } 117 | } 118 | 119 | class Builder implements javax.visrec.ml.model.ModelBuilder> { 120 | 121 | private BuildingBlock block; 122 | 123 | private Builder() { 124 | block = new BuildingBlock<>(); 125 | } 126 | 127 | private Builder(BuildingBlock block) { 128 | this.block = block; 129 | } 130 | 131 | public Builder inputClass(Class cls) { 132 | BuildingBlock newBlock = BuildingBlock.copyWithNewInputClass(block, cls); 133 | return new Builder<>(newBlock); 134 | } 135 | 136 | public Builder imageWidth(int imageWidth) { 137 | block.imageWidth = imageWidth; 138 | return this; 139 | } 140 | 141 | public Builder imageHeight(int imageHeight) { 142 | block.imageHeight = imageHeight; 143 | return this; 144 | } 145 | 146 | public Builder trainingFile(Path trainingFile) { 147 | block.trainingPath = trainingFile; 148 | return this; 149 | } 150 | 151 | public Builder labelsFile(Path labelsFile) { 152 | block.labelsFile = labelsFile; 153 | return this; 154 | } 155 | 156 | public Builder maxError(float maxError) { 157 | block.maxError = maxError; 158 | return this; 159 | } 160 | 161 | public Builder maxEpochs(int epochs) { 162 | block.maxEpochs = epochs; 163 | return this; 164 | } 165 | 166 | public Builder learningRate(float learningRate) { 167 | block.learningRate = learningRate; 168 | return this; 169 | } 170 | 171 | public Builder threshold(float threshold) { 172 | block.threshold = threshold; 173 | return this; 174 | } 175 | 176 | public Builder exportModel(Path path) { 177 | block.exportPath = path; 178 | return this; 179 | } 180 | 181 | public Builder importModel(Path path) { 182 | block.importPath = path; 183 | return this; 184 | } 185 | 186 | public Builder networkArchitecture(Path architecture) { 187 | block.networkArchitecture = architecture; 188 | return this; 189 | } 190 | 191 | public BuildingBlock getBuildingBlock() { 192 | return block; 193 | } 194 | 195 | public ImageClassifier build() throws ModelCreationException { 196 | return ServiceProvider.current().getClassifierFactoryService().createNeuralNetImageClassifier(block); 197 | } 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /src/main/java/javax/visrec/ml/data/DataSet.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Visual Recognition API for Java, JSR381 3 | * Copyright (C) 2020 Zoran Sevarac, Frank Greco 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | package javax.visrec.ml.data; 21 | 22 | import java.util.Collection; 23 | import java.util.Collections; 24 | import java.util.Iterator; 25 | import java.util.List; 26 | import java.util.Objects; 27 | import java.util.Random; 28 | import java.util.stream.Stream; 29 | 30 | /** 31 | * Generic interface for all data sets for machine learning, independent of type of elements. 32 | * 33 | * @param type of data set elements 34 | * @since 1.0 35 | */ 36 | public interface DataSet extends Iterable { 37 | 38 | /** 39 | * Get a collection of the items in the {@link DataSet} 40 | * @return {@link Collection} 41 | */ 42 | List getItems(); 43 | 44 | /** 45 | * Adds an element to this data set. 46 | * 47 | * @param item data set item to add to the data set 48 | * @return current instance of {@link DataSet} 49 | */ 50 | default DataSet add(E item) { 51 | Objects.requireNonNull(item, "Null items are not allowed in dataset"); 52 | getItems().add(item); 53 | return this; 54 | } 55 | 56 | /** 57 | * Add an existing {@link DataSet} to the current {@link DataSet} 58 | * @param dataSet existing {@link DataSet} 59 | * @return current instance of {@link DataSet} 60 | */ 61 | default DataSet addAll(DataSet dataSet) { 62 | Objects.requireNonNull(dataSet, "Dataset is null. Cannot add items from null dataset"); 63 | getItems().addAll(dataSet.getItems()); 64 | return this; 65 | } 66 | 67 | /** 68 | * Get an item from the {@link DataSet} 69 | * @param idx index as {@code int} which corresponds with 70 | * the index of the {@link DataSet} 71 | * @return item from the {@link DataSet} 72 | */ 73 | default E get(int idx) { 74 | return getItems().get(idx); 75 | } 76 | 77 | /** 78 | * Clear items of the {@link DataSet} 79 | */ 80 | default void clear() { 81 | getItems().clear(); 82 | } 83 | 84 | /** 85 | * Determines whether the {@link DataSet} is empty or not. 86 | * @return {@code true} if the {@link DataSet} is empty, otherwise {@code false} 87 | */ 88 | default boolean isEmpty() { 89 | return getItems().isEmpty(); 90 | } 91 | 92 | /** 93 | * Get the number of elements in {@link DataSet} 94 | * @return size in {@code int} 95 | */ 96 | default int size() { 97 | return getItems().size(); 98 | } 99 | 100 | @Override 101 | default Iterator iterator() { 102 | return getItems().iterator(); 103 | } 104 | 105 | /** 106 | * Split data set into specified number of equally sized parts. 107 | * @param numParts number of parts to be returned 108 | * @return multiple {@link DataSet} in an array. 109 | */ 110 | default DataSet[] split(int numParts) { 111 | double part = 1.0 / (double)numParts; 112 | double[] parts = new double[numParts]; 113 | 114 | for (int i=0; i[] split(int numParts, Random rnd) { 128 | double part = 1.0 / (double)numParts; 129 | double[] parts = new double[numParts]; 130 | 131 | for (int i=0; i[] split(double part) { 145 | return split(part, 1-part); 146 | } 147 | 148 | /** 149 | * Split data set into parts of specified sizes 150 | * @param parts specific sizes of {@link DataSet} 151 | * @return array of {@link DataSet} 152 | */ 153 | DataSet[] split(double... parts); 154 | 155 | /** 156 | * Split data set into parts of specified sizes using specified random generator 157 | * @param rnd random generator 158 | * @param parts specific sizes of {@link DataSet} 159 | * @return array of {@link DataSet} 160 | */ 161 | default DataSet[] split(Random rnd, double... parts) { 162 | shuffle(rnd); 163 | return split(parts); 164 | } 165 | 166 | 167 | /** 168 | * Shuffles the data set. 169 | */ 170 | default void shuffle() { 171 | Collections.shuffle(getItems()); 172 | } 173 | 174 | /** 175 | * Shuffles the data set using the specified random number generator. 176 | * @param rnd random generator 177 | */ 178 | default void shuffle(Random rnd) { 179 | Collections.shuffle(getItems(), rnd); 180 | } 181 | 182 | /** 183 | * Sets the columns of this data set. 184 | * 185 | * @param columns 186 | */ 187 | public void setColumns(List columns); 188 | 189 | /** 190 | * Returns the columns of the data set. 191 | * 192 | * @return 193 | */ 194 | public List getColumns(); 195 | 196 | /** 197 | * Get the names of target columns. 198 | * Target columns are use as target output during the training. 199 | * 200 | * @return Returns target columns 201 | */ 202 | public String[] getTargetColumnsNames(); 203 | 204 | 205 | default public Stream stream() { 206 | return getItems().stream(); 207 | } 208 | 209 | } -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 124 | 125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 162 | if ERRORLEVEL 1 goto error 163 | goto end 164 | 165 | :error 166 | set ERROR_CODE=1 167 | 168 | :end 169 | @endlocal & set ERROR_CODE=%ERROR_CODE% 170 | 171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 175 | :skipRcPost 176 | 177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 179 | 180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 181 | 182 | exit /B %ERROR_CODE% 183 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | fi 118 | 119 | if [ -z "$JAVA_HOME" ]; then 120 | javaExecutable="`which javac`" 121 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 122 | # readlink(1) is not available as standard on Solaris 10. 123 | readLink=`which readlink` 124 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 125 | if $darwin ; then 126 | javaHome="`dirname \"$javaExecutable\"`" 127 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 128 | else 129 | javaExecutable="`readlink -f \"$javaExecutable\"`" 130 | fi 131 | javaHome="`dirname \"$javaExecutable\"`" 132 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 133 | JAVA_HOME="$javaHome" 134 | export JAVA_HOME 135 | fi 136 | fi 137 | fi 138 | 139 | if [ -z "$JAVACMD" ] ; then 140 | if [ -n "$JAVA_HOME" ] ; then 141 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 142 | # IBM's JDK on AIX uses strange locations for the executables 143 | JAVACMD="$JAVA_HOME/jre/sh/java" 144 | else 145 | JAVACMD="$JAVA_HOME/bin/java" 146 | fi 147 | else 148 | JAVACMD="`which java`" 149 | fi 150 | fi 151 | 152 | if [ ! -x "$JAVACMD" ] ; then 153 | echo "Error: JAVA_HOME is not defined correctly." >&2 154 | echo " We cannot execute $JAVACMD" >&2 155 | exit 1 156 | fi 157 | 158 | if [ -z "$JAVA_HOME" ] ; then 159 | echo "Warning: JAVA_HOME environment variable is not set." 160 | fi 161 | 162 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 163 | 164 | # traverses directory structure from process work directory to filesystem root 165 | # first directory with .mvn subdirectory is considered project base directory 166 | find_maven_basedir() { 167 | 168 | if [ -z "$1" ] 169 | then 170 | echo "Path not specified to find_maven_basedir" 171 | return 1 172 | fi 173 | 174 | basedir="$1" 175 | wdir="$1" 176 | while [ "$wdir" != '/' ] ; do 177 | if [ -d "$wdir"/.mvn ] ; then 178 | basedir=$wdir 179 | break 180 | fi 181 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 182 | if [ -d "${wdir}" ]; then 183 | wdir=`cd "$wdir/.."; pwd` 184 | fi 185 | # end of workaround 186 | done 187 | echo "${basedir}" 188 | } 189 | 190 | # concatenates all lines of a file 191 | concat_lines() { 192 | if [ -f "$1" ]; then 193 | echo "$(tr -s '\n' ' ' < "$1")" 194 | fi 195 | } 196 | 197 | BASE_DIR=`find_maven_basedir "$(pwd)"` 198 | if [ -z "$BASE_DIR" ]; then 199 | exit 1; 200 | fi 201 | 202 | ########################################################################################## 203 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 204 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 205 | ########################################################################################## 206 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 207 | if [ "$MVNW_VERBOSE" = true ]; then 208 | echo "Found .mvn/wrapper/maven-wrapper.jar" 209 | fi 210 | else 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 213 | fi 214 | if [ -n "$MVNW_REPOURL" ]; then 215 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 216 | else 217 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 218 | fi 219 | while IFS="=" read key value; do 220 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 221 | esac 222 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 223 | if [ "$MVNW_VERBOSE" = true ]; then 224 | echo "Downloading from: $jarUrl" 225 | fi 226 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 227 | if $cygwin; then 228 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 229 | fi 230 | 231 | if command -v wget > /dev/null; then 232 | if [ "$MVNW_VERBOSE" = true ]; then 233 | echo "Found wget ... using wget" 234 | fi 235 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 236 | wget "$jarUrl" -O "$wrapperJarPath" 237 | else 238 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" 239 | fi 240 | elif command -v curl > /dev/null; then 241 | if [ "$MVNW_VERBOSE" = true ]; then 242 | echo "Found curl ... using curl" 243 | fi 244 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 245 | curl -o "$wrapperJarPath" "$jarUrl" -f 246 | else 247 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 248 | fi 249 | 250 | else 251 | if [ "$MVNW_VERBOSE" = true ]; then 252 | echo "Falling back to using Java to download" 253 | fi 254 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 255 | # For Cygwin, switch paths to Windows format before running javac 256 | if $cygwin; then 257 | javaClass=`cygpath --path --windows "$javaClass"` 258 | fi 259 | if [ -e "$javaClass" ]; then 260 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 261 | if [ "$MVNW_VERBOSE" = true ]; then 262 | echo " - Compiling MavenWrapperDownloader.java ..." 263 | fi 264 | # Compiling the Java class 265 | ("$JAVA_HOME/bin/javac" "$javaClass") 266 | fi 267 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 268 | # Running the downloader 269 | if [ "$MVNW_VERBOSE" = true ]; then 270 | echo " - Running MavenWrapperDownloader.java ..." 271 | fi 272 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 273 | fi 274 | fi 275 | fi 276 | fi 277 | ########################################################################################## 278 | # End of extension 279 | ########################################################################################## 280 | 281 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 282 | if [ "$MVNW_VERBOSE" = true ]; then 283 | echo $MAVEN_PROJECTBASEDIR 284 | fi 285 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 286 | 287 | # For Cygwin, switch paths to Windows format before running java 288 | if $cygwin; then 289 | [ -n "$M2_HOME" ] && 290 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 291 | [ -n "$JAVA_HOME" ] && 292 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 293 | [ -n "$CLASSPATH" ] && 294 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 295 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 296 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 297 | fi 298 | 299 | # Provide a "standardized" way to retrieve the CLI args that will 300 | # work with both Windows and non-Windows executions. 301 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 302 | export MAVEN_CMD_LINE_ARGS 303 | 304 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 305 | 306 | exec "$JAVACMD" \ 307 | $MAVEN_OPTS \ 308 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 309 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 310 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 311 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | 342 | CLASSPATH" EXCEPTION TO THE GPL 343 | 344 | Linking this library statically or dynamically with other modules is making 345 | a combined work based on this library. Thus, the terms and conditions of 346 | the GNU General Public License cover the whole combination. 347 | 348 | As a special exception, the copyright holders of this library give you 349 | permission to link this library with independent modules to produce an 350 | executable, regardless of the license terms of these independent modules, 351 | and to copy and distribute the resulting executable under terms of your 352 | choice, provided that you also meet, for each linked independent module, 353 | the terms and conditions of the license of that module. An independent 354 | module is a module which is not derived from or based on this library. If 355 | you modify this library, you may extend this exception to your version of 356 | the library, but you are not obligated to do so. If you do not wish to do 357 | so, delete this exception statement from your version. 358 | --------------------------------------------------------------------------------