diff --git a/.gitignore b/.gitignore index b71ef365088..831bb56cc90 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,7 @@ tags # Gradle out/ + +*/bin/* +bin/ +bin/* diff --git a/vision/color/README.md b/vision/color/README.md new file mode 100644 index 00000000000..013bd2b8afa --- /dev/null +++ b/vision/color/README.md @@ -0,0 +1,38 @@ +# Google Cloud Vision API WORKSHOP + +## Exercise 1 + +This sample uses the [Apache Maven][maven] build system. Before getting started, be +sure to [download][maven-download] and [install][maven-install] it. When you use +Maven as described here, it will automatically download the needed client +libraries. + +[maven]: https://maven.apache.org +[maven-download]: https://maven.apache.org/download.cgi +[maven-install]: https://maven.apache.org/install.html + +## Setup + +* Create a project with the [Google Cloud Console][cloud-console], and enable + the [Vision API][vision-api]. +* Set up your environment with [Application Default Credentials][adc]. For + example, from the Cloud Console, you might create a service account, + download its json credentials file, then set the appropriate environment + variable: + + ```bash + export GOOGLE_APPLICATION_CREDENTIALS=/path/to/your-project-credentials.json + ``` + +[cloud-console]: https://console.cloud.google.com +[vision-api]: https://console.cloud.google.com/apis/api/vision.googleapis.com/overview?project=_ +[adc]: https://cloud.google.com/docs/authentication#developer_workflow + +## Run the sample + +To build and run the sample: + +```bash +mvn clean compile assembly:single +java -cp target/vision-color-1.0-SNAPSHOT-jar-with-dependencies.jar com.google.cloud.vision.samples.color.ColorApp data/apple_good.jpg +``` diff --git a/vision/color/data/good_mango.jpg b/vision/color/data/good_mango.jpg new file mode 100644 index 00000000000..0d8748604dc Binary files /dev/null and b/vision/color/data/good_mango.jpg differ diff --git a/vision/color/data/green_mango.jpg b/vision/color/data/green_mango.jpg new file mode 100644 index 00000000000..38ce6cf6c3f Binary files /dev/null and b/vision/color/data/green_mango.jpg differ diff --git a/vision/color/pom.xml b/vision/color/pom.xml new file mode 100644 index 00000000000..f8e45ec7faf --- /dev/null +++ b/vision/color/pom.xml @@ -0,0 +1,101 @@ + + + + 4.0.0 + jar + 1.0-SNAPSHOT + com.google.cloud.vision.samples + vision-color + + + + com.google.cloud + doc-samples + 1.0.0 + ../.. + + + + 1.8 + 1.8 + + + + + com.google.apis + google-api-services-vision + v1-rev24-1.22.0 + + + com.google.api-client + google-api-client + 1.22.0 + + + com.google.guava + guava + 19.0 + + + + + junit + junit + 4.12 + test + + + com.google.truth + truth + 0.30 + test + + + + javax.servlet + javax.servlet-api + 3.1.0 + test + + + + + + org.apache.maven.plugins + 3.3 + maven-compiler-plugin + + 1.7 + 1.7 + + + + maven-assembly-plugin + + + + com.google.cloud.vision.samples.label.LabelApp + + + + jar-with-dependencies + + + + + + diff --git a/vision/color/src/main/java/com/google/cloud/vision/samples/color/ColorApp.java b/vision/color/src/main/java/com/google/cloud/vision/samples/color/ColorApp.java new file mode 100644 index 00000000000..25ead487dcd --- /dev/null +++ b/vision/color/src/main/java/com/google/cloud/vision/samples/color/ColorApp.java @@ -0,0 +1,158 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.vision.samples.color; + +import java.io.IOException; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.GeneralSecurityException; + +// [START import_libraries] +import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; +import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; +import com.google.api.client.json.JsonFactory; +import com.google.api.client.json.jackson2.JacksonFactory; +import com.google.api.services.vision.v1.Vision; +import com.google.api.services.vision.v1.VisionScopes; +import com.google.api.services.vision.v1.model.AnnotateImageRequest; +import com.google.api.services.vision.v1.model.AnnotateImageResponse; +import com.google.api.services.vision.v1.model.BatchAnnotateImagesRequest; +import com.google.api.services.vision.v1.model.BatchAnnotateImagesResponse; +import com.google.api.services.vision.v1.model.Color; +import com.google.api.services.vision.v1.model.ColorInfo; +import com.google.api.services.vision.v1.model.DominantColorsAnnotation; +import com.google.api.services.vision.v1.model.Feature; +import com.google.api.services.vision.v1.model.Image; +import com.google.api.services.vision.v1.model.ImageProperties; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +// [END import_libraries] + +/** + * A sample application that uses the Vision API to verify the dominant color of a picture + */ +public class ColorApp { + /** + * Be sure to specify the name of your application. If the application name is {@code null} or + * blank, the application will log a warning. Suggested format is "MyCompany-ProductName/1.0". + */ + private static final String APPLICATION_NAME = "Google-VisionLabelSample/1.0"; + + // [START run_application] + /** + * Annotates an image using the Vision API. + */ + public static void main(String[] args) throws IOException, GeneralSecurityException { + if (args.length != 1) { + System.err.println("Missing imagePath argument."); + System.err.println("Usage:"); + System.err.printf("\tjava %s imagePath\n", ColorApp.class.getCanonicalName()); + System.exit(1); + } + Path imagePath = Paths.get(args[0]); + + ColorApp app = new ColorApp(getVisionService()); + printProperties(System.out, imagePath, app.getImageProperties(imagePath)); + } + + private float rgbDistance(Color c1, Color c2) { + return (float) Math.sqrt( + (Math.abs(Math.pow(c1.getRed() - c2.getRed(), 2)) + Math.abs(Math.pow(c1.getGreen() - c2.getGreen(), 2)) + + Math.abs(Math.pow(c1.getBlue() - c2.getBlue(), 2)))); + } + + private String closestColorName(Color c) { + Color red = new Color(); + red.setRed(255.0f); + red.setGreen(0.0f); + red.setBlue(0.0f); + red.set("name", "red"); + Color yellow = new Color(); + yellow.setRed(255.0f); + yellow.setGreen(255.0f); + yellow.setBlue(0.0f); + yellow.set("name", "yellow"); + Color green = new Color(); + green.setRed(0.0f); + green.setGreen(255.0f); + green.setBlue(0.0f); + green.set("name", "green"); + java.util.List referenceColors = Lists.newArrayList(red, yellow, green); + float minDistance = rgbDistance(red, c); + String closestColorName = (String) red.get("name"); + for (Color ref : referenceColors) { + float distance = rgbDistance(ref, c); + if (distance <= minDistance) { + minDistance = distance; + closestColorName = (String) ref.get("name"); + } + } + return closestColorName; + } + + public String getDominantColor(Path imagePath) throws IOException, GeneralSecurityException { + //TODO + return null; + } + + /** + * Prints the properties received from the Vision API. + * + * @throws IOException + */ + public static void printProperties(PrintStream out, Path imagePath, ImageProperties properties) + throws IOException { + out.printf("Properties for image %s:\n %s", imagePath, properties.toPrettyString()); + if (properties.isEmpty()) { + out.println("\tNo properties found."); + } + } + // [END run_application] + + // [START authenticate] + /** + * Connects to the Vision API using Application Default Credentials. + */ + public static Vision getVisionService() throws IOException, GeneralSecurityException { + GoogleCredential credential = + GoogleCredential.getApplicationDefault().createScoped(VisionScopes.all()); + JsonFactory jsonFactory = JacksonFactory.getDefaultInstance(); + return new Vision.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, credential) + .setApplicationName(APPLICATION_NAME) + .build(); + } + // [END authenticate] + + private final Vision vision; + + /** + * Constructs a {@link ColorApp} which connects to the Vision API. + */ + public ColorApp(Vision vision) { + this.vision = vision; + } + + /** + * Gets properties for an image stored at {@code path}. + */ + public ImageProperties getImageProperties(Path path) throws IOException { + // TODO + return null; + } +} diff --git a/vision/color/src/test/java/com/google/cloud/vision/samples/color/ColorAppTest.java b/vision/color/src/test/java/com/google/cloud/vision/samples/color/ColorAppTest.java new file mode 100644 index 00000000000..3be737b1934 --- /dev/null +++ b/vision/color/src/test/java/com/google/cloud/vision/samples/color/ColorAppTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.vision.samples.color; + +import static com.google.common.truth.Truth.assertThat; + +import java.nio.file.Paths; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Integration (system) tests for {@link ColorApp}. + */ +@RunWith(JUnit4.class) +public class ColorAppTest { + + private ColorApp appUnderTest; + + @Before + public void setUp() throws Exception { + appUnderTest = new ColorApp(ColorApp.getVisionService()); + } + + @Test + public void goodMangoShoudReturnRedOrYellow() throws Exception { + String predominantColor = appUnderTest.getDominantColor(Paths.get("data/good_mango.jpg")); + assertThat(predominantColor).isAnyOf("red", "yellow"); + } + + @Test + public void immatureMangoShoudReturnGreen() throws Exception { + String predominantColor = appUnderTest.getDominantColor(Paths.get("data/green_mango.jpg")); + assertThat(predominantColor).isEqualTo("green"); + } +} diff --git a/vision/face-sentiment-detection/.gitignore b/vision/face-sentiment-detection/.gitignore new file mode 100644 index 00000000000..55d847395a3 --- /dev/null +++ b/vision/face-sentiment-detection/.gitignore @@ -0,0 +1 @@ +output.jpg diff --git a/vision/face-sentiment-detection/README.md b/vision/face-sentiment-detection/README.md new file mode 100644 index 00000000000..25de0a9057b --- /dev/null +++ b/vision/face-sentiment-detection/README.md @@ -0,0 +1,43 @@ +# Google Cloud Vision API Java Face Detection example + +## Download Maven + +This sample uses the [Apache Maven][maven] build system. Before getting started, be +sure to [download][maven-download] and [install][maven-install] it. When you use +Maven as described here, it will automatically download the needed client +libraries. + +[maven]: https://maven.apache.org +[maven-download]: https://maven.apache.org/download.cgi +[maven-install]: https://maven.apache.org/install.html + +## Setup + +* Create a project with the [Google Cloud Console][cloud-console], and enable + the [Vision API][vision-api]. +* Set up your environment with [Application Default Credentials][adc]. For + example, from the Cloud Console, you might create a service account, + download its json credentials file, then set the appropriate environment + variable: + + ```bash + export GOOGLE_APPLICATION_CREDENTIALS=/path/to/your-project-credentials.json + ``` + +[cloud-console]: https://console.cloud.google.com +[vision-api]: https://console.cloud.google.com/apis/api/vision.googleapis.com/overview?project=_ +[adc]: https://cloud.google.com/docs/authentication#developer_workflow + +## Run the sample + +To build and run the sample, run the following from this directory: + +```bash +mvn clean compile assembly:single +java -cp target/vision-face-detection-1.0-SNAPSHOT-jar-with-dependencies.jar com.google.cloud.vision.samples.facedetect.FaceDetectApp data/face.jpg output.jpg +``` + +For more information about face detection see the [Quickstart][quickstart] +guide. + +[quickstart]: https://cloud.google.com/vision/docs/face-tutorial diff --git a/vision/face-sentiment-detection/data/bad.txt b/vision/face-sentiment-detection/data/bad.txt new file mode 100644 index 00000000000..d03a5a96367 --- /dev/null +++ b/vision/face-sentiment-detection/data/bad.txt @@ -0,0 +1 @@ +I am not an image. Labelling shouldn't work on me. diff --git a/vision/face-sentiment-detection/data/face.jpg b/vision/face-sentiment-detection/data/face.jpg new file mode 100644 index 00000000000..c0ee5580b37 Binary files /dev/null and b/vision/face-sentiment-detection/data/face.jpg differ diff --git a/vision/face-sentiment-detection/data/meeting-out.jpg b/vision/face-sentiment-detection/data/meeting-out.jpg new file mode 100644 index 00000000000..df60e02fa05 Binary files /dev/null and b/vision/face-sentiment-detection/data/meeting-out.jpg differ diff --git a/vision/face-sentiment-detection/data/meeting.jpg b/vision/face-sentiment-detection/data/meeting.jpg new file mode 100644 index 00000000000..b994f115be5 Binary files /dev/null and b/vision/face-sentiment-detection/data/meeting.jpg differ diff --git a/vision/face-sentiment-detection/pom.xml b/vision/face-sentiment-detection/pom.xml new file mode 100644 index 00000000000..4e9c64d419c --- /dev/null +++ b/vision/face-sentiment-detection/pom.xml @@ -0,0 +1,94 @@ + + + + 4.0.0 + jar + 1.0-SNAPSHOT + com.google.cloud.vision.samples + vision-face-sentiment-detection + + + + com.google.cloud + doc-samples + 1.0.0 + ../.. + + + + 1.8 + 1.8 + + + + + + com.google.apis + google-api-services-vision + v1-rev24-1.22.0 + + + com.google.api-client + google-api-client + 1.22.0 + + + + com.google.guava + guava + 19.0 + + + + + junit + junit + 4.12 + test + + + com.google.truth + truth + 0.30 + test + + + + javax.servlet + javax.servlet-api + 3.1.0 + test + + + + + + maven-assembly-plugin + + + + com.google.cloud.vision.samples.facedetect.FaceDetectApp + + + + jar-with-dependencies + + + + + + diff --git a/vision/face-sentiment-detection/src/main/java/com/google/cloud/vision/samples/facesentimentdetect/FaceSentimentDetectApp.java b/vision/face-sentiment-detection/src/main/java/com/google/cloud/vision/samples/facesentimentdetect/FaceSentimentDetectApp.java new file mode 100644 index 00000000000..8e0f51f0436 --- /dev/null +++ b/vision/face-sentiment-detection/src/main/java/com/google/cloud/vision/samples/facesentimentdetect/FaceSentimentDetectApp.java @@ -0,0 +1,208 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.vision.samples.facesentimentdetect; + +// [BEGIN import_libraries] +import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; +import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; +import com.google.api.client.json.JsonFactory; +import com.google.api.client.json.jackson2.JacksonFactory; +import com.google.api.services.vision.v1.Vision; +import com.google.api.services.vision.v1.VisionScopes; +import com.google.api.services.vision.v1.model.AnnotateImageRequest; +import com.google.api.services.vision.v1.model.AnnotateImageResponse; +import com.google.api.services.vision.v1.model.BatchAnnotateImagesRequest; +import com.google.api.services.vision.v1.model.BatchAnnotateImagesResponse; +import com.google.api.services.vision.v1.model.FaceAnnotation; +import com.google.api.services.vision.v1.model.Feature; +import com.google.api.services.vision.v1.model.Image; +import com.google.api.services.vision.v1.model.Vertex; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.GeneralSecurityException; +import java.util.List; + +import javax.imageio.ImageIO; +// [END import_libraries] + +/** + * A sample application that uses the Vision API to detect people emotions in an image. + */ +public class FaceSentimentDetectApp { + /** + * Be sure to specify the name of your application. If the application name is {@code null} or + * blank, the application will log a warning. Suggested format is "MyCompany-ProductName/1.0". + */ + private static final String APPLICATION_NAME = "Google-VisionFaceDetectSample/1.0"; + + private static final int MAX_RESULTS = 10; + + // [START main] + /** + * Annotates an image using the Vision API. + */ + public static void main(String[] args) throws IOException, GeneralSecurityException { + if (args.length != 2) { + System.err.println("Usage:"); + System.err.printf( + "\tjava %s inputImagePath outputImagePath\n", + FaceSentimentDetectApp.class.getCanonicalName()); + System.exit(1); + } + Path inputPath = Paths.get(args[0]); + Path outputPath = Paths.get(args[1]); + if (!outputPath.toString().toLowerCase().endsWith(".jpg")) { + System.err.println("outputImagePath must have the file extension 'jpg'."); + System.exit(1); + } + + FaceSentimentDetectApp app = new FaceSentimentDetectApp(getVisionService()); + List faces = app.detectFaces(inputPath, MAX_RESULTS); + System.out.printf("Found %d face%s\n", faces.size(), faces.size() == 1 ? "" : "s"); + System.out.printf("Writing to file %s\n", outputPath); + FaceSentimentDetectApp.writeWithFaces(inputPath, outputPath, faces); + } + // [END main] + + // [START get_vision_service] + /** + * Connects to the Vision API using Application Default Credentials. + */ + public static Vision getVisionService() throws IOException, GeneralSecurityException { + GoogleCredential credential = + GoogleCredential.getApplicationDefault().createScoped(VisionScopes.all()); + JsonFactory jsonFactory = JacksonFactory.getDefaultInstance(); + return new Vision.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, credential) + .setApplicationName(APPLICATION_NAME) + .build(); + } + // [END get_vision_service] + + private final Vision vision; + + /** + * Constructs a {@link FaceSentimentDetectApp} which connects to the Vision API. + */ + public FaceSentimentDetectApp(Vision vision) { + this.vision = vision; + } + + // [START detect_face] + /** + * Gets up to {@code maxResults} faces for an image stored at {@code path}. + */ + public List detectFaces(Path path, int maxResults) throws IOException { + byte[] data = Files.readAllBytes(path); + + AnnotateImageRequest request = + new AnnotateImageRequest() + .setImage(new Image().encodeContent(data)) + .setFeatures(ImmutableList.of( + new Feature() + .setType("FACE_DETECTION") + .setMaxResults(maxResults))); + Vision.Images.Annotate annotate = + vision.images() + .annotate(new BatchAnnotateImagesRequest().setRequests(ImmutableList.of(request))); + // Due to a bug: requests to Vision API containing large images fail when GZipped. + annotate.setDisableGZipContent(true); + + BatchAnnotateImagesResponse batchResponse = annotate.execute(); + assert batchResponse.getResponses().size() == 1; + AnnotateImageResponse response = batchResponse.getResponses().get(0); + if (response.getFaceAnnotations() == null) { + throw new IOException( + response.getError() != null + ? response.getError().getMessage() + : "Unknown error getting image annotations"); + } + return response.getFaceAnnotations(); + } + // [END detect_face] + + // [START highlight_faces] + /** + * Reads image {@code inputPath} and writes {@code outputPath} with {@code faces} outlined. + */ + private static void writeWithFaces(Path inputPath, Path outputPath, List faces) + throws IOException { + BufferedImage img = ImageIO.read(inputPath.toFile()); + annotateWithFaces(img, faces); + ImageIO.write(img, "jpg", outputPath.toFile()); + } + + + /** + * Annotates an image {@code img} with a polygon around each face in {@code faces}. + */ + public static void annotateWithFaces(BufferedImage img, List faces) { + for (FaceAnnotation face : faces) { + annotateWithFace(img, face); + } + } + + /** + * Sentiments can be positive, neutral or negative + * Positive sentiments: joy + * Negative sentiments: sorrow, anger + * Neutral sentiments: surprise + * Hint: Possible likelihoods: LIKELY, VERY_LIKELY, UNLIKELY, VERY_UNLIKELY, + * POSSIBLE, UNKNOWN + * @param face + * @return + */ + public static String getSentiment(FaceAnnotation face) { + // TODO + return null; + } + + + + /** + * Annotates an image {@code img} with a polygon defined by {@code face}. + */ + private static void annotateWithFace(BufferedImage img, FaceAnnotation face) { + Color color = new Color(0xffffff); + String sentiment = getSentiment(face); + if (sentiment.equals("positive")) { + color = new Color(0x00ff00); + } else if (sentiment.equals("negative")) { + color = new Color(0xff0000); + } else if (sentiment.equals("neutral")) { + color = new Color(0xd3d3d3); + } + Graphics2D gfx = img.createGraphics(); + Polygon poly = new Polygon(); + for (Vertex vertex : face.getFdBoundingPoly().getVertices()) { + poly.addPoint(vertex.getX(), vertex.getY()); + } + gfx.setStroke(new BasicStroke(5)); + gfx.setColor(color); + gfx.draw(poly); + } + // [END highlight_faces] +} diff --git a/vision/face-sentiment-detection/src/test/java/com/google/cloud/vision/samples/facesentimentdetect/FaceSentimentDetectTest.java b/vision/face-sentiment-detection/src/test/java/com/google/cloud/vision/samples/facesentimentdetect/FaceSentimentDetectTest.java new file mode 100644 index 00000000000..9bd676290ae --- /dev/null +++ b/vision/face-sentiment-detection/src/test/java/com/google/cloud/vision/samples/facesentimentdetect/FaceSentimentDetectTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.vision.samples.facesentimentdetect; + +import static com.google.common.truth.Truth.assertThat; + +import java.nio.file.Paths; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import com.google.api.services.vision.v1.model.FaceAnnotation; +import com.google.cloud.vision.samples.facesentimentdetect.FaceSentimentDetectApp; +import com.google.common.collect.Lists; + +/** + * Integration (system) tests for {@link FaceSentimentDetectApp}. + */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class FaceSentimentDetectTest { + private static final int MAX_RESULTS = 6; + + private FaceSentimentDetectApp appUnderTest; + + @Before + public void setUp() throws Exception { + appUnderTest = new FaceSentimentDetectApp(FaceSentimentDetectApp.getVisionService()); + } + + @Test + public void shouldReturnAtLeastOneFace() throws Exception { + List faces = appUnderTest.detectFaces(Paths.get("data/meeting.jpg"), MAX_RESULTS); + + assertThat(faces).named("meeting.jpg faces").isNotEmpty(); + assertThat(faces.get(0).getFdBoundingPoly().getVertices()).named("face.jpg face #0 FdBoundingPoly Vertices") + .isNotEmpty(); + } + + @SuppressWarnings("static-access") + @Test + public void shouldGetSentimentsRight() throws Exception { + List sentiments = Lists.newArrayList(); + List faces = appUnderTest.detectFaces(Paths.get("data/meeting.jpg"), MAX_RESULTS); + for (FaceAnnotation face : faces) { + sentiments.add(appUnderTest.getSentiment(face)); + } + assertThat(sentiments).containsExactly("neutral", "neutral", "positive", "neutral", + "positive", "positive"); + System.out.println(sentiments); + } + +}