?+S14qiz|Q{O&9a8LR@t2)Q%rlrZfeZ4_|J($Td`Tb4Ciq
zdC=ARs;#{(1J?Cfr!9VZLWb)#ncTO|c>TP_jP>4h)(eNvZzt0xf=>?T
zMeqU#!0D3pTu%@;(-UdsTeK@4mReE1Vi2zAGOsD$ND~%`LYPC^35La0
z>gk8%>jU82xknLJu;D&tGg^C
zWtsgjGYv*u;LRyQ`>Z3-MbE5%@dXv{p3Onja-&mmM1ZWH#kQuxeXUojD8D%R&CmSG
zSqxdboFRLGj;-8!m!8y!+KbhSQ4^AKAoyKEt)D+?)xAt)6PY?26A+8RJv5m$*Mr9{Sj7(yZ
zg`E79`?hczj7@fTFj`%+ZJsySLGv1$Ja)heKAz^DRmBUf$59-g-(2+)!jTrew)`4{6O*o5VvD-mnoeQp
z*V|X94(kNK>kSL@C(=jy{lK5uPL+X@4xy`FzWksHdy+oHqTsvdOxw?wx2VO<8VV
zwSEuR!GV~dSZR`mmI0%AM@BKjD;^?gr94xj+l?*gHjgwvium8_NU=6^jo=f2_LLz
z`1Ayv02@zBw#$8?fRBG9{Lu)H(bg({^7*Ia#7GtJThE~cF)!xI<)v@StLk(yKrw{T
zR`Zxb@8Ls2`FapaPr_HIl
zch(VY0?AWp2-VKyRXLb%A@w0sT$;Hd1a`7rFTTgx;3?4M_0k`9*KQx&+GnzQ%wG{?
z{QRTdzIF8uSU4%XSPXYNgf2ZO=M)vG3)
zaXC>`EEaFnCEn*T8b%vI7o*qMj$TVXyRqSCjys0l28PPO-3i8)lL05ueItX6A61QW
z{poWI2I-f8s@Y-rQ?oBe{8#FY35%x2pv
zlRG~SYTXaxBD0OWhp@%-WN63F(94*wQ|p?Lt8$W-p@)2^xIW6t+Rj+3gLmQFm@v+*
z^JUfi)tEi?d+-6qT*KUs_YwoZH}Ov{jT6d!$3HvMcyF{VqEE$Q%c)4xg`PVP!uzZ3
z`-i7{X8Zm%{xtT^OyFOkKYOfartgoCJAM2U`jZ9xE5pwYk(h;?Cy%
zk@T5>`w@bt-G9FMUv}a@f&ZGe%fEwv)06+iaOOS!h|0fV_|u8}mFj05f95>?h@=0F
z>USUVSH_q>5u;O-|f)i
z;Ys7^*w}k}+FG9#b~c;4Y>IHWwU-;hiS3VmHw2rbmzTS=h={MRudwy+!@{<1uKxp@
Cv2C{i
diff --git a/4_video_sdks/camera_face_sdk/pom.xml b/4_video_sdks/camera_face_sdk/pom.xml
index f49d999e..138b8a96 100644
--- a/4_video_sdks/camera_face_sdk/pom.xml
+++ b/4_video_sdks/camera_face_sdk/pom.xml
@@ -31,7 +31,7 @@
UTF-8
1.8
1.8
- 0.13.0
+ 0.14.0
@@ -94,7 +94,7 @@
ai.djl.pytorch
pytorch-native-auto
- 1.9.0
+ 1.9.1
@@ -113,13 +113,6 @@
paddlepaddle-model-zoo
${djl.version}
-
- aias
- face-lib
- 0.1.0
- system
- ${project.basedir}/lib/aias-face-lib-0.1.0.jar
-
org.bytedeco
javacv-platform
diff --git a/4_video_sdks/camera_face_sdk/src/main/java/me/calvin/example/CameraFaceDetectionExample.java b/4_video_sdks/camera_face_sdk/src/main/java/me/calvin/example/CameraFaceDetectionExample.java
index 2e02416a..6660ce21 100644
--- a/4_video_sdks/camera_face_sdk/src/main/java/me/calvin/example/CameraFaceDetectionExample.java
+++ b/4_video_sdks/camera_face_sdk/src/main/java/me/calvin/example/CameraFaceDetectionExample.java
@@ -11,7 +11,7 @@ import ai.djl.repository.zoo.Criteria;
import ai.djl.repository.zoo.ModelZoo;
import ai.djl.repository.zoo.ZooModel;
import ai.djl.translate.TranslateException;
-import me.aias.FaceDetection;
+import me.calvin.example.utils.FaceDetection;
import me.calvin.example.utils.OpenCVImageUtil;
import org.bytedeco.javacv.CanvasFrame;
import org.bytedeco.javacv.Frame;
diff --git a/4_video_sdks/camera_face_sdk/src/main/java/me/calvin/example/utils/FaceDetection.java b/4_video_sdks/camera_face_sdk/src/main/java/me/calvin/example/utils/FaceDetection.java
new file mode 100644
index 00000000..cee49203
--- /dev/null
+++ b/4_video_sdks/camera_face_sdk/src/main/java/me/calvin/example/utils/FaceDetection.java
@@ -0,0 +1,104 @@
+package me.calvin.example.utils;
+
+import ai.djl.Device;
+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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public final class FaceDetection {
+
+ private static final Logger logger = LoggerFactory.getLogger(FaceDetection.class);
+
+ public FaceDetection() {}
+
+ public Criteria criteria(float shrink, float threshold) {
+ Criteria 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())
+ .optDevice(Device.cpu())
+ .optTranslator(new FaceTranslator(shrink, threshold))
+ .build();
+
+ return criteria;
+ }
+
+ private final class FaceTranslator implements Translator {
+
+ private float shrink;
+ private float threshold;
+ private List 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 className, float threshold) {
+ NDArray result = list.singletonOrThrow();
+ float[] probabilities = result.get(":,1").toFloatArray();
+ List names = new ArrayList<>();
+ List prob = new ArrayList<>();
+ List 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);
+ }
+ }
+}
diff --git a/4_video_sdks/camera_facemask_sdk/camera-facemask-sdk.iml b/4_video_sdks/camera_facemask_sdk/camera-facemask-sdk.iml
new file mode 100644
index 00000000..6278679a
--- /dev/null
+++ b/4_video_sdks/camera_facemask_sdk/camera-facemask-sdk.iml
@@ -0,0 +1,216 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/4_video_sdks/camera_facemask_sdk/lib/aias-mask-lib-0.1.0.jar b/4_video_sdks/camera_facemask_sdk/lib/aias-mask-lib-0.1.0.jar
deleted file mode 100644
index 071e0e430d6fbeefcb7ac3b5488f406c00ebbdd5..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 9200
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
U2VNEycXxMYz`q_do7mg_AH%Ahh5!Hn
diff --git a/4_video_sdks/camera_facemask_sdk/pom.xml b/4_video_sdks/camera_facemask_sdk/pom.xml
index f2714cf9..afcaa435 100644
--- a/4_video_sdks/camera_facemask_sdk/pom.xml
+++ b/4_video_sdks/camera_facemask_sdk/pom.xml
@@ -31,7 +31,7 @@
UTF-8
1.8
1.8
- 0.13.0
+ 0.14.0
@@ -94,14 +94,13 @@
ai.djl.pytorch
pytorch-native-auto
- 1.9.0
+ 1.9.1
ai.djl.paddlepaddle
paddlepaddle-engine
${djl.version}
- runtime
ai.djl.paddlepaddle
@@ -113,13 +112,6 @@
paddlepaddle-model-zoo
${djl.version}
-
- aias
- mask-lib
- 0.1.0
- system
- ${project.basedir}/lib/aias-mask-lib-0.1.0.jar
-
org.bytedeco
javacv-platform
diff --git a/4_video_sdks/camera_facemask_sdk/src/main/java/me/aias/example/CameraFaceMaskDetectionExample.java b/4_video_sdks/camera_facemask_sdk/src/main/java/me/aias/example/CameraFaceMaskDetectionExample.java
index c25e6056..d89734d4 100644
--- a/4_video_sdks/camera_facemask_sdk/src/main/java/me/aias/example/CameraFaceMaskDetectionExample.java
+++ b/4_video_sdks/camera_facemask_sdk/src/main/java/me/aias/example/CameraFaceMaskDetectionExample.java
@@ -12,8 +12,8 @@ import ai.djl.repository.zoo.Criteria;
import ai.djl.repository.zoo.ModelZoo;
import ai.djl.repository.zoo.ZooModel;
import ai.djl.translate.TranslateException;
-import me.aias.FaceDetection;
-import me.aias.FaceMaskDetect;
+import me.aias.example.utils.FaceDetection;
+import me.aias.example.utils.FaceMaskDetect;
import me.aias.example.utils.OpenCVImageUtil;
import org.bytedeco.javacv.CanvasFrame;
import org.bytedeco.javacv.Frame;
@@ -151,7 +151,7 @@ public class CameraFaceMaskDetectionExample {
if (squareBox[1] > height) squareBox[1] = height;
if ((squareBox[0] + squareBox[2]) > width) squareBox[2] = width - squareBox[0];
if ((squareBox[1] + squareBox[2]) > height) squareBox[2] = height - squareBox[1];
- return img.getSubimage(squareBox[0], squareBox[1], squareBox[2], squareBox[2]);
+ return img.getSubImage(squareBox[0], squareBox[1], squareBox[2], squareBox[2]);
// return img.getSubimage(squareBox[0], squareBox[1], squareBox[2], squareBox[3]);
}
}
diff --git a/4_video_sdks/camera_facemask_sdk/src/main/java/me/aias/example/utils/FaceDetection.java b/4_video_sdks/camera_facemask_sdk/src/main/java/me/aias/example/utils/FaceDetection.java
new file mode 100644
index 00000000..f5cfdd48
--- /dev/null
+++ b/4_video_sdks/camera_facemask_sdk/src/main/java/me/aias/example/utils/FaceDetection.java
@@ -0,0 +1,104 @@
+package me.aias.example.utils;
+
+import ai.djl.Device;
+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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public final class FaceDetection {
+
+ private static final Logger logger = LoggerFactory.getLogger(FaceDetection.class);
+
+ public FaceDetection() {}
+
+ public Criteria criteria(float shrink, float threshold) {
+ Criteria 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())
+ .optDevice(Device.cpu())
+ .optTranslator(new FaceTranslator(shrink, threshold))
+ .build();
+
+ return criteria;
+ }
+
+ private final class FaceTranslator implements Translator {
+
+ private float shrink;
+ private float threshold;
+ private List 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 className, float threshold) {
+ NDArray result = list.singletonOrThrow();
+ float[] probabilities = result.get(":,1").toFloatArray();
+ List names = new ArrayList<>();
+ List prob = new ArrayList<>();
+ List 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);
+ }
+ }
+}
diff --git a/4_video_sdks/camera_facemask_sdk/src/main/java/me/aias/example/utils/FaceMaskDetect.java b/4_video_sdks/camera_facemask_sdk/src/main/java/me/aias/example/utils/FaceMaskDetect.java
new file mode 100644
index 00000000..bf6f9d92
--- /dev/null
+++ b/4_video_sdks/camera_facemask_sdk/src/main/java/me/aias/example/utils/FaceMaskDetect.java
@@ -0,0 +1,98 @@
+package me.aias.example.utils;
+
+import ai.djl.Device;
+import ai.djl.inference.Predictor;
+import ai.djl.modality.Classifications;
+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.transform.Normalize;
+import ai.djl.modality.cv.transform.Resize;
+import ai.djl.modality.cv.transform.ToTensor;
+import ai.djl.modality.cv.translator.ImageClassificationTranslator;
+import ai.djl.repository.zoo.Criteria;
+import ai.djl.training.util.ProgressBar;
+import ai.djl.translate.TranslateException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class FaceMaskDetect {
+
+ private static final Logger logger = LoggerFactory.getLogger(FaceMaskDetect.class);
+
+ public FaceMaskDetect() {}
+
+ public DetectedObjects predict(
+ Predictor faceDetector,
+ Predictor classifier,
+ Image image)
+ throws TranslateException {
+
+ DetectedObjects detections = faceDetector.predict(image);
+ List faces = detections.items();
+
+ List names = new ArrayList<>();
+ List prob = new ArrayList<>();
+ List rect = new ArrayList<>();
+ for (DetectedObjects.DetectedObject face : faces) {
+ Image subImg = getSubImage(image, face.getBoundingBox());
+ Classifications classifications = classifier.predict(subImg);
+ names.add(classifications.best().getClassName());
+ prob.add(face.getProbability());
+ rect.add(face.getBoundingBox());
+ }
+
+ return new DetectedObjects(names, prob, rect);
+ }
+
+ public Criteria criteria() {
+ Criteria criteria =
+ Criteria.builder()
+ .optEngine("PaddlePaddle")
+ .setTypes(Image.class, Classifications.class)
+ .optTranslator(
+ ImageClassificationTranslator.builder()
+ .addTransform(new Resize(128, 128))
+ .addTransform(new ToTensor()) // HWC -> CHW div(255)
+ .addTransform(
+ new Normalize(
+ new float[] {0.5f, 0.5f, 0.5f}, new float[] {1.0f, 1.0f, 1.0f}))
+ .addTransform(nd -> nd.flip(0)) // RGB -> GBR
+ .build())
+ .optModelUrls(
+ "https://aias-home.oss-cn-beijing.aliyuncs.com/models/face_mask/face_mask.zip")
+ .optProgress(new ProgressBar())
+ .optDevice(Device.cpu())
+ .build();
+
+ return criteria;
+ }
+
+ private int[] extendSquare(
+ double xmin, double ymin, double width, double height, double percentage) {
+ double centerx = xmin + width / 2;
+ double centery = ymin + height / 2;
+ double maxDist = Math.max(width / 2, height / 2) * (1 + percentage);
+ return new int[] {(int) (centerx - maxDist), (int) (centery - maxDist), (int) (2 * maxDist)};
+ // return new int[] {(int) xmin, (int) ymin, (int) width, (int) height};
+ }
+
+ private Image getSubImage(Image img, BoundingBox box) {
+ Rectangle rect = box.getBounds();
+ int width = img.getWidth();
+ int height = img.getHeight();
+ int[] squareBox =
+ extendSquare(
+ rect.getX() * width,
+ rect.getY() * height,
+ rect.getWidth() * width,
+ rect.getHeight() * height,
+ 0); // 0.18
+ return img.getSubImage(squareBox[0], squareBox[1], squareBox[2], squareBox[2]);
+ // return img.getSubimage(squareBox[0], squareBox[1], squareBox[2], squareBox[3]);
+ }
+}
diff --git a/4_video_sdks/mp4_face_sdk/lib/aias-face-lib-0.1.0.jar b/4_video_sdks/mp4_face_sdk/lib/aias-face-lib-0.1.0.jar
deleted file mode 100644
index 65a056bbc60fcdff616590094e226707c0204be3..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 6492
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
Cv2C{i
diff --git a/4_video_sdks/mp4_face_sdk/mp4-face-sdk.iml b/4_video_sdks/mp4_face_sdk/mp4-face-sdk.iml
new file mode 100644
index 00000000..aade2256
--- /dev/null
+++ b/4_video_sdks/mp4_face_sdk/mp4-face-sdk.iml
@@ -0,0 +1,225 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/4_video_sdks/mp4_face_sdk/pom.xml b/4_video_sdks/mp4_face_sdk/pom.xml
index 6fc1fd77..662995ef 100644
--- a/4_video_sdks/mp4_face_sdk/pom.xml
+++ b/4_video_sdks/mp4_face_sdk/pom.xml
@@ -31,7 +31,7 @@
UTF-8
1.8
1.8
- 0.13.0
+ 0.14.0
@@ -94,14 +94,13 @@
ai.djl.pytorch
pytorch-native-auto
- 1.9.0
+ 1.9.1
ai.djl.paddlepaddle
paddlepaddle-engine
${djl.version}
- runtime
ai.djl.paddlepaddle
@@ -113,13 +112,6 @@
paddlepaddle-model-zoo
${djl.version}
-
- aias
- face-lib
- 0.1.0
- system
- ${project.basedir}/lib/aias-face-lib-0.1.0.jar
-
org.bytedeco
javacv-platform
diff --git a/4_video_sdks/mp4_face_sdk/src/main/java/me/aias/example/MP4FaceDetectionExample.java b/4_video_sdks/mp4_face_sdk/src/main/java/me/aias/example/MP4FaceDetectionExample.java
index 5246fd57..d4465385 100644
--- a/4_video_sdks/mp4_face_sdk/src/main/java/me/aias/example/MP4FaceDetectionExample.java
+++ b/4_video_sdks/mp4_face_sdk/src/main/java/me/aias/example/MP4FaceDetectionExample.java
@@ -11,7 +11,7 @@ import ai.djl.repository.zoo.Criteria;
import ai.djl.repository.zoo.ModelZoo;
import ai.djl.repository.zoo.ZooModel;
import ai.djl.translate.TranslateException;
-import me.aias.FaceDetection;
+import me.aias.example.utils.FaceDetection;
import me.aias.example.utils.OpenCVImageUtil;
import org.bytedeco.javacv.CanvasFrame;
import org.bytedeco.javacv.FFmpegFrameGrabber;
diff --git a/4_video_sdks/mp4_face_sdk/src/main/java/me/aias/example/utils/FaceDetection.java b/4_video_sdks/mp4_face_sdk/src/main/java/me/aias/example/utils/FaceDetection.java
new file mode 100644
index 00000000..f5cfdd48
--- /dev/null
+++ b/4_video_sdks/mp4_face_sdk/src/main/java/me/aias/example/utils/FaceDetection.java
@@ -0,0 +1,104 @@
+package me.aias.example.utils;
+
+import ai.djl.Device;
+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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public final class FaceDetection {
+
+ private static final Logger logger = LoggerFactory.getLogger(FaceDetection.class);
+
+ public FaceDetection() {}
+
+ public Criteria criteria(float shrink, float threshold) {
+ Criteria 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())
+ .optDevice(Device.cpu())
+ .optTranslator(new FaceTranslator(shrink, threshold))
+ .build();
+
+ return criteria;
+ }
+
+ private final class FaceTranslator implements Translator {
+
+ private float shrink;
+ private float threshold;
+ private List 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 className, float threshold) {
+ NDArray result = list.singletonOrThrow();
+ float[] probabilities = result.get(":,1").toFloatArray();
+ List names = new ArrayList<>();
+ List prob = new ArrayList<>();
+ List 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);
+ }
+ }
+}
diff --git a/4_video_sdks/mp4_facemask_sdk/lib/aias-mask-lib-0.1.0.jar b/4_video_sdks/mp4_facemask_sdk/lib/aias-mask-lib-0.1.0.jar
deleted file mode 100644
index 071e0e430d6fbeefcb7ac3b5488f406c00ebbdd5..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 9200
zcmbVy1yo$iwk;A|g1b8ehX4VBySrQCjk`kk3Gg7wQJ73M%C_BYt<|zS?Cv75b*Hu5DM11st~^!0>ldld2uyiCTRr;mWM$I
z2xtf;SvdIT9#H@4ru4U9tfwA-faQf1q$R{v)tKcaF6D=Zt*f*LL;UJ8_>^_$ubJfoH;@M!_|mr8dczvBk!NCzjqb!>8Xvq
z1*a7|vxluseoTi!yjrdtyndd#?jD4D!W98UPnNrC*A
zp4vBNG#rnQBUH{60+M1FPX7wCc
znFelf{ZJy4KMRD_c~jV&s!O?bD3r@25QC!LYt1-)#!|2^ygUDK=`h;C-H@nh&QxzT
z2D?1}=1perE`4+GM0q#KHe9Hb79k0PlzE#eSGrNGAm_e;b89SdUA<{+Hkn%fhpHMZ
zjjK*nECw2s3OU?tN{zf8s|?d~;_aQL>lDcfHs<7`Aph|B=`Z-h<^z3`2~A9WQWuKB@+McI7PP>2$84?2G>goFXF?{(nhJQ@AEx^spj^+RRYxyS}
z00cPyR~*Fu(}jO<*aDobnQVZ@{}mb4|BcMS-uC%xnbsQlxX6Xpda7C^QIW@Z%H@iy
z0|T=F1%tsU^e*}plcSjzy)qho}L3c`>J1PK`w1a=%;OCVbN^}
z-UQs-MwR)-LmE?QRXKKyQFx|Mw-_
zu}nW`91MRg25f231&yR5y@TmO3M!eVMrUse`0Cggbc)EXGk(M?b3Y1-!8Yy`_^Xmr
zH&a-g-JJf`FsROutL58)vKYN;Squg=Dlr4{QS;VC3<9-;W21-`r>NWW?lO@A4nzhu
zSb2
zB5{bmYzQzx+YiYd+3|T$PENcS1$@$g@p(+3px3#FvKrRf|Tm00Hk6Jx~7
zmDc)4Tr@@O6$MkYm^#K-m$Wriu&JAoou<7$XfI)au&E_M>0YkZ7oAb%?=c83(|_ek
z(XAT4|(ydsUu9pEa*0Udwf>R50l^PO+XPvVp|E`aZ_6KF>D%7{U-0+vJy(vZF89{
z{K)8NS1*yQsDT*QN4t_2-wN>T49MiE>lSC0?G0Cz>Y4#+1`x+HV@;Sx3uYdXixQ>!
zk;Cun)4OLjc3!W4ccpDggqdZ@h!fcmV+=H_WVjb9031&j@blx_Ob~dKNhILX>u~%O
z2CMAvw|Gr_&>Ju1QsaQ_kC-wNPRy$>g1ILc9}f#Gup%6?mV0kNHJK(C7fX=PuVDSH
zntNW;TKM9gQ->H$Vyysa<0k=oD7UX|Q_43lL&z_$!#_-|a1V`h9>}rRm6Y{qb2Mwj
z*@$r{y(iUNo@hn4UqY5A{BVxmC(@mMVCQc_Klwpn@`M7G>no2=?Z{_$@CU-uzUt+b
zM0v%Fq1vFJaDrf|UdFqtGuj&$A2CVtas(oKEGP4ID>&Qrqxl$Boybp-pkM3#{@CK`YV-Z!Y16Fz%EQIxv0&Ts{Vmv=-%UaW
z4@4S-<2diQGch!yIIJmI7EmMHdedPMeY&G0!q+l};c`@VpH
zn8W)|;rZ47OE`0IvUf0Zasiq-tGX$U$TG<=O3N!tm8hM`Gs=!^s-VJM+{MXaMGRvj
zN0vtnmqjpQr3Z*&MIc8YHx8?;#al7m+c=W7C82&b_hGC3!;D0>{`h?HVug^VfZDV*d|VfzAkm0!r14OM5DZP;M~ZK7hR
z)d}!v<)N|Yf}&4cKGes%ATa4?eWOW#AwzGw@5FPrxB77U=6-Q%Ds$?pl{>af3u#BK
zex=!SNWay)?Puo7!)fU(#8Jm5e7z|zC63Q}4tlUA$)O5B4jtCwd>a4iDOInfCDQ2#
zBVz`9&RQLYq_1*sd328QYkl(v_FY6|33gJ9d}#1eW@xVN>&z!TIpVkj$d{=)ygF5)
z7vC8PiVj(|uv3AUP+W!_*sJJ4^|43*rV8DfNEaDUc)@9|eR3-Suu5+zO@bZowG$2f
za-&sIW#>{fyt%pi{)lFTBf(rDx4`@ZQh$5NEx8MjJ6^295o+%m!xGuW8r7Y8PeSXuZ7WarFs
zmzTZeC!FQL(fPuC*)A1~tdV0jAmsj8-~yga*IVe@cIcb;8=YW2~cDc3z&m$@NI)$NbC@r6(~7{2ii
zqcQh%d;h5HE=}8b*ZP7bN_NkPq
zJITf@2bxI;cQHf~Qp;ZF?Nf#@@c2W5h`&u)CSL*hxlNUNVtmPOwdjb{SpxyEkEzZ|
zy>wmrt<&+ImF}|3jxc=={iQg&)pfLocN*?QA-LAR6P2{=CEqe7o|UTu++ZU4P?DH|nfQm)!UE
z6>SQ=REqZ@kMLuk>0w|=vN(!BxloTC(P!6q-{`%jx`WCxIYtla^lOiz#0VM^B_xCq
zKW*@wgEOReU4-)_(wtZuEj(*{_<^SU9^(Yb38<~mQgDx>Y44y=wMh8_0#sGEMnsqT
zf;CYSOQia57=K`o9k?X39$iKT5w0(_5BHrl5Jqh{cQ5H>`p>H3=D>;wMA0@{D@yx%
z?2#fLYC36SvEbw4bKQ0(1ma-&j~S|+!T5w;DelH0e;6EOOa3IV%yZc4U+FYrXrgpA
zACV{%7_m>J|IQ~;GdIJJbvKq$ip2%A99701R2KcQJ&h9HmyT73SyK6=RyQz`j$Q8dU#D
zQPLehLtcxDS+_+5_-$}NHs3sju6UcL4EeY}Qb2P7S*j$|e9S8?($^|r@d#xsUVr#-^?KBCmTWrS>X
zH_*^J1w8wqc`9Dtl~jhdT~ak9CV$xIy(E+-Ue23?-|rALzBstzHd#@Vc!(
zJ5R*R9&*CyRFT)%=k0{b`YFSd8G>^;fSl?bvw<_S=07Z;qB0YCp~S
z{g+C-O;D94Lr`}5Oxd|2{>IW|#cI;PZdpZ<(byj5m>xR<&o9=H?nNysrSA|Rf2#9P
zeKUo8>xNa8ls#J=;d?-F>y?rJQSX3re!7LZa&v*2|G@QgBY5$XCn|m=mA+#f{PfC>
zmrv1qZ(DKUuvz>whVLgxFo8F7_go%k)u$U6usuK7LCx}omX(^0E{0bO3M>7~ced$X
z^29=@eUNnQHtcTwdxd?>
z_$KV%wI8wIzmujnDNImFnfe^@_LX-y!IxcQ)R0vS1#WTeynp%FYd4&Q%R(WBj%PZO
zOqDk_2`=nUG$VM2*@jlVpQnX(&@-p?R=xXBKSsRXcue$XnGZNpXQLtEt<5XF4XJb_
z7i_dI!o*5Q$wpadGDuPa^8&6Nuja#Bs7RYRHEM2B@Tv}9HT
zvW7f+=wWrnNYwLZ6iL;I%XdFAcPVA`gxGakfYhY%Rfq@2DM;wo5cpuB-EkZ`Kr@9&
zXWLMj>#*}kH#i7-y{PKoFnwctBUAKMgMk^;3#c2yx@%0)6>>MJvrSa6_XCXL8VP@R
zxd-ICav__F2)t8YNwQw=RqT)v?GSX`%)aX|n|XcHa5)?8_G?0A@roS8%{JojK;k?$
z=At09N4AXi3=?M$Af%u!lcSc@l3h7d+K{&(?j@6%^J#%;m8qZ{n!~jhQAXi{yIYBg
z{-uW*dRuy*>}7IO7|bgwS+P;{u))&1#=zO#^WIlx$7y0Bcj1U*>^joQgj{i#Nw3QG
z>2;?l-`6B~yVV4smgl^l$SEB8F#4vs<33%tJ+1VfUz5DCk+HGy$f8yXNI3GS98V7J
zRz*VmoG|WoC(WPs0Qa0uX=xVFoxnjruweYBtc38lR6zn@VkTzhVrJq3w72_b+K`|w
ztGcLx^-xjGw3&>tgcggXLIP_esx*nQ(2a_KCk2#~>deJk=&bWWhazXI85Y9XN1ieq
z*H6>uUgny@?}}F_JY;S^7}7?(U5}`rQ)?3Ce+bUCEsz
zaktqjLeK$7Ju`BmP$oQWgWQc}&Y}slm!)~pN?q+5_*SI~Lm2+Z`g(ClrC^&-l-i>C
zf;uL_*Ya;nfb~_JB!tXBFJUbV5oFC(yI17HWa>nC2cVky?EL}SOYF(&il5)nwyNC_YhBda>~I<`-*f=%Xr~)$O5O#-yUA7l0;GGcp-W#cCAYJ6JiALH796&GL0wpj9hf%E5Ed5E=U7IHs#fAHavKhWIt8N0TB{U}Gi~A=lB7W4x
zE)2GZKINkLHwE&teO}_;7EOC>eDz6J0!(kFS`&9xO8VqdTE@U)x<>_0+<|t3Xfb>M
zoInAS{T_G>5@Bi345Gy1MyfF95Vh{qwq#L?dgh{$?0;esQpwVL?W@Cl8ZT&vy6(KbUlq-3#-+!#Sgt&>h
z^gT0%*1Q4x-N+fT&}73VL^dCHUoGwTEUf7w+1?gbDr9tH#J9GNxkb*rDeDgak0uK2
ziod_KYf(|O?C5ePy%WP2oi`%An`WaiTj>QJWy$zHNcaebD$4oT
zEf)=`2B#T;Q;ms%;)A6OHj0Dep3S!yeT4Qeh<>mpX7SkWwCGrIP$0Km+T7!pz<_QU
zUDJZ|zcp7CcpBi^J!&)v4223VXa?4)rdl~PnNEQ126qM*UaS`FQEY<98F2%qa647a
z2UNO~3y_ww-uvA~vgtW)Obsd?dZp9;Ks;`hM0?Fy_!pdRQNVYAo5<0Y?1XO^4^_v8-7@*LM5grfL`oDBwTVW4$8GBSiL
zB^NGs>)q};%G(t#Udru|#Iq&*WLg^=VY)>^3Ydp{>|Dy&4Y{V$-5I*sSWFGr$v8FF
z$=sxnw%mm$y#KgY7|?dT|2|WH*!#;Quo+?%@*FRkm45w|#G_9yc$rU3ui3M+Nyr)A
zP_$yr#`(37?bk2Coh({@>pSh_^m`?!mPdS??&gvNQYRw5j{Suex0|xnP}r?LT7_&f
zwPK%YOY+-{UL*k;7TO=5i|8-$O#W%h?4L31-*pgz9+4*g
zqu|`~2LL8~BblZ%n%2iE8hI;dPPk}jJu(E&0az1`CO$^YMB?;}d~z$@NZZd=I<{ZG
zmV8qvt>cowg|Cj(%&oJsd3&I5U#|I9$9j6>dgZ7FiILFqhPw9D_q3_dC31)RNWsc05GXSNCCjd4T~ZT&n=c5pyGQkTv!QF%OZ`
z^#LSxUJA6`yEfgZRA1#O+lf-ha0(T6KbDRTB>`J2gg3~webD#>ljCV1jE{j>s@zNR
zEiy{B@bobuGxMDKlXyp&)o7*J-v(buz-zk49#DQIwv$#KfL^BW(RF
zWfrB(jxHm8X-XHVif{FaWI`$q@>*Hnof|K;m>@Nl(?OuCX1D_m}=4m)5v)*d%;Z|;kA2MWk&{Qa?N%T)cze{ULn43u?
zRHb(S);We34$f_kEf=R;@*H(#2}QFdx&2S1imdMeUnF0`s^=y`&07>fM$*oXFe@$*
zFfHX1Sj|;}-L-?k%6u8MYAo=z)&xKju%oVs?bBZY#BcqHY3Mz6448K$RYB
z$%s^){^JP>qLE0={{9{vP~$*tIVc<1;RS-G>d7<^FtXGgeax_W*bS>kY4X-Ux`#hA
zEie-KO*4+Cyb=cqZ6!S_ZAx9ykSIz8WdhA7**Q6crE)QyY083V&-T#rqOmRWn3y09_TfT_{wi1C*Wo3f&>`ldL^fP+ymZrg9y@if=}Zj{N;Gd_owh&OYx
zC+bj;pdb6OVN0!~1|&t$iG1$(V8wHw9yNNB1g$}2z>;z$zIzkbfwG}gf6H^=W
zO{WB|h^@od@`6$BCB(HVIkvzAKMXxB;!Kdr+QcT{k8pa965HdNHM5cHFnQgr1nuI{
zVT83P^{J)?*%2x!JwwwAjai10PrUnS^FD;M6FR7p7(}HNyM_9F!eMO^_ee|kpj?R$
zX8ovL=3b&xwdk^;f#juIQ)(7Vw$2p4B-Xkby66dR#^vcucR;4f?qW;l-Z*SNJi4vnP@GGEcH|)xZ5^+
z791CrvQn9#b!~aIj4k1yS^;FHz@N9KG`wEynlZNH(xIYHAK~q(7MHz^>q?<%ok~21
zXLi6hG@XlSH5|Sor%1my!>>J0xH=YQJ(`R(I6y-`rmG8<^xVyL!Wp@(k17Z&(T`wt&|cs7x^_z#-aCTy)t=eB1Oe+ZH#C5uY}IP6I4OHN&R7
zjIuP=U>}DK%^O#8&!61!Iyok+Hmx;xG?{H(r=B10KCBq2Z4FQw@Tppw#EfQB<-YL)6w<@?p=N?MY-0i@Z>JD@8;#qe`IJC68dgrW?48uwOqWD!x9hDts*EL2cpbQcx=P5|Bfq#b
z>PHdyxigT>Hd%O&7x_al&grF=P-QX;YL*Ji@Q7e!A@J=maCM<5qIX}rKnbNk$
z-Qj8^_gmw$fl(z^9tlpDU5J)B%@;xYqVkf;px1kdwP=X
z%KeH>=gUmX%Z0&m!;iYAr*9^DTN0>|8L?ze^5zUMtZ@eeFVfc5p!(u>OLIj$trOnX
z*F=@)RjXGhwNY0*KyUFf=Qmp6ePR8qrsl;Ld~Qyl4{}TgsH!8|8~QW{`<-Yp_^kks
zPjZ%zgqs%+2P!H)t7|U&Xag+SN~$~}I@pfI9-$)kh%6ew1>w@W|Ez|+R%Rvb
zk>JvutJAYw;WyW;g@*{QTnR3NN->Oe9I+nY_2Vk+#JMi|Vv9#QDx=&^j`k5@M*%4X
z&sQvd5_XU@JSNTUZrFe=Bq}pSh(A@tCdxW7ASx2Q5{*{K4lsiz;ED6n0hTdHn8Q~v
z5-yZp@?EC?KsIf#L;cyMC=YH|SI~NABbyHp-jKLM{FG=(MEzC^c@+$?3(q{U!xuUd
zXVB*v%vyKW)YQWDP(4Kp>4FjQu$a*VcMcuCL*$2~HH4QLy3P_bhM4_`*Wuj#;|HDr
zkum4qg7I+7)gny^*%}PH%Zncov>QOg(ORr3-Tmy=kN!@`uqS!A2NYg>cI}Q!!U=Wp
zWP-i=oK4jFZj(;h%}xTM)7{o?#6Kh`6#MCDn&+vQk|;QEFZbLb<@bNQFbt&DvKq=a
z)&7t`XI={f$2Syp`9MuQq)K&K{0RM=RPK)>yC6NO=J&YINhKr{7Q~+q5d8ae!1Dou
zKieM?@$+$lze0ak>z|Jg{Ia)Cw|_u?J52CbhTpa7XI1}~?LFQ8()j<1d+zsdr=Mkj
zU&i><{KuRBDNO$-@Sokb{-5A~s1pB);aSE0WtD%!@Q0@TSE}FTpl1#Hm)-r}sQ#sB
z|CRA~o#t6a`ej2;`y_uEn?DQg&y2rBrN0tC6FvF#4||q*ep%pCvGSzE{3pP($n(p-
z{1foM4({(eI)9$q)8A145`6yp%HPYU=S`nqMu7fHE&5-!fc{GK`(Ng{+WKV&*ncMa
zYwe{Z3j_Py8|CQ-cp4``G6)D>2t{LaS7#Hz^PUr#u_u|ZjSaxX-U&$d?{<49GD{a1
U2VNEycXxMYz`q_do7mg_AH%Ahh5!Hn
diff --git a/4_video_sdks/mp4_facemask_sdk/mp4-facemask-sdk.iml b/4_video_sdks/mp4_facemask_sdk/mp4-facemask-sdk.iml
new file mode 100644
index 00000000..6278679a
--- /dev/null
+++ b/4_video_sdks/mp4_facemask_sdk/mp4-facemask-sdk.iml
@@ -0,0 +1,216 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/4_video_sdks/mp4_facemask_sdk/pom.xml b/4_video_sdks/mp4_facemask_sdk/pom.xml
index 8b06f691..80ac3bce 100644
--- a/4_video_sdks/mp4_facemask_sdk/pom.xml
+++ b/4_video_sdks/mp4_facemask_sdk/pom.xml
@@ -31,7 +31,7 @@
UTF-8
1.8
1.8
- 0.13.0
+ 0.14.0
@@ -94,14 +94,13 @@
ai.djl.pytorch
pytorch-native-auto
- 1.9.0
+ 1.9.1
ai.djl.paddlepaddle
paddlepaddle-engine
${djl.version}
- runtime
ai.djl.paddlepaddle
@@ -118,13 +117,6 @@
javacv-platform
1.5.4
-
- aias
- mask-lib
- 0.1.0
- system
- ${project.basedir}/lib/aias-mask-lib-0.1.0.jar
-
org.testng
testng
diff --git a/4_video_sdks/mp4_facemask_sdk/src/main/java/me/aias/example/MP4FaceMaskDetectionExample.java b/4_video_sdks/mp4_facemask_sdk/src/main/java/me/aias/example/MP4FaceMaskDetectionExample.java
index e8aec865..9c9e0f18 100644
--- a/4_video_sdks/mp4_facemask_sdk/src/main/java/me/aias/example/MP4FaceMaskDetectionExample.java
+++ b/4_video_sdks/mp4_facemask_sdk/src/main/java/me/aias/example/MP4FaceMaskDetectionExample.java
@@ -12,8 +12,8 @@ import ai.djl.repository.zoo.Criteria;
import ai.djl.repository.zoo.ModelZoo;
import ai.djl.repository.zoo.ZooModel;
import ai.djl.translate.TranslateException;
-import me.aias.FaceDetection;
-import me.aias.FaceMaskDetect;
+import me.aias.example.utils.FaceDetection;
+import me.aias.example.utils.FaceMaskDetect;
import me.aias.example.utils.OpenCVImageUtil;
import org.bytedeco.javacv.CanvasFrame;
import org.bytedeco.javacv.FFmpegFrameGrabber;
@@ -156,7 +156,7 @@ public class MP4FaceMaskDetectionExample {
if (squareBox[1] > height) squareBox[1] = height;
if ((squareBox[0] + squareBox[2]) > width) squareBox[2] = width - squareBox[0];
if ((squareBox[1] + squareBox[2]) > height) squareBox[2] = height - squareBox[1];
- return img.getSubimage(squareBox[0], squareBox[1], squareBox[2], squareBox[2]);
+ return img.getSubImage(squareBox[0], squareBox[1], squareBox[2], squareBox[2]);
// return img.getSubimage(squareBox[0], squareBox[1], squareBox[2], squareBox[3]);
}
}
diff --git a/4_video_sdks/mp4_facemask_sdk/src/main/java/me/aias/example/utils/FaceDetection.java b/4_video_sdks/mp4_facemask_sdk/src/main/java/me/aias/example/utils/FaceDetection.java
new file mode 100644
index 00000000..f5cfdd48
--- /dev/null
+++ b/4_video_sdks/mp4_facemask_sdk/src/main/java/me/aias/example/utils/FaceDetection.java
@@ -0,0 +1,104 @@
+package me.aias.example.utils;
+
+import ai.djl.Device;
+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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public final class FaceDetection {
+
+ private static final Logger logger = LoggerFactory.getLogger(FaceDetection.class);
+
+ public FaceDetection() {}
+
+ public Criteria criteria(float shrink, float threshold) {
+ Criteria 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())
+ .optDevice(Device.cpu())
+ .optTranslator(new FaceTranslator(shrink, threshold))
+ .build();
+
+ return criteria;
+ }
+
+ private final class FaceTranslator implements Translator {
+
+ private float shrink;
+ private float threshold;
+ private List 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 className, float threshold) {
+ NDArray result = list.singletonOrThrow();
+ float[] probabilities = result.get(":,1").toFloatArray();
+ List names = new ArrayList<>();
+ List prob = new ArrayList<>();
+ List 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);
+ }
+ }
+}
diff --git a/4_video_sdks/mp4_facemask_sdk/src/main/java/me/aias/example/utils/FaceMaskDetect.java b/4_video_sdks/mp4_facemask_sdk/src/main/java/me/aias/example/utils/FaceMaskDetect.java
new file mode 100644
index 00000000..bf6f9d92
--- /dev/null
+++ b/4_video_sdks/mp4_facemask_sdk/src/main/java/me/aias/example/utils/FaceMaskDetect.java
@@ -0,0 +1,98 @@
+package me.aias.example.utils;
+
+import ai.djl.Device;
+import ai.djl.inference.Predictor;
+import ai.djl.modality.Classifications;
+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.transform.Normalize;
+import ai.djl.modality.cv.transform.Resize;
+import ai.djl.modality.cv.transform.ToTensor;
+import ai.djl.modality.cv.translator.ImageClassificationTranslator;
+import ai.djl.repository.zoo.Criteria;
+import ai.djl.training.util.ProgressBar;
+import ai.djl.translate.TranslateException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class FaceMaskDetect {
+
+ private static final Logger logger = LoggerFactory.getLogger(FaceMaskDetect.class);
+
+ public FaceMaskDetect() {}
+
+ public DetectedObjects predict(
+ Predictor faceDetector,
+ Predictor classifier,
+ Image image)
+ throws TranslateException {
+
+ DetectedObjects detections = faceDetector.predict(image);
+ List faces = detections.items();
+
+ List names = new ArrayList<>();
+ List prob = new ArrayList<>();
+ List rect = new ArrayList<>();
+ for (DetectedObjects.DetectedObject face : faces) {
+ Image subImg = getSubImage(image, face.getBoundingBox());
+ Classifications classifications = classifier.predict(subImg);
+ names.add(classifications.best().getClassName());
+ prob.add(face.getProbability());
+ rect.add(face.getBoundingBox());
+ }
+
+ return new DetectedObjects(names, prob, rect);
+ }
+
+ public Criteria criteria() {
+ Criteria criteria =
+ Criteria.builder()
+ .optEngine("PaddlePaddle")
+ .setTypes(Image.class, Classifications.class)
+ .optTranslator(
+ ImageClassificationTranslator.builder()
+ .addTransform(new Resize(128, 128))
+ .addTransform(new ToTensor()) // HWC -> CHW div(255)
+ .addTransform(
+ new Normalize(
+ new float[] {0.5f, 0.5f, 0.5f}, new float[] {1.0f, 1.0f, 1.0f}))
+ .addTransform(nd -> nd.flip(0)) // RGB -> GBR
+ .build())
+ .optModelUrls(
+ "https://aias-home.oss-cn-beijing.aliyuncs.com/models/face_mask/face_mask.zip")
+ .optProgress(new ProgressBar())
+ .optDevice(Device.cpu())
+ .build();
+
+ return criteria;
+ }
+
+ private int[] extendSquare(
+ double xmin, double ymin, double width, double height, double percentage) {
+ double centerx = xmin + width / 2;
+ double centery = ymin + height / 2;
+ double maxDist = Math.max(width / 2, height / 2) * (1 + percentage);
+ return new int[] {(int) (centerx - maxDist), (int) (centery - maxDist), (int) (2 * maxDist)};
+ // return new int[] {(int) xmin, (int) ymin, (int) width, (int) height};
+ }
+
+ private Image getSubImage(Image img, BoundingBox box) {
+ Rectangle rect = box.getBounds();
+ int width = img.getWidth();
+ int height = img.getHeight();
+ int[] squareBox =
+ extendSquare(
+ rect.getX() * width,
+ rect.getY() * height,
+ rect.getWidth() * width,
+ rect.getHeight() * height,
+ 0); // 0.18
+ return img.getSubImage(squareBox[0], squareBox[1], squareBox[2], squareBox[2]);
+ // return img.getSubimage(squareBox[0], squareBox[1], squareBox[2], squareBox[3]);
+ }
+}
diff --git a/4_video_sdks/rtsp_face_sdk/lib/aias-face-lib-0.1.0.jar b/4_video_sdks/rtsp_face_sdk/lib/aias-face-lib-0.1.0.jar
deleted file mode 100644
index 65a056bbc60fcdff616590094e226707c0204be3..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 6492
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