如何在 Android (Java, OpenCV) 中绘制包含对象的矩形

创世纪

基本上,我想实现这一点,到目前为止,我已经编写了以下 Java 代码......

    // Display the camera frame
    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
        // The object's width and height are set to 0
        objectWidth = objectHeight = 0;

        // frame is captured as a coloured image
        frame = inputFrame.rgba();

        /** Since the Canny algorithm only works on greyscale images and the captured image is
         *  coloured, we transform the captured cam image into a greyscale one
         */
        Imgproc.cvtColor(frame, grey, Imgproc.COLOR_RGB2GRAY);

        // Calculating borders of image using the Canny algorithm
        Imgproc.Canny(grey, canny, 180, 210);

        /** To avoid background noise (given by the camera) that makes the system too sensitive
         *  small variations, the image is blurred to a small extent. Blurring is one of the
         *  required steps before any image transformation because this eliminates small details
         *  that are of no use. Blur is a low-pass filter.
         */
        Imgproc.GaussianBlur(canny, canny, new Size(5, 5), 5);

        // Calculate the contours
        Imgproc.findContours(canny, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

        /** The contours come in different sequences
         *  1 sequence for each connected component.
         *  Taking the assumption only 1 object is in view, if we have more than 1 connected
         *  component, this'll be considered part of the details of the object.
         *
         *  For this, we put all contours together in a single sequence
         *  If there is at least 1 contour, I can continue processing
         */
        for (MatOfPoint mat : contours) {
            // Retrieve and store all contours in one giant map
            mat.copyTo(allContours);
        }

        MatOfPoint2f allCon = new MatOfPoint2f(allContours.toArray());

        // Calculating the minimal rectangle to contain the contours
        RotatedRect box = Imgproc.minAreaRect(allCon);

        // Getting the vertices of the rectangle
        Point[] vertices = initialiseWithDefaultPointInstances(4);
        box.points(vertices);

        // Now the vertices are in possession, temporal smoothing can be performed.
            for (int i = 0; i < 4; i++) {
                // Smooth coordinate x of the vertex
                vertices[i].x = alpha * lastVertices[i].x + (1.0 - alpha) * vertices[i].x;
                // Smooth coordinate y of the vertex
                vertices[i].y = alpha * lastVertices[i].y + (1.0 - alpha) * vertices[i].y;
                // Assign the present smoothed values as lastVertices for the next smooth
                lastVertices[i] = vertices[i];
            }

        /** With the vertices, the object size is calculated.
         *  The object size is calculated through pythagoras theorm. In addition, it gives
         *  the distance between 2 points in a bi-dimensional space.
         *
         *  For a rectangle, considering any vertex V, its two sizes (width and height) can
         *  be calculated by calculating the distance of V from the previous vertex and
         *  calculating the distance of V from the next vertex. This is the reason why I
         *  calculate the distance between vertici[0]/vertici[3] and vertici[0]/vertici[1]
         */
        objectWidth = (int) (conversionFactor * Math.sqrt((vertices[0].x - vertices[3].x) * (vertices[0].x - vertices[3].x) + (vertices[0].y - vertices[3].y) * (vertices[0].y - vertices[3].y)));
        objectHeight = (int) (conversionFactor * Math.sqrt((vertices[0].x - vertices[1].x) * (vertices[0].x - vertices[1].x) + (vertices[0].y - vertices[1].y) * (vertices[0].y - vertices[1].y)));

        /** Draw the rectangle containing the contours. The line method draws a line from 1
         *  point to the next, and accepts only integer coordinates; for this reason, 2
         *  temporary Points have been created and why I used Math.round method.
         */
        Point pt1 = new Point();
        Point pt2 = new Point();
        for (int i = 0; i < 4; i++) {
            pt1.x = Math.round(vertices[i].x);
            pt1.y = Math.round(vertices[i].y);
            pt2.x = Math.round(vertices[(i + 1) % 4].x);
            pt2.y = Math.round(vertices[(i + 1) % 4].y);
            Imgproc.line(frame, pt1, pt2, red, 3);
        }

        //If the width and height are non-zero, then print the object size on-screen
        if (objectWidth != 0 && objectHeight != 0) {
            String text;
            text = String.format("%d x %d", objectWidth, objectHeight);
            widthValue.setText(text);
        }


        // This function must return
        return frame;
    }

    // Initialising an array of points
    public static Point[] initialiseWithDefaultPointInstances(int length) {
        Point[] array = new Point[length];
        for (int i = 0; i < length; i++) {
            array[i] = new Point();
        }
        return array;
    }

我想要实现的是在屏幕上绘制一个包含对象轮廓(边缘)的矩形。如果有人知道我的问题的答案,请随时在下面发表评论,因为我已经坚持了几个小时

懒惰的

这是注释中引用的代码如何在 Android (Java, OpenCV) 中绘制包含对象的矩形

public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    // The object's width and height are set to 0
    List<Integer> objectWidth = new ArrayList<>();
    List<Integer> objectHeight = new ArrayList<>();

    // frame is captured as a coloured image
    Mat frame = inputFrame.rgba();
    Mat gray = new Mat();
    Mat canny = new Mat();
    List<MatOfPoint> contours = new ArrayList<>();

    /** Since the Canny algorithm only works on greyscale images and the captured image is
     *  coloured, we transform the captured cam image into a greyscale one
     */
    Imgproc.cvtColor(frame, gray, Imgproc.COLOR_RGB2GRAY);

    // Calculating borders of image using the Canny algorithm
    Imgproc.Canny(gray, canny, 180, 210);

    /** To avoid background noise (given by the camera) that makes the system too sensitive
     *  small variations, the image is blurred to a small extent. Blurring is one of the
     *  required steps before any image transformation because this eliminates small details
     *  that are of no use. Blur is a low-pass filter.
     */
    Imgproc.GaussianBlur(canny, canny, new Size(5, 5), 5);

    // Calculate the contours
    Imgproc.findContours(canny, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

    /** The contours come in different sequences
     *  1 sequence for each connected component.
     *  Taking the assumption only 1 object is in view, if we have more than 1 connected
     *  component, this'll be considered part of the details of the object.
     *
     *  For this, we put all contours together in a single sequence
     *  If there is at least 1 contour, I can continue processing
     */

    if(contours.size() > 0){
        // Calculating the minimal rectangle to contain the contours
        List<RotatedRect> boxes = new ArrayList<>();
        for(MatOfPoint contour : contours){
            RotatedRect box = Imgproc.minAreaRect(new MatOfPoint2f(contour.toArray()));
            boxes.add(box);
        }

        // Getting the vertices of the rectangle

        List<Point[]> vertices = initialiseWithDefaultPointInstances(boxes.size(), 4);
        for(int i=0; i<boxes.size(); i++){
            boxes.get(i).points(vertices.get(i));
        }

        /*
        double alpha = 0.5;
        // Now the vertices are in possession, temporal smoothing can be performed.
            for(int i = 0; i<vertices.size(); i++){
                for (int j = 0; j < 4; j++) {
                    // Smooth coordinate x of the vertex
                    vertices.get(i)[j].x = alpha * lastVertices.get(i)[j].x + (1.0 - alpha) * vertices.get(i)[j].x;
                    // Smooth coordinate y of the vertex
                    vertices.get(i)[j].y = alpha * lastVertices.get(i)[j].y + (1.0 - alpha) * vertices.get(i)[j].y;
                    // Assign the present smoothed values as lastVertices for the next smooth
                    lastVertices.get(i)[j] = vertices.get(i)[j];
                }
        }*/

        /** With the vertices, the object size is calculated.
         *  The object size is calculated through pythagoras theorm. In addition, it gives
         *  the distance between 2 points in a bi-dimensional space.
         *
         *  For a rectangle, considering any vertex V, its two sizes (width and height) can
         *  be calculated by calculating the distance of V from the previous vertex and
         *  calculating the distance of V from the next vertex. This is the reason why I
         *  calculate the distance between vertici[0]/vertici[3] and vertici[0]/vertici[1]
         */
        double conversionFactor = 1.0;
        for(Point[] points : vertices){
            int width = (int) (conversionFactor * Math.sqrt((points[0].x - points[3].x) * (points[0].x - points[3].x) + (points[0].y - points[3].y) * (points[0].y - points[3].y)));
            int height = (int) (conversionFactor * Math.sqrt((points[0].x - points[1].x) * (points[0].x - points[1].x) + (points[0].y - points[1].y) * (points[0].y - points[1].y)));
            objectWidth.add(width);
            objectHeight.add(height);
        }



        /** Draw the rectangle containing the contours. The line method draws a line from 1
         *  point to the next, and accepts only integer coordinates; for this reason, 2
         *  temporary Points have been created and why I used Math.round method.
         */
        Scalar red = new Scalar(255, 0, 0, 255);
        for (int i=0; i<vertices.size(); i++){
            Point pt1 = new Point();
            Point pt2 = new Point();
            for (int j = 0; j < 4; j++) {
                pt1.x = Math.round(vertices.get(i)[j].x);
                pt1.y = Math.round(vertices.get(i)[j].y);
                pt2.x = Math.round(vertices.get(i)[(j + 1) % 4].x);
                pt2.y = Math.round(vertices.get(i)[(j + 1) % 4].y);
                Imgproc.line(frame, pt1, pt2, red, 3);
            }
            if (objectWidth.get(i) != 0 && objectHeight.get(i) != 0){
                Imgproc.putText(frame, "width: " + objectWidth + ", height: " + objectHeight, new Point(Math.round(vertices.get(i)[1].x), Math.round(vertices.get(i)[1].y)), 1, 1, red);
            }
        }

    }


    // This function must return
    return frame;
}

// Initialising an array of points
public static List<Point[]> initialiseWithDefaultPointInstances(int n_Contours, int n_Points) {
    List<Point[]> pointsList = new ArrayList<>();
    for(int i=0; i<n_Contours; i++){
        Point[] array = new Point[n_Points];
        for (int j = 0; j < n_Points; j++) {
            array[j] = new Point();
        }
        pointsList.add(array);
    }
    return pointsList;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Java:如何在JFrame中绘制矩形?

来自分类Dev

如何在Android OpenCV中捕获图像

来自分类Dev

如何在OpenCV中保存绘制的矩形?

来自分类Dev

如何在Android中绘制复杂的形状,包含三角形,矩形和笔触

来自分类Dev

Android布局-如何在矩形中绘制孔

来自分类Dev

如何在Java中绘制自定义的圆角矩形?

来自分类Dev

如何从 OpenCV Java 中的 HoughLines 变换中检测矩形

来自分类Dev

如何在Android Studio 1.5.1中导入openCV 3.1

来自分类Dev

如何在 Android 的 OpenCV 中优化我的算法?

来自分类Dev

如何在OpenCV Java中消除图像中的噪点

来自分类Dev

如何在opencv java中裁剪检测到的面部图像

来自分类Dev

如何在Java中使用OpenCV检测图像中的行

来自分类Dev

如何在opencv的Aruco标记上绘制矩形?

来自分类Dev

如何在Java中用箭头绘制矩形?

来自分类Dev

如何使用android和openCV在图像上绘制轮廓并创建边界矩形

来自分类Dev

如何在Android中添加2个org.opencv.core.Point对象?

来自分类Dev

如何在Java / Android中缩短代码?

来自分类Dev

如何在android(java)中读取XML

来自分类Dev

如何在Google函数中绘制圆形或矩形等图形对象?

来自分类Dev

OpenCV Android:如何在比较的图像上绘制匹配的关键点?

来自分类Dev

如何在OpenCV中获取旋转矩形的顶点?

来自分类Dev

如何在OpenCV中获取旋转矩形的顶点?

来自分类Dev

如何从Android中的文件读取OpenCV Mat对象?

来自分类Dev

如何从openCV android中的Byte []获取Mat对象?

来自分类Dev

如何在Android中不使用OpenCV管理器的情况下运行与openCV相关的应用

来自分类Dev

如何在Android画布上绘制局部圆角矩形?

来自分类Dev

如何在Android画布上绘制局部圆角矩形?

来自分类Dev

如何在Android项目中包含sqlite4java

来自分类Dev

如何在Java中形成矩形形式?

Related 相关文章

  1. 1

    Java:如何在JFrame中绘制矩形?

  2. 2

    如何在Android OpenCV中捕获图像

  3. 3

    如何在OpenCV中保存绘制的矩形?

  4. 4

    如何在Android中绘制复杂的形状,包含三角形,矩形和笔触

  5. 5

    Android布局-如何在矩形中绘制孔

  6. 6

    如何在Java中绘制自定义的圆角矩形?

  7. 7

    如何从 OpenCV Java 中的 HoughLines 变换中检测矩形

  8. 8

    如何在Android Studio 1.5.1中导入openCV 3.1

  9. 9

    如何在 Android 的 OpenCV 中优化我的算法?

  10. 10

    如何在OpenCV Java中消除图像中的噪点

  11. 11

    如何在opencv java中裁剪检测到的面部图像

  12. 12

    如何在Java中使用OpenCV检测图像中的行

  13. 13

    如何在opencv的Aruco标记上绘制矩形?

  14. 14

    如何在Java中用箭头绘制矩形?

  15. 15

    如何使用android和openCV在图像上绘制轮廓并创建边界矩形

  16. 16

    如何在Android中添加2个org.opencv.core.Point对象?

  17. 17

    如何在Java / Android中缩短代码?

  18. 18

    如何在android(java)中读取XML

  19. 19

    如何在Google函数中绘制圆形或矩形等图形对象?

  20. 20

    OpenCV Android:如何在比较的图像上绘制匹配的关键点?

  21. 21

    如何在OpenCV中获取旋转矩形的顶点?

  22. 22

    如何在OpenCV中获取旋转矩形的顶点?

  23. 23

    如何从Android中的文件读取OpenCV Mat对象?

  24. 24

    如何从openCV android中的Byte []获取Mat对象?

  25. 25

    如何在Android中不使用OpenCV管理器的情况下运行与openCV相关的应用

  26. 26

    如何在Android画布上绘制局部圆角矩形?

  27. 27

    如何在Android画布上绘制局部圆角矩形?

  28. 28

    如何在Android项目中包含sqlite4java

  29. 29

    如何在Java中形成矩形形式?

热门标签

归档