@@ -6,7 +6,7 @@ import ai.djl.modality.cv.Image;
|
|||||||
import ai.djl.modality.cv.ImageFactory;
|
import ai.djl.modality.cv.ImageFactory;
|
||||||
import ai.djl.translate.TranslateException;
|
import ai.djl.translate.TranslateException;
|
||||||
import cn.heavenlybook.utils.AnimalsClassification;
|
import cn.heavenlybook.utils.AnimalsClassification;
|
||||||
import cn.heavenlybook.utils.OpenCVImageUtil;
|
import cn.heavenlybook.utils.OpenCvImageUtil;
|
||||||
import lombok.extern.java.Log;
|
import lombok.extern.java.Log;
|
||||||
import org.bytedeco.javacv.CanvasFrame;
|
import org.bytedeco.javacv.CanvasFrame;
|
||||||
import org.bytedeco.javacv.Frame;
|
import org.bytedeco.javacv.Frame;
|
||||||
@@ -48,7 +48,7 @@ public class Main {
|
|||||||
while (canvas.isVisible() && (frame = grabber.grab()) != null) {
|
while (canvas.isVisible() && (frame = grabber.grab()) != null) {
|
||||||
// 将获取的frame转化成mat数据类型
|
// 将获取的frame转化成mat数据类型
|
||||||
Mat img = converter.convert(frame);
|
Mat img = converter.convert(frame);
|
||||||
BufferedImage buffImg = OpenCVImageUtil.mat2BufferedImage(img);
|
BufferedImage buffImg = OpenCvImageUtil.mat2BufferedImage(img);
|
||||||
Image image = ImageFactory.getInstance().fromImage(buffImg);
|
Image image = ImageFactory.getInstance().fromImage(buffImg);
|
||||||
Classifications classifications = AnimalsClassification.predict(image);
|
Classifications classifications = AnimalsClassification.predict(image);
|
||||||
Classifications.Classification bestItem = classifications.best();
|
Classifications.Classification bestItem = classifications.best();
|
||||||
@@ -56,7 +56,7 @@ public class Main {
|
|||||||
log.info(classifications.toJson());
|
log.info(classifications.toJson());
|
||||||
// 显示视频图像
|
// 显示视频图像
|
||||||
canvas.showImage(frame);
|
canvas.showImage(frame);
|
||||||
if (bestItem.getProbability() == 1.0 && !"非动物".equals(bestItem.getClassName())) {
|
if (bestItem.getProbability() < 0.00001 && !"非动物".equals(bestItem.getClassName())) {
|
||||||
File outPutFile = Paths.get("src/test/resources/coffee" + i++ + ".png").toFile();
|
File outPutFile = Paths.get("src/test/resources/coffee" + i++ + ".png").toFile();
|
||||||
if (buffImg != null) {
|
if (buffImg != null) {
|
||||||
if (!outPutFile.exists()) {
|
if (!outPutFile.exists()) {
|
||||||
|
|||||||
@@ -42,34 +42,28 @@ public class AnimalTranslator implements Translator<Image, Classifications> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NDList processInput(TranslatorContext ctx, Image input) throws Exception {
|
public NDList processInput(TranslatorContext ctx, Image input) {
|
||||||
NDArray array = input.toNDArray(ctx.getNDManager(), Image.Flag.COLOR);
|
NDArray array = input.toNDArray(ctx.getNDManager(), Image.Flag.COLOR);
|
||||||
|
|
||||||
float percent = 256f / Math.min(input.getWidth(), input.getHeight());
|
float percent = 256f / Math.min(input.getWidth(), input.getHeight());
|
||||||
int resizedWidth = Math.round(input.getWidth() * percent);
|
int resizedWidth = Math.round(input.getWidth() * percent);
|
||||||
int resizedHeight = Math.round(input.getHeight() * percent);
|
int resizedHeight = Math.round(input.getHeight() * percent);
|
||||||
// img = img.resize((resizedWidth, resizedHeight), Image.LANCZOS)
|
// img = img.resize((resizedWidth, resizedHeight), Image.LANCZOS)
|
||||||
|
|
||||||
array = NDImageUtils.resize(array, resizedWidth, resizedHeight);
|
array = NDImageUtils.resize(array, resizedWidth, resizedHeight);
|
||||||
array = NDImageUtils.centerCrop(array, 224, 224);
|
array = NDImageUtils.centerCrop(array, 224, 224);
|
||||||
|
|
||||||
// The network by default takes float32
|
// The network by default takes float32
|
||||||
if (!array.getDataType().equals(DataType.FLOAT32)) {
|
if (!array.getDataType().equals(DataType.FLOAT32)) {
|
||||||
array = array.toType(DataType.FLOAT32, false);
|
array = array.toType(DataType.FLOAT32, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
array = array.transpose(2, 0, 1).div(255f); // HWC -> CHW RGB
|
// HWC -> CHW RGB
|
||||||
|
array = array.transpose(2, 0, 1).div(255f);
|
||||||
NDArray mean =
|
NDArray mean =
|
||||||
ctx.getNDManager().create(new float[] {0.485f, 0.456f, 0.406f}, new Shape(3, 1, 1));
|
ctx.getNDManager().create(new float[] {0.485f, 0.456f, 0.406f}, new Shape(3, 1, 1));
|
||||||
NDArray std =
|
NDArray std =
|
||||||
ctx.getNDManager().create(new float[] {0.229f, 0.224f, 0.225f}, new Shape(3, 1, 1));
|
ctx.getNDManager().create(new float[] {0.229f, 0.224f, 0.225f}, new Shape(3, 1, 1));
|
||||||
|
|
||||||
array = array.sub(mean);
|
array = array.sub(mean);
|
||||||
array = array.div(std);
|
array = array.div(std);
|
||||||
|
|
||||||
array = array.expandDims(0);
|
array = array.expandDims(0);
|
||||||
|
|
||||||
return new NDList(array);
|
return new NDList(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
package cn.heavenlybook.utils;
|
|
||||||
|
|
||||||
import ai.djl.modality.cv.Image;
|
|
||||||
import ai.djl.modality.cv.output.BoundingBox;
|
|
||||||
import ai.djl.modality.cv.output.DetectedObjects;
|
|
||||||
import ai.djl.modality.cv.output.Rectangle;
|
|
||||||
import ai.djl.modality.cv.util.NDImageUtils;
|
|
||||||
import ai.djl.ndarray.NDArray;
|
|
||||||
import ai.djl.ndarray.NDList;
|
|
||||||
import ai.djl.ndarray.NDManager;
|
|
||||||
import ai.djl.ndarray.types.Shape;
|
|
||||||
import ai.djl.repository.zoo.Criteria;
|
|
||||||
import ai.djl.training.util.ProgressBar;
|
|
||||||
import ai.djl.translate.Batchifier;
|
|
||||||
import ai.djl.translate.Translator;
|
|
||||||
import ai.djl.translate.TranslatorContext;
|
|
||||||
import lombok.extern.java.Log;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author ht
|
|
||||||
*/
|
|
||||||
@Log
|
|
||||||
public final class FaceDetection {
|
|
||||||
|
|
||||||
public FaceDetection() {}
|
|
||||||
|
|
||||||
public Criteria<Image, DetectedObjects> criteria(float shrink, float threshold) {
|
|
||||||
Criteria<Image, DetectedObjects> criteria =
|
|
||||||
Criteria.builder()
|
|
||||||
.optEngine("PaddlePaddle")
|
|
||||||
.setTypes(Image.class, DetectedObjects.class)
|
|
||||||
.optModelUrls(
|
|
||||||
"https://aias-home.oss-cn-beijing.aliyuncs.com/models/face_mask/face_detection.zip")
|
|
||||||
// .optModelUrls("/Users/calvin/model/face_mask/pyramidbox_lite/")
|
|
||||||
// .optModelName("inference")
|
|
||||||
.optProgress(new ProgressBar())
|
|
||||||
.optTranslator(new FaceTranslator(shrink, threshold))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
return criteria;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class FaceTranslator implements Translator<Image, DetectedObjects> {
|
|
||||||
|
|
||||||
private final float shrink;
|
|
||||||
private final float threshold;
|
|
||||||
private final List<String> className;
|
|
||||||
|
|
||||||
FaceTranslator(float shrink, float threshold) {
|
|
||||||
this.shrink = shrink;
|
|
||||||
this.threshold = threshold;
|
|
||||||
className = Arrays.asList("Not Face", "Face");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DetectedObjects processOutput(TranslatorContext ctx, NDList list) {
|
|
||||||
return processImageOutput(list, className, threshold);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NDList processInput(TranslatorContext ctx, Image input) {
|
|
||||||
return processImageInput(ctx.getNDManager(), input, shrink);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Batchifier getBatchifier() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
NDList processImageInput(NDManager manager, Image input, float shrink) {
|
|
||||||
NDArray array = input.toNDArray(manager);
|
|
||||||
Shape shape = array.getShape();
|
|
||||||
array =
|
|
||||||
NDImageUtils.resize(array, (int) (shape.get(1) * shrink), (int) (shape.get(0) * shrink));
|
|
||||||
array = array.transpose(2, 0, 1).flip(0); // HWC -> CHW BGR -> RGB
|
|
||||||
NDArray mean = manager.create(new float[] {104f, 117f, 123f}, new Shape(3, 1, 1));
|
|
||||||
array = array.sub(mean).mul(0.007843f); // normalization
|
|
||||||
array = array.expandDims(0); // make batch dimension
|
|
||||||
return new NDList(array);
|
|
||||||
}
|
|
||||||
|
|
||||||
DetectedObjects processImageOutput(NDList list, List<String> className, float threshold) {
|
|
||||||
NDArray result = list.singletonOrThrow();
|
|
||||||
float[] probabilities = result.get(":,1").toFloatArray();
|
|
||||||
List<String> names = new ArrayList<>();
|
|
||||||
List<Double> prob = new ArrayList<>();
|
|
||||||
List<BoundingBox> boxes = new ArrayList<>();
|
|
||||||
for (int i = 0; i < probabilities.length; i++) {
|
|
||||||
if (probabilities[i] >= threshold) {
|
|
||||||
float[] array = result.get(i).toFloatArray();
|
|
||||||
names.add(className.get((int) array[0]));
|
|
||||||
prob.add((double) probabilities[i]);
|
|
||||||
boxes.add(new Rectangle(array[2], array[3], array[4] - array[2], array[5] - array[3]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new DetectedObjects(names, prob, boxes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
-1
@@ -14,7 +14,7 @@ import java.nio.IntBuffer;
|
|||||||
*
|
*
|
||||||
* @author Calvin
|
* @author Calvin
|
||||||
*/
|
*/
|
||||||
public class OpenCVImageUtil {
|
public class OpenCvImageUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将 BufferedImage 转 Mat
|
* 将 BufferedImage 转 Mat
|
||||||
Reference in New Issue
Block a user