diff --git a/.gitignore b/.gitignore index 361a02fb..6f04b0b2 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ 1_image_sdks/crowd_sdk/models/ 1_image_sdks/crowd_sdk/target/ 1_image_sdks/crowd_sdk/build/output/ +1_image_sdks/ocr_sdks/ocr_v4_sdk/target/ +1_image_sdks/ocr_sdks/ocr_v3_sdk/target/ diff --git a/1_image_sdks/crowd_sdk/density_plot.jpg b/1_image_sdks/crowd_sdk/density_plot.jpg new file mode 100644 index 00000000..50c5fff3 Binary files /dev/null and b/1_image_sdks/crowd_sdk/density_plot.jpg differ diff --git a/1_image_sdks/crowd_sdk/src/main/java/me/aias/CrowdDetectExample.java b/1_image_sdks/crowd_sdk/src/main/java/me/aias/CrowdDetectExample.java index d0b44008..4719ef81 100644 --- a/1_image_sdks/crowd_sdk/src/main/java/me/aias/CrowdDetectExample.java +++ b/1_image_sdks/crowd_sdk/src/main/java/me/aias/CrowdDetectExample.java @@ -6,13 +6,13 @@ import ai.djl.modality.cv.Image; import ai.djl.modality.cv.ImageFactory; import ai.djl.ndarray.NDArray; import ai.djl.ndarray.NDList; -import ai.djl.ndarray.types.DataType; 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.util.CrowdDetect; -import me.aias.util.ImageUtils; +import me.aias.util.ImagePlotter; +import me.aias.util.NDArrayUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,8 +52,13 @@ public final class CrowdDetectExample { // density 为密度图 NDArray densityArray = list.get(0); densityArray = densityArray.squeeze(0); + densityArray = densityArray.squeeze(0); + densityArray = densityArray.transpose(); + logger.info("密度图 density: {}", densityArray.toDebugString(1000000000, 1000, 1000, 1000)); + float[][] densityArr = NDArrayUtils.floatNDArrayToArray(densityArray); + ImagePlotter.plotDensity(densityArr); } } } diff --git a/1_image_sdks/crowd_sdk/src/main/java/me/aias/util/ImagePlotter.java b/1_image_sdks/crowd_sdk/src/main/java/me/aias/util/ImagePlotter.java new file mode 100644 index 00000000..a27cc348 --- /dev/null +++ b/1_image_sdks/crowd_sdk/src/main/java/me/aias/util/ImagePlotter.java @@ -0,0 +1,69 @@ +package me.aias.util; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +public class ImagePlotter { + + public static void plotDensity(float[][] density) { + int width = density[0].length; + int height = density.length; + + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + double value = density[y][x]; + int rgb = getColor(value); + image.setRGB(x, y, rgb); + } + } + + File output = new File("density_plot.jpg"); + try { + ImageIO.write(image, "jpg", output); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static int getColor(double value) { + // Jet colormap implementation + double[][] jetColors = {{0, 0, 0.5}, {0, 0, 1}, {0, 0.5, 1}, {0, 1, 1}, {0.5, 1, 0.5}, {1, 1, 0}, {1, 0.5, 0}, {1, 0, 0}, {0.5, 0, 0}}; + + int numColors = jetColors.length; + double scaledValue = value * (numColors - 1); + int colorIndex = (int) scaledValue; + double colorFraction = scaledValue - colorIndex; + + int[] color1 = getColorComponents(jetColors[colorIndex]); + int[] color2 = getColorComponents(jetColors[colorIndex + 1]); + + int red = (int) (color1[0] + colorFraction * (color2[0] - color1[0])); + int green = (int) (color1[1] + colorFraction * (color2[1] - color1[1])); + int blue = (int) (color1[2] + colorFraction * (color2[2] - color1[2])); + + return new Color(red, green, blue).getRGB(); + } + + private static int[] getColorComponents(double[] color) { + int[] components = new int[3]; + for (int i = 0; i < 3; i++) { + components[i] = (int) (color[i] * 255); + } + return components; + } + + public static void main(String[] args) { + float[][] density = { + {0.1f, 0.2f, 0.3f}, + {0.4f, 0.5f, 0.6f}, + {0.7f, 0.8f, 0.9f} + }; + + plotDensity(density); + } +} \ No newline at end of file diff --git a/1_image_sdks/crowd_sdk/src/main/java/me/aias/util/ImageUtils.java b/1_image_sdks/crowd_sdk/src/main/java/me/aias/util/ImageUtils.java deleted file mode 100644 index 28987637..00000000 --- a/1_image_sdks/crowd_sdk/src/main/java/me/aias/util/ImageUtils.java +++ /dev/null @@ -1,235 +0,0 @@ -package me.aias.util; - -import ai.djl.engine.Engine; -import ai.djl.modality.cv.Image; -import ai.djl.modality.cv.ImageFactory; -import ai.djl.modality.cv.output.BoundingBox; -import ai.djl.modality.cv.output.DetectedObjects; -import ai.djl.modality.cv.output.Joints; -import ai.djl.modality.cv.output.Rectangle; -import ai.djl.modality.cv.util.NDImageUtils; -import ai.djl.ndarray.NDArray; -import ai.djl.ndarray.NDArrays; -import ai.djl.ndarray.NDList; -import ai.djl.ndarray.NDManager; -import ai.djl.ndarray.types.DataType; -import ai.djl.util.RandomUtils; - -import java.awt.*; -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.util.Iterator; -import java.util.List; -import java.util.stream.Collectors; -/** - * Image Utils - * - * @author Calvin - * - * @email 179209347@qq.com - **/ -public class ImageUtils { - - public static Image bufferedImage2DJLImage(BufferedImage img) { - return ImageFactory.getInstance().fromImage(img); - } - - public static void saveImages(List input, List generated, String path) throws IOException { - Path outputPath = Paths.get(path); - Files.createDirectories(outputPath); - - save(generated, "image", outputPath); - save(group(input, generated), "stitch", outputPath); - - } - - private static void save(List images, String name, Path path) throws IOException { - for (int i = 0; i < images.size(); i++) { - Path imagePath = path.resolve(name + i + ".png"); - images.get(i).save(Files.newOutputStream(imagePath), "png"); - } - } - - private static List group(List input, List generated) { - NDList stitches = new NDList(input.size()); - - try (NDManager manager = Engine.getInstance().newBaseManager()) { - for (int i = 0; i < input.size(); i++) { - int scale = 4; - int width = scale * input.get(i).getWidth(); - int height = scale * input.get(i).getHeight(); - - NDArray left = input.get(i).toNDArray(manager); - NDArray right = generated.get(i).toNDArray(manager); - - left = NDImageUtils.resize(left, width, height, Image.Interpolation.BICUBIC); - left = left.toType(DataType.UINT8, false); - - right = right.toType(DataType.UINT8, false); - - stitches.add(NDArrays.concat(new NDList(left, right), 1)); - } - - return stitches.stream() - .map(array -> array.toType(DataType.UINT8, false)) - .map(array -> ImageFactory.getInstance().fromNDArray(array)) - .collect(Collectors.toList()); - } - } - - public static void saveImage(BufferedImage img, String name, String path) { - Image djlImg = ImageFactory.getInstance().fromImage(img); - Path outputDir = Paths.get(path); - Path imagePath = outputDir.resolve(name); - try { - djlImg.save(Files.newOutputStream(imagePath), "png"); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public static void saveImage(Image img, String name, String path) { - Path outputDir = Paths.get(path); - Path imagePath = outputDir.resolve(name); - try { - img.save(Files.newOutputStream(imagePath), "png"); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public static void saveBoundingBoxImage( - Image img, DetectedObjects detection, String name, String path) throws IOException { - img.drawBoundingBoxes(detection); - Path outputDir = Paths.get(path); - Files.createDirectories(outputDir); - Path imagePath = outputDir.resolve(name); - img.save(Files.newOutputStream(imagePath), "png"); - } - - public static void drawImageRect(BufferedImage image, int x, int y, int width, int height) { - // 将绘制图像转换为Graphics2D - // Convert the drawing image to Graphics2D - Graphics2D g = (Graphics2D) image.getGraphics(); - try { - g.setColor(new Color(246, 96, 0)); - // 声明画笔属性 :粗 细(单位像素)末端无修饰 折线处呈尖角 - // Declare the pen attribute: thick, no decoration at the end, sharp angle at the intersection - BasicStroke bStroke = new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); - g.setStroke(bStroke); - g.drawRect(x, y, width, height); - - } finally { - g.dispose(); - } - } - - public static void drawImageRect( - BufferedImage image, int x, int y, int width, int height, Color c) { - // 将绘制图像转换为Graphics2D - // Convert the drawing image to Graphics2D - Graphics2D g = (Graphics2D) image.getGraphics(); - try { - g.setColor(c); - // 声明画笔属性 :粗 细(单位像素)末端无修饰 折线处呈尖角 - // Declare the pen attribute: thick, no decoration at the end, sharp angle at the intersection - BasicStroke bStroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); - g.setStroke(bStroke); - g.drawRect(x, y, width, height); - - } finally { - g.dispose(); - } - } - - public static void drawImageText(BufferedImage image, String text) { - Graphics graphics = image.getGraphics(); - int fontSize = 100; - Font font = new Font("楷体", Font.PLAIN, fontSize); - try { - graphics.setFont(font); - graphics.setColor(new Color(246, 96, 0)); - int strWidth = graphics.getFontMetrics().stringWidth(text); - graphics.drawString(text, fontSize - (strWidth / 2), fontSize + 30); - } finally { - graphics.dispose(); - } - } - - /** 返回外扩人脸 factor = 1, 100%, factor = 0.2, 20% - * Returns the enlarged face with factor = 1, 100%, factor = 0.2, 20% - * @param img - * @param box - * @param factor - * @return - */ - - public static Image getSubImage(Image img, BoundingBox box, float factor) { - Rectangle rect = box.getBounds(); - // 左上角坐标 - Upper left corner coordinates - int x1 = (int) (rect.getX() * img.getWidth()); - int y1 = (int) (rect.getY() * img.getHeight()); - // 宽度,高度 - width, height - int w = (int) (rect.getWidth() * img.getWidth()); - int h = (int) (rect.getHeight() * img.getHeight()); - // 左上角坐标 - Upper right corner coordinates - int x2 = x1 + w; - int y2 = y1 + h; - - // 外扩大100%,防止对齐后人脸出现黑边 - // Expand by 100% to prevent black edges after alignment - int new_x1 = Math.max((int) (x1 + x1 * factor / 2 - x2 * factor / 2), 0); - int new_x2 = Math.min((int) (x2 + x2 * factor / 2 - x1 * factor / 2), img.getWidth() - 1); - int new_y1 = Math.max((int) (y1 + y1 * factor / 2 - y2 * factor / 2), 0); - int new_y2 = Math.min((int) (y2 + y2 * factor / 2 - y1 * factor / 2), img.getHeight() - 1); - int new_w = new_x2 - new_x1; - int new_h = new_y2 - new_y1; - - return img.getSubImage(new_x1, new_y1, new_w, new_h); - } - - public static void drawJoints(Image img, Image subImg, int x, int y, Joints joints) { - BufferedImage image = (BufferedImage) img.getWrappedImage(); - Graphics2D g = (Graphics2D) image.getGraphics(); - int stroke = 2; - g.setStroke(new BasicStroke((float) stroke)); - int imageWidth = subImg.getWidth(); - int imageHeight = subImg.getHeight(); - Iterator iterator = joints.getJoints().iterator(); - - while (iterator.hasNext()) { - Joints.Joint joint = (Joints.Joint) iterator.next(); - g.setPaint(randomColor().darker()); - int newX = x + (int) (joint.getX() * (double) imageWidth); - int newY = y + (int) (joint.getY() * (double) imageHeight); - g.fillOval(newX, newY, 10, 10); - } - - g.dispose(); - } - - private static Color randomColor() { - return new Color(RandomUtils.nextInt(255)); - } - - public static void drawBoundingBoxImage(Image img, DetectedObjects detection) { - img.drawBoundingBoxes(detection); - } - - public static int getX(Image img, BoundingBox box) { - Rectangle rect = box.getBounds(); - // 左上角x坐标 - Upper left corner x coordinate - int x = (int) (rect.getX() * img.getWidth()); - return x; - } - - public static int getY(Image img, BoundingBox box) { - Rectangle rect = box.getBounds(); - // 左上角y坐标 - Upper left corner y coordinate - int y = (int) (rect.getY() * img.getHeight()); - return y; - } -} \ No newline at end of file diff --git a/1_image_sdks/crowd_sdk/src/main/java/me/aias/util/NDArrayUtils.java b/1_image_sdks/crowd_sdk/src/main/java/me/aias/util/NDArrayUtils.java new file mode 100644 index 00000000..8bc7abe3 --- /dev/null +++ b/1_image_sdks/crowd_sdk/src/main/java/me/aias/util/NDArrayUtils.java @@ -0,0 +1,31 @@ +package me.aias.util; + +import ai.djl.ndarray.NDArray; +/** + * NDArray Utils + * + * @author Calvin + * @mail 179209347@qq.com + * @website www.aias.top + */ +public class NDArrayUtils { + + /** + * float NDArray To float[][] Array + * @param ndArray + * @return + */ + public static float[][] floatNDArrayToArray(NDArray ndArray) { + int rows = (int) (ndArray.getShape().get(0)); + int cols = (int) (ndArray.getShape().get(1)); + float[][] arr = new float[rows][cols]; + + float[] arrs = ndArray.toFloatArray(); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + arr[i][j] = arrs[i * cols + j]; + } + } + return arr; + } +} diff --git a/README.md b/README.md index a7991ef6..177ac1ec 100644 --- a/README.md +++ b/README.md @@ -811,7 +811,8 @@ - +#### 人工智能算法: +- https://zhuanlan.zhihu.com/p/693738275 #### 帮助文档: