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);
+ }
+
+}