GH-7: Add checkstyle and javaformat plugins

Fixes: #7

* Run `./gradlew format`
* Updates from PR review suggestions
This commit is contained in:
Chris Bono
2023-12-29 21:08:58 -06:00
committed by Artem Bilan
parent 84e732da08
commit 836708f0f2
357 changed files with 4344 additions and 4519 deletions

View File

@@ -33,8 +33,8 @@ import org.springframework.cloud.fn.object.detection.domain.ObjectDetection;
import org.springframework.util.CollectionUtils;
/**
* Augment the input image fromMemory detected object bounding boxes and categories.
* For mask models and withMask set to true it draws the instance segmentation image as well.
* Augment the input image fromMemory detected object bounding boxes and categories. For
* mask models and withMask set to true it draws the instance segmentation image as well.
*
* @author Christian Tzolov
*/
@@ -48,6 +48,7 @@ public class ObjectDetectionImageAugmenter implements BiFunction<byte[], List<Ob
private String imageFormat = DEFAULT_IMAGE_FORMAT;
private final boolean withMask;
private boolean agnosticColors = false;
public ObjectDetectionImageAugmenter() {
@@ -99,8 +100,7 @@ public class ObjectDetectionImageAugmenter implements BiFunction<byte[], List<Ob
float[][] mask = od.getMask();
if (mask != null) {
Color maskColor = this.agnosticColors ? null : GraphicsUtils.getClassColor(cid);
BufferedImage maskImage = GraphicsUtils.createMaskImage(
mask, x2 - x1, y2 - y1, maskColor);
BufferedImage maskImage = GraphicsUtils.createMaskImage(mask, x2 - x1, y2 - y1, maskColor);
GraphicsUtils.overlayImages(bufferedImage, maskImage, x1, y1);
}
}
@@ -116,4 +116,5 @@ public class ObjectDetectionImageAugmenter implements BiFunction<byte[], List<Ob
// Null mend that QR image is found and not output message will be send.
return imageBytes;
}
}

View File

@@ -41,8 +41,10 @@ public class ObjectDetectionInputAdapter implements Function<byte[], Map<String,
/** Make checkstyle happy. **/
public static final String RAW_IMAGE = "raw_image";
/** Make checkstyle happy. **/
public static final String NORMALIZED_IMAGE = "normalized_image";
/** Make checkstyle happy. **/
public static final long CHANNELS = 3;
@@ -50,14 +52,14 @@ public class ObjectDetectionInputAdapter implements Function<byte[], Map<String,
public ObjectDetectionInputAdapter() {
this.imageLoaderGraph = new GraphRunner(RAW_IMAGE, NORMALIZED_IMAGE)
.withGraphDefinition(tf -> {
Placeholder<String> rawImage = tf.withName(RAW_IMAGE).placeholder(String.class);
Operand<UInt8> decodedImage = tf.dtypes.cast(
tf.image.decodeJpeg(rawImage, DecodeJpeg.channels(CHANNELS)), UInt8.class);
// Expand dimensions since the model expects images to have shape: [1, H, W, 3]
tf.withName(NORMALIZED_IMAGE).expandDims(decodedImage, tf.constant(0));
});
this.imageLoaderGraph = new GraphRunner(RAW_IMAGE, NORMALIZED_IMAGE).withGraphDefinition(tf -> {
Placeholder<String> rawImage = tf.withName(RAW_IMAGE).placeholder(String.class);
Operand<UInt8> decodedImage = tf.dtypes.cast(tf.image.decodeJpeg(rawImage, DecodeJpeg.channels(CHANNELS)),
UInt8.class);
// Expand dimensions since the model expects images to have shape: [1, H, W,
// 3]
tf.withName(NORMALIZED_IMAGE).expandDims(decodedImage, tf.constant(0));
});
}
@Override
@@ -73,4 +75,5 @@ public class ObjectDetectionInputAdapter implements Function<byte[], Map<String,
this.imageLoaderGraph.close();
}
}
}

View File

@@ -35,8 +35,8 @@ import org.tensorflow.types.UInt8;
import org.springframework.cloud.fn.common.tensorflow.deprecated.GraphicsUtils;
/**
* Converts byte array image into a input Tensor for the Object Detection API. The computed image tensors uses the
* 'image_tensor' model placeholder.
* Converts byte array image into a input Tensor for the Object Detection API. The
* computed image tensors uses the 'image_tensor' model placeholder.
*
* @author Christian Tzolov
*/
@@ -95,4 +95,5 @@ public class ObjectDetectionInputConverter implements Function<byte[][], Map<Str
data[i + 2] = tmp;
}
}
}

View File

@@ -37,21 +37,22 @@ import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
/**
* Converts the Tensorflow Object Detection result into {@link ObjectDetection} list.
* The pre-trained Object Detection models (http://bit.ly/2osxMAY) produce 3 tensor outputs:
* (1) detection_classes - containing the ids of detected objects, (2) detection_scores - confidence probabilities of the
* detected object and (3) detection_boxes - the object bounding boxes withing the images.
* Converts the Tensorflow Object Detection result into {@link ObjectDetection} list. The
* pre-trained Object Detection models (http://bit.ly/2osxMAY) produce 3 tensor outputs:
* (1) detection_classes - containing the ids of detected objects, (2) detection_scores -
* confidence probabilities of the detected object and (3) detection_boxes - the object
* bounding boxes withing the images.
*
* The MASK based models provide to 2 additional tensors: (4) num_detections and (5) detection_masks.
* The MASK based models provide to 2 additional tensors: (4) num_detections and (5)
* detection_masks.
*
* All outputs tensors are float arrays, having:
* - 1 as the first dimension
* - maxObjects as the second dimension
* While boxesT will have 4 as the third dimension (2 sets of (x, y) coordinates).
* This can be verified by looking at scoresT.shape() etc.
* All outputs tensors are float arrays, having: - 1 as the first dimension - maxObjects
* as the second dimension While boxesT will have 4 as the third dimension (2 sets of (x,
* y) coordinates). This can be verified by looking at scoresT.shape() etc.
*
* The format detected classes (e.g. labels) names is defined by the 'string_int_labels_map.proto'. The input list
* is available at: https://github.com/tensorflow/models/tree/master/research/object_detection/data
* The format detected classes (e.g. labels) names is defined by the
* 'string_int_labels_map.proto'. The input list is available at:
* https://github.com/tensorflow/models/tree/master/research/object_detection/data
*
* @author Christian Tzolov
*/
@@ -61,17 +62,23 @@ public class ObjectDetectionOutputConverter implements Function<Map<String, Tens
/** DETECTION_CLASSES. */
public static final String DETECTION_CLASSES = "detection_classes";
/** DETECTION_SCORES. */
public static final String DETECTION_SCORES = "detection_scores";
/** DETECTION_BOXES. */
public static final String DETECTION_BOXES = "detection_boxes";
/** DETECTION_MASKS. */
public static final String DETECTION_MASKS = "detection_masks";
/** NUM_DETECTIONS. */
public static final String NUM_DETECTIONS = "num_detections";
private final String[] labels;
private float confidence;
private List<String> modelFetch;
public ObjectDetectionOutputConverter(Resource labelsResource, float confidence, List<String> modelFetch) {
@@ -96,15 +103,16 @@ public class ObjectDetectionOutputConverter implements Function<Map<String, Tens
private static String[] loadLabels(Resource labelsResource) throws Exception {
try (InputStream is = labelsResource.getInputStream()) {
String text = StreamUtils.copyToString(is, Charset.forName("UTF-8"));
StringIntLabelMapOuterClass.StringIntLabelMap.Builder builder =
StringIntLabelMapOuterClass.StringIntLabelMap.newBuilder();
StringIntLabelMapOuterClass.StringIntLabelMap.Builder builder = StringIntLabelMapOuterClass.StringIntLabelMap
.newBuilder();
TextFormat.merge(text, builder);
StringIntLabelMapOuterClass.StringIntLabelMap proto = builder.build();
int maxLabelId = proto.getItemList().stream()
.map(StringIntLabelMapOuterClass.StringIntLabelMapItem::getId)
.max(Comparator.comparing(i -> i))
.orElse(-1);
int maxLabelId = proto.getItemList()
.stream()
.map(StringIntLabelMapOuterClass.StringIntLabelMapItem::getId)
.max(Comparator.comparing(i -> i))
.orElse(-1);
String[] labelIdToNameMap = new String[maxLabelId + 1];
for (StringIntLabelMapOuterClass.StringIntLabelMapItem item : proto.getItemList()) {
@@ -112,7 +120,8 @@ public class ObjectDetectionOutputConverter implements Function<Map<String, Tens
labelIdToNameMap[item.getId()] = item.getDisplayName();
}
else {
// Common practice is to set the name to a MID or Synsets Id. Synset is a set of synonyms that
// Common practice is to set the name to a MID or Synsets Id. Synset
// is a set of synonyms that
// share a common meaning: https://en.wikipedia.org/wiki/WordNet
labelIdToNameMap[item.getId()] = item.getName();
}
@@ -125,13 +134,13 @@ public class ObjectDetectionOutputConverter implements Function<Map<String, Tens
public List<List<ObjectDetection>> apply(Map<String, Tensor<?>> tensorMap) {
try (Tensor<Float> scoresTensor = tensorMap.get(DETECTION_SCORES).expect(Float.class);
Tensor<Float> classesTensor = tensorMap.get(DETECTION_CLASSES).expect(Float.class);
Tensor<Float> boxesTensor = tensorMap.get(DETECTION_BOXES).expect(Float.class)
) {
Tensor<Float> classesTensor = tensorMap.get(DETECTION_CLASSES).expect(Float.class);
Tensor<Float> boxesTensor = tensorMap.get(DETECTION_BOXES).expect(Float.class)) {
// All these tensors have:
// - 1 as the first dimension
// - maxObjects as the second dimension
// While boxesT will have 4 as the third dimension (2 sets of (x, y) coordinates).
// While boxesT will have 4 as the third dimension (2 sets of (x, y)
// coordinates).
// This can be verified by looking at scoresT.shape() etc.
int batchSize = (int) scoresTensor.shape()[0];
int maxObjects = (int) scoresTensor.shape()[1];
@@ -143,10 +152,10 @@ public class ObjectDetectionOutputConverter implements Function<Map<String, Tens
for (int batchIndex = 0; batchIndex < batchSize; batchIndex++) {
List<ObjectDetection> objectDetections = new ArrayList<>();
// Collect only the objects whose scores are at above the configured confidence threshold.
// Collect only the objects whose scores are at above the configured
// confidence threshold.
for (int i = 0; i < scores[batchIndex].length; ++i) {
if (scores[batchIndex][i] >= confidence) {
String category = labels[(int) classes[batchIndex][i]];
@@ -169,7 +178,8 @@ public class ObjectDetectionOutputConverter implements Function<Map<String, Tens
if (masksTensor != null) {
long[] shape = masksTensor.shape();
float[][][][] masks = masksTensor.copyTo(new float[(int) shape[0]][(int) shape[1]][(int) shape[2]][(int) shape[3]]);
float[][][][] masks = masksTensor
.copyTo(new float[(int) shape[0]][(int) shape[1]][(int) shape[2]][(int) shape[3]]);
od.setMask(masks[batchIndex][i]);
logger.debug(String.format("Num detections: %s, Masks: %s", nd, masks));
}
@@ -184,4 +194,5 @@ public class ObjectDetectionOutputConverter implements Function<Map<String, Tens
return batchObjectDetections;
}
}
}

View File

@@ -29,66 +29,79 @@ import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.util.StreamUtils;
/**
* Convenience class that leverages the the {@link ObjectDetectionInputConverter}, {@link ObjectDetectionOutputConverter} and {@link TensorFlowService}
* in combination fromMemory the Tensorflow Object Detection API (https://github.com/tensorflow/models/tree/master/research/object_detection)
* models for detection objects in input images.
* Convenience class that leverages the the {@link ObjectDetectionInputConverter},
* {@link ObjectDetectionOutputConverter} and {@link TensorFlowService} in combination
* fromMemory the Tensorflow Object Detection API
* (https://github.com/tensorflow/models/tree/master/research/object_detection) models for
* detection objects in input images.
*
* All pre-trained models (https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md) and labels are supported.
* All pre-trained models
* (https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md)
* and labels are supported.
*
* You can download pre-trained models directly from the zoo: https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md
* Just use the URI notation: (zoo model tar.gz url)#(name of the frozen model file name). To speedup the bootstrap
* performance you should consider downloading the models locally and use the file:/"path to my model" URI instead!
* You can download pre-trained models directly from the zoo:
* https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md
* Just use the URI notation: (zoo model tar.gz url)#(name of the frozen model file name).
* To speedup the bootstrap performance you should consider downloading the models locally
* and use the file:/"path to my model" URI instead!
*
* The object category labels for the pre-trained models are available at: https://github.com/tensorflow/models/tree/master/research/object_detection/data
* Use the labels applicable for the model. Also, for performance reasons you may consider to download the labels
* and load them from file: instead.
* The object category labels for the pre-trained models are available at:
* https://github.com/tensorflow/models/tree/master/research/object_detection/data Use the
* labels applicable for the model. Also, for performance reasons you may consider to
* download the labels and load them from file: instead.
*
* @author Christian Tzolov
*/
public class ObjectDetectionService {
/** Default list of fetch names for Box models. */
public static List<String> FETCH_NAMES = Arrays.asList(
ObjectDetectionOutputConverter.DETECTION_SCORES, ObjectDetectionOutputConverter.DETECTION_CLASSES,
ObjectDetectionOutputConverter.DETECTION_BOXES, ObjectDetectionOutputConverter.NUM_DETECTIONS);
/** Default list of fetch names for mask supporting models. */
public static List<String> FETCH_NAMES_WITH_MASKS = Arrays.asList(
ObjectDetectionOutputConverter.DETECTION_SCORES, ObjectDetectionOutputConverter.DETECTION_CLASSES,
ObjectDetectionOutputConverter.DETECTION_BOXES, ObjectDetectionOutputConverter.DETECTION_MASKS,
public static List<String> FETCH_NAMES = Arrays.asList(ObjectDetectionOutputConverter.DETECTION_SCORES,
ObjectDetectionOutputConverter.DETECTION_CLASSES, ObjectDetectionOutputConverter.DETECTION_BOXES,
ObjectDetectionOutputConverter.NUM_DETECTIONS);
/** Default list of fetch names for mask supporting models. */
public static List<String> FETCH_NAMES_WITH_MASKS = Arrays.asList(ObjectDetectionOutputConverter.DETECTION_SCORES,
ObjectDetectionOutputConverter.DETECTION_CLASSES, ObjectDetectionOutputConverter.DETECTION_BOXES,
ObjectDetectionOutputConverter.DETECTION_MASKS, ObjectDetectionOutputConverter.NUM_DETECTIONS);
private final ObjectDetectionInputConverter inputConverter;
private final ObjectDetectionOutputConverter outputConverter;
private final TensorFlowService tensorFlowService;
public ObjectDetectionService() {
this("https://download.tensorflow.org/models/object_detection/ssdlite_mobilenet_v2_coco_2018_05_09.tar.gz#frozen_inference_graph.pb",
"https://storage.googleapis.com/scdf-tensorflow-models/object-detection/mscoco_label_map.pbtxt",
0.4f, false, true);
"https://storage.googleapis.com/scdf-tensorflow-models/object-detection/mscoco_label_map.pbtxt", 0.4f,
false, true);
}
/**
* Convenience constructor that would initialize all necessary internal components.
* @param modelUri URI of the pre-trained, frozen Tensorflow model.
* @param labelsUri URI of the pre-trained category labels.
* @param confidence Confidence threshold. Only objects detected wth confidence above this threshold will be returned.
* @param withMasks If a Mask model is selected then you can use this flag to extract the instance segmentation masks as well.
* @param confidence Confidence threshold. Only objects detected wth confidence above
* this threshold will be returned.
* @param withMasks If a Mask model is selected then you can use this flag to extract
* the instance segmentation masks as well.
*/
public ObjectDetectionService(String modelUri, String labelsUri,
float confidence, boolean withMasks, boolean cacheModel) {
public ObjectDetectionService(String modelUri, String labelsUri, float confidence, boolean withMasks,
boolean cacheModel) {
this.inputConverter = new ObjectDetectionInputConverter();
List<String> fetchNames = withMasks ? FETCH_NAMES_WITH_MASKS : FETCH_NAMES;
this.outputConverter = new ObjectDetectionOutputConverter(
new DefaultResourceLoader().getResource(labelsUri), confidence, fetchNames);
this.tensorFlowService = new TensorFlowService(
new DefaultResourceLoader().getResource(modelUri), fetchNames, cacheModel);
this.outputConverter = new ObjectDetectionOutputConverter(new DefaultResourceLoader().getResource(labelsUri),
confidence, fetchNames);
this.tensorFlowService = new TensorFlowService(new DefaultResourceLoader().getResource(modelUri), fetchNames,
cacheModel);
}
/**
* Generic constructor thea allow the converter to be pre-configured before passed to the service.
* @param inputConverter Converter from byte array to object detection input image tensor
* @param outputConverter Covets the object detection output tensors into {@link ObjectDetection } list
* Generic constructor thea allow the converter to be pre-configured before passed to
* the service.
* @param inputConverter Converter from byte array to object detection input image
* tensor
* @param outputConverter Covets the object detection output tensors into
* {@link ObjectDetection } list
* @param tensorFlowService Java tensorflow runner instance
*/
public ObjectDetectionService(ObjectDetectionInputConverter inputConverter,
@@ -100,9 +113,9 @@ public class ObjectDetectionService {
/**
* Detects objects in a single input image identified by its URI.
*
* @param imageUri input image's URI
* @return Returns a list of {@link ObjectDetection} domain objects representing detected objects
* @return Returns a list of {@link ObjectDetection} domain objects representing
* detected objects
*/
public List<ObjectDetection> detect(String imageUri) {
try (InputStream is = new DefaultResourceLoader().getResource(imageUri).getInputStream()) {
@@ -116,10 +129,11 @@ public class ObjectDetectionService {
/**
* Detects objects in a single {@link BufferedImage}.
*
* @param image Input image to detect objects from.
* @param format Image format (e.g. jpg, png ...) to use when converting the buffer into byte array.
* @return Returns a list of {@link ObjectDetection} domain objects representing detected objects in the input image
* @param format Image format (e.g. jpg, png ...) to use when converting the buffer
* into byte array.
* @return Returns a list of {@link ObjectDetection} domain objects representing
* detected objects in the input image
*/
public List<ObjectDetection> detect(BufferedImage image, String format) {
return this.detect(GraphicsUtils.toImageByteArray(image, format));
@@ -127,21 +141,27 @@ public class ObjectDetectionService {
/**
* Detects objects from a single input image encoded as byte array.
*
* @param image Input image encoded as byte array
* @return Returns a list of {@link ObjectDetection} domain objects representing detected objects in the input image
* @return Returns a list of {@link ObjectDetection} domain objects representing
* detected objects in the input image
*/
public List<ObjectDetection> detect(byte[] image) {
return this.inputConverter.andThen(this.tensorFlowService).andThen(this.outputConverter).apply(new byte[][] { image }).get(0);
return this.inputConverter.andThen(this.tensorFlowService)
.andThen(this.outputConverter)
.apply(new byte[][] { image })
.get(0);
}
/**
* Uses detects objects from a batch of input images encoded as byte array.
*
* @param batchedImages Batch of input images encoded as byte arrays. First dimension is the batch size and second the image bytes.
* @return Returns list of lists. For every input image in the batch a list of {@link ObjectDetection} domain objects representing detected objects in the input image.
* @param batchedImages Batch of input images encoded as byte arrays. First dimension
* is the batch size and second the image bytes.
* @return Returns list of lists. For every input image in the batch a list of
* {@link ObjectDetection} domain objects representing detected objects in the input
* image.
*/
public List<List<ObjectDetection>> detect(byte[][] batchedImages) {
return this.inputConverter.andThen(this.tensorFlowService).andThen(this.outputConverter).apply(batchedImages);
}
}

View File

@@ -40,35 +40,34 @@ import org.springframework.core.io.DefaultResourceLoader;
public class ObjectDetectionService2 implements AutoCloseable {
/** Default Box models fetch names. */
public static List<String> FETCH_NAMES = Arrays.asList(
ObjectDetectionOutputConverter.DETECTION_SCORES, ObjectDetectionOutputConverter.DETECTION_CLASSES,
ObjectDetectionOutputConverter.DETECTION_BOXES, ObjectDetectionOutputConverter.NUM_DETECTIONS);
/** Default Models models fetch names. */
public static List<String> FETCH_NAMES_WITH_MASKS = Arrays.asList(
ObjectDetectionOutputConverter.DETECTION_SCORES, ObjectDetectionOutputConverter.DETECTION_CLASSES,
ObjectDetectionOutputConverter.DETECTION_BOXES, ObjectDetectionOutputConverter.DETECTION_MASKS,
public static List<String> FETCH_NAMES = Arrays.asList(ObjectDetectionOutputConverter.DETECTION_SCORES,
ObjectDetectionOutputConverter.DETECTION_CLASSES, ObjectDetectionOutputConverter.DETECTION_BOXES,
ObjectDetectionOutputConverter.NUM_DETECTIONS);
private final GraphRunner imageNormalization;
private final GraphRunner objectDetection;
private final ObjectDetectionOutputConverter outputConverter;
/** Default Models models fetch names. */
public static List<String> FETCH_NAMES_WITH_MASKS = Arrays.asList(ObjectDetectionOutputConverter.DETECTION_SCORES,
ObjectDetectionOutputConverter.DETECTION_CLASSES, ObjectDetectionOutputConverter.DETECTION_BOXES,
ObjectDetectionOutputConverter.DETECTION_MASKS, ObjectDetectionOutputConverter.NUM_DETECTIONS);
private final GraphRunner imageNormalization;
private final GraphRunner objectDetection;
private final ObjectDetectionOutputConverter outputConverter;
public ObjectDetectionService2(String modelUri, ObjectDetectionOutputConverter outputConverter) {
this.imageNormalization = new GraphRunner("raw_image", "normalized_image")
.withGraphDefinition(tf -> {
Placeholder<String> rawImage = tf.withName("raw_image").placeholder(String.class);
Operand<UInt8> decodedImage = tf.dtypes.cast(
tf.image.decodeJpeg(rawImage, DecodeJpeg.channels(3L)), UInt8.class);
// Expand dimensions since the model expects images to have shape: [1, H, W, 3]
tf.withName("normalized_image").expandDims(decodedImage, tf.constant(0));
});
this.imageNormalization = new GraphRunner("raw_image", "normalized_image").withGraphDefinition(tf -> {
Placeholder<String> rawImage = tf.withName("raw_image").placeholder(String.class);
Operand<UInt8> decodedImage = tf.dtypes.cast(tf.image.decodeJpeg(rawImage, DecodeJpeg.channels(3L)),
UInt8.class);
// Expand dimensions since the model expects images to have shape: [1, H, W,
// 3]
tf.withName("normalized_image").expandDims(decodedImage, tf.constant(0));
});
this.objectDetection = new GraphRunner(Arrays.asList("image_tensor"), FETCH_NAMES)
.withGraphDefinition(new ProtoBufGraphDefinition(
new DefaultResourceLoader().getResource(modelUri), true));
.withGraphDefinition(new ProtoBufGraphDefinition(new DefaultResourceLoader().getResource(modelUri), true));
this.outputConverter = outputConverter;
}
@@ -77,9 +76,10 @@ public class ObjectDetectionService2 implements AutoCloseable {
try (Tensor inputTensor = Tensor.create(image); GraphRunnerMemory memorize = new GraphRunnerMemory()) {
List<List<ObjectDetection>> out = this.imageNormalization.andThen(memorize)
.andThen(this.objectDetection).andThen(memorize)
.andThen(outputConverter)
.apply(Collections.singletonMap("raw_image", inputTensor));
.andThen(this.objectDetection)
.andThen(memorize)
.andThen(outputConverter)
.apply(Collections.singletonMap("raw_image", inputTensor));
return out.get(0);
@@ -90,7 +90,7 @@ public class ObjectDetectionService2 implements AutoCloseable {
public void close() {
this.imageNormalization.close();
this.objectDetection.close();
//this.outputConverter.close();
// this.outputConverter.close();
}
public static void main(String[] args) throws IOException {
@@ -100,7 +100,8 @@ public class ObjectDetectionService2 implements AutoCloseable {
ObjectDetectionOutputConverter outputAdapter = new ObjectDetectionOutputConverter(
new DefaultResourceLoader().getResource(labelUri), 0.4f, FETCH_NAMES);
//byte[] inputImage = GraphicsUtils.loadAsByteArray("classpath:/images/object-detection.jpg");
// byte[] inputImage =
// GraphicsUtils.loadAsByteArray("classpath:/images/object-detection.jpg");
byte[] inputImage = GraphicsUtils.loadAsByteArray("classpath:/images/wild-animals-15.jpg");
try (ObjectDetectionService2 objectDetectionService2 = new ObjectDetectionService2(modelUri, outputAdapter)) {
@@ -110,4 +111,5 @@ public class ObjectDetectionService2 implements AutoCloseable {
System.out.println(boza);
}
}
}

View File

@@ -28,12 +28,19 @@ import com.fasterxml.jackson.annotation.JsonInclude;
public class ObjectDetection {
private String name;
private float confidence;
private float x1;
private float y1;
private float x2;
private float y2;
private float[][] mask;
private int cid;
public String getName() {
@@ -102,15 +109,8 @@ public class ObjectDetection {
@Override
public String toString() {
return "ObjectDetection{" +
"name='" + name + '\'' +
", confidence=" + confidence +
", x1=" + x1 +
", y1=" + y1 +
", x2=" + x2 +
", y2=" + y2 +
", mask=" + Arrays.toString(mask) +
", cid=" + cid +
'}';
return "ObjectDetection{" + "name='" + name + '\'' + ", confidence=" + confidence + ", x1=" + x1 + ", y1=" + y1
+ ", x2=" + x2 + ", y2=" + y2 + ", mask=" + Arrays.toString(mask) + ", cid=" + cid + '}';
}
}

View File

@@ -32,15 +32,15 @@ import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
/**
* 4 of the pre-trained model in the model zoo (https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md)
* 4 of the pre-trained model in the model zoo
* (https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md)
* can also compute the masks of the detected objects, providing instance segmentation.
* <p>
* Here are the models that can be used for instance segmentation.
* <p>
* mask_rcnn_inception_resnet_v2_atrous_coco 771 36 Masks
* mask_rcnn_inception_v2_coco 79 25 Masks
* mask_rcnn_resnet101_atrous_coco 470 33 Masks
* mask_rcnn_resnet50_atrous_coco 343 29 Masks
* mask_rcnn_inception_resnet_v2_atrous_coco 771 36 Masks mask_rcnn_inception_v2_coco 79
* 25 Masks mask_rcnn_resnet101_atrous_coco 470 33 Masks mask_rcnn_resnet50_atrous_coco
* 343 29 Masks
*
* @author Christian Tzolov
*/
@@ -50,44 +50,53 @@ public class ExampleInstanceSegmentation {
ResourceLoader resourceLoader = new DefaultResourceLoader();
// You can download pre-trained models directly from the zoo: https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md
// Just use the notation <zoo model tar.gz url>#<name of the frozen model file name>
// For performance reasons you may consider downloading the model locally and use the file:/<path to my model> URI instead!
// You can download pre-trained models directly from the zoo:
// https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md
// Just use the notation <zoo model tar.gz url>#<name of the frozen model file
// name>
// For performance reasons you may consider downloading the model locally and use
// the file:/<path to my model> URI instead!
String model = "https://download.tensorflow.org/models/object_detection/mask_rcnn_inception_resnet_v2_atrous_coco_2018_01_28.tar.gz#frozen_inference_graph.pb";
// All labels for the pre-trained models are available at:
// https://github.com/tensorflow/models/tree/master/research/object_detection/data
// Use the labels applicable for the model.
// Also, for performance reasons you may consider to download the labels and load them from file: instead.
// Also, for performance reasons you may consider to download the labels and load
// them from file: instead.
String labels = "https://raw.githubusercontent.com/tensorflow/models/master/research/object_detection/data/mscoco_label_map.pbtxt";
// You can cache the TF model on the local file system to improve the bootstrap performance on consecutive runs!
// You can cache the TF model on the local file system to improve the bootstrap
// performance on consecutive runs!
boolean CACHE_TF_MODEL = true;
// For the pre-trained models fromMemory mask you can set the INSTANCE_SEGMENTATION to enable object instance segmentation as well
// For the pre-trained models fromMemory mask you can set the
// INSTANCE_SEGMENTATION to enable object instance segmentation as well
boolean INSTANCE_SEGMENTATION = true;
// Only object fromMemory confidence above the threshold are returned
float CONFIDENCE_THRESHOLD = 0.4f;
ObjectDetectionService detectionService =
new ObjectDetectionService(model, labels, CONFIDENCE_THRESHOLD, INSTANCE_SEGMENTATION, CACHE_TF_MODEL);
ObjectDetectionService detectionService = new ObjectDetectionService(model, labels, CONFIDENCE_THRESHOLD,
INSTANCE_SEGMENTATION, CACHE_TF_MODEL);
// You can use file:, http: or classpath: to provide the path to the input image.
byte[] image = GraphicsUtils.loadAsByteArray("classpath:/images/object-detection.jpg");
// Returns a list ObjectDetection domain classes to allow programmatic accesses to the detected objects's metadata
// Returns a list ObjectDetection domain classes to allow programmatic accesses to
// the detected objects's metadata
List<ObjectDetection> detectedObjects = detectionService.detect(image);
// Get JSON representation of the detected objects
String jsonObjectDetections = new JsonMapperFunction().apply(detectedObjects);
System.out.println(jsonObjectDetections);
// Draw the detected object metadata on top of the original image and store the result
// Draw the detected object metadata on top of the original image and store the
// result
byte[] annotatedImage = new ObjectDetectionImageAugmenter(INSTANCE_SEGMENTATION).apply(image, detectedObjects);
File projectDir = new File("functions/function/object-detection-function");
File output = new File(projectDir, "target/object-detection-segmentation-augmented.jpg");
IOUtils.write(annotatedImage, new FileOutputStream(output));
System.out.println("Created:" + output.getPath());
}
}

View File

@@ -37,31 +37,40 @@ public class ExampleObjectDetection {
public static void main(String[] args) throws IOException {
// You can download pre-trained models directly from the zoo: https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md
// Just use the notation <zoo model tar.gz url>#<name of the frozen model file name>
// For performance reasons you may consider downloading the model locally and use the file:/<path to my model> URI instead!
// You can download pre-trained models directly from the zoo:
// https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md
// Just use the notation <zoo model tar.gz url>#<name of the frozen model file
// name>
// For performance reasons you may consider downloading the model locally and use
// the file:/<path to my model> URI instead!
String model = "https://download.tensorflow.org/models/object_detection/faster_rcnn_nas_coco_2018_01_28.tar.gz#frozen_inference_graph.pb";
//Resource model = resourceLoader.getResource("https://download.tensorflow.org/models/object_detection/faster_rcnn_resnet101_fgvc_2018_07_19.tar.gz#frozen_inference_graph.pb");
//Resource model = resourceLoader.getResource("https://download.tensorflow.org/models/object_detection/faster_rcnn_resnet50_fgvc_2018_07_19.tar.gz#frozen_inference_graph.pb");
// Resource model =
// resourceLoader.getResource("https://download.tensorflow.org/models/object_detection/faster_rcnn_resnet101_fgvc_2018_07_19.tar.gz#frozen_inference_graph.pb");
// Resource model =
// resourceLoader.getResource("https://download.tensorflow.org/models/object_detection/faster_rcnn_resnet50_fgvc_2018_07_19.tar.gz#frozen_inference_graph.pb");
// All labels for the pre-trained models are available at:
// https://github.com/tensorflow/models/tree/master/research/object_detection/data
// Use the labels applicable for the model.
// Also, for performance reasons you may consider to download the labels and load them from file: instead.
// Also, for performance reasons you may consider to download the labels and load
// them from file: instead.
String labels = "https://raw.githubusercontent.com/tensorflow/models/master/research/object_detection/data/mscoco_label_map.pbtxt";
//Resource labels = resourceLoader.getResource("https://raw.githubusercontent.com/tensorflow/models/master/research/object_detection/data/fgvc_2854_classes_label_map.pbtxt");
// Resource labels =
// resourceLoader.getResource("https://raw.githubusercontent.com/tensorflow/models/master/research/object_detection/data/fgvc_2854_classes_label_map.pbtxt");
// You can cache the TF model on the local file system to improve the bootstrap performance on consecutive runs!
// You can cache the TF model on the local file system to improve the bootstrap
// performance on consecutive runs!
boolean CACHE_TF_MODEL = true;
// For the pre-trained models fromMemory mask you can set the INSTANCE_SEGMENTATION to enable object instance segmentation as well
// For the pre-trained models fromMemory mask you can set the
// INSTANCE_SEGMENTATION to enable object instance segmentation as well
boolean NO_INSTANCE_SEGMENTATION = false;
// Only object fromMemory confidence above the threshold are returned
float CONFIDENCE_THRESHOLD = 0.4f;
ObjectDetectionService detectionService =
new ObjectDetectionService(model, labels, CONFIDENCE_THRESHOLD, NO_INSTANCE_SEGMENTATION, CACHE_TF_MODEL);
ObjectDetectionService detectionService = new ObjectDetectionService(model, labels, CONFIDENCE_THRESHOLD,
NO_INSTANCE_SEGMENTATION, CACHE_TF_MODEL);
// You can use file:, http: or classpath: to provide the path to the input image.
String inputImageUri = "classpath:/images/object-detection.jpg";
@@ -69,16 +78,21 @@ public class ExampleObjectDetection {
byte[] image = StreamUtils.copyToByteArray(is);
// Returns a list ObjectDetection domain classes to allow programmatic accesses to the detected objects's metadata
// Returns a list ObjectDetection domain classes to allow programmatic
// accesses to the detected objects's metadata
List<ObjectDetection> detectedObjects = detectionService.detect(image);
// Get JSON representation of the detected objects
String jsonObjectDetections = new JsonMapperFunction().apply(detectedObjects);
System.out.println(jsonObjectDetections);
// Draw the detected object metadata on top of the original image and store the result
byte[] annotatedImage = new ObjectDetectionImageAugmenter(NO_INSTANCE_SEGMENTATION).apply(image, detectedObjects);
IOUtils.write(annotatedImage, new FileOutputStream("./object-detection-function/target/object-detection-augmented.jpg"));
// Draw the detected object metadata on top of the original image and store
// the result
byte[] annotatedImage = new ObjectDetectionImageAugmenter(NO_INSTANCE_SEGMENTATION).apply(image,
detectedObjects);
IOUtils.write(annotatedImage,
new FileOutputStream("./object-detection-function/target/object-detection-augmented.jpg"));
}
}
}

View File

@@ -16,7 +16,6 @@
package org.springframework.cloud.fn.object.detection.examples;
import java.util.List;
import org.springframework.cloud.fn.object.detection.ObjectDetectionService;
@@ -28,15 +27,30 @@ import org.springframework.cloud.fn.object.detection.domain.ObjectDetection;
public class SimpleExample {
public static void main(String[] args) {
// Select a pre-trained model from the model zoo: https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md
// Just use the notation <model zoo url>#<name of the frozen model file in the zoo's tar.gz>
// Select a pre-trained model from the model zoo:
// https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md
// Just use the notation <model zoo url>#<name of the frozen model file in the
// zoo's tar.gz>
String model = "https://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_ppn_shared_box_predictor_300x300_coco14_sync_2018_07_03.tar.gz#frozen_inference_graph.pb";
// All labels for the pre-trained models are available at: https://github.com/tensorflow/models/tree/master/research/object_detection/data
// All labels for the pre-trained models are available at:
// https://github.com/tensorflow/models/tree/master/research/object_detection/data
String labels = "https://raw.githubusercontent.com/tensorflow/models/master/research/object_detection/data/mscoco_label_map.pbtxt";
ObjectDetectionService detectionService = new ObjectDetectionService(model, labels,
0.4f, // Only object fromMemory confidence above the threshold are returned. Confidence range is [0, 1].
ObjectDetectionService detectionService = new ObjectDetectionService(model, labels, 0.4f, // Only
// object
// fromMemory
// confidence
// above
// the
// threshold
// are
// returned.
// Confidence
// range
// is
// [0,
// 1].
false, // No instance segmentation
true); // cache the TF model locally
@@ -44,4 +58,5 @@ public class SimpleExample {
List<ObjectDetection> detectedObjects = detectionService.detect("classpath:/images/object-detection.jpg");
detectedObjects.stream().map(o -> o.toString()).forEach(System.out::println);
}
}