【问题标题】:2D geometric shape vertices coordinates detection二维几何形状顶点坐标检测
【发布时间】:2019-03-04 02:33:42
【问题描述】:

我正在尝试使用 marvin-framework 查找简单几何形状的顶点及其坐标。

这是我的代码(基于https://stackoverflow.com/a/25223830/957057

package com.example.marvin;

import static marvin.MarvinPluginCollection.floodfillSegmentation;
import static marvin.MarvinPluginCollection.moravec;
import static marvin.MarvinPluginCollection.scale;

import java.io.FileWriter;
import java.io.IOException;

import marvin.image.MarvinImage;
import marvin.image.MarvinSegment;
import marvin.io.MarvinImageIO;

public class ShapesExample {

    private FileWriter fw = null;

    public ShapesExample() throws IOException{
        fw = new FileWriter("out.txt");

        // Scale down the image since the desired features can be extracted
        // in a lower resolution.
        MarvinImage image = MarvinImageIO.loadImage("square.png");
        scale(image.clone(), image, 269);

        // segment each object
        MarvinSegment[] objs = floodfillSegmentation(image);
        MarvinSegment seg;  

        OUT("Number of objects: " + objs.length);

        // For each object...
        // Skip position 0 which is just the background
        for(int i=1; i<objs.length; i++){
            seg = objs[i];
            OUT("seq: " + seg);
            MarvinImage imgSeg = image.subimage(seg.x1-5, seg.y1-5, seg.width+10, seg.height+10);
            OUT("i = " + i + "/" + objs.length);
            int[][] output;
            output = moravec(imgSeg, null, 18, 1000000);
            int xcount = 0;
            for(int x = 0; x < output.length; x++) {
                OUT("x = " + xcount++ + "/" + output[x].length);
                for(int y = 0; y < output[y].length; y++) {
                    OUTNONL("y = " + output[x][y] + " ");
                }
                OUT("");
            }
        }

        fw.close();
    }

    private void OUTNONL(String str) throws IOException {
        System.out.print(str);
    }

    private void OUT(String str) throws IOException {
        System.out.println(str);
    }

    public static void main(String[] args) throws IOException {
        new ShapesExample();
    }
}

square.png 包含形状图片

这是我看到的输出:

Number of objects: 3
seq: {x1:97, x2:136, y1:35, y2:72, width:40, height:38, area:189}
i = 1/3
x = 0/48
y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 
.....
x = 48/48
y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 
seq: {x1:99, x2:135, y1:36, y2:71, width:37, height:36, area:1333}
i = 2/3
x = 0/46
y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 
.....
x = 46/46
y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 y = 0 

(其中 i 是图像中检测到的第 n 个对象,x 是行,y 是列) 如您所见,所有值都是 0。

问题:

  • 我在获取坐标时缺少什么?
  • 为什么它会检测到图像中的 3 个形状?

【问题讨论】:

    标签: java image-processing graphics computer-vision marvin-framework


    【解决方案1】:

    “为什么它在图像中检测到 3 个形状?”

    FloodfillSegmentation 填充具有不同颜色的像素区域。在您的情况下,有三个分开的区域:(1)白色背景,(2)方形线条,(3)方形内部。为了解决这个问题,我只是将你的正方形变成了一个实心形状:

     boundaryFill(image.clone(), image, 1, 1, Color.BLACK);
     invertColors(image);
    

    “我在获取坐标时缺少什么?”

    moravec 输出不是顶点列表。它是具有与角位置相关的强度值的像素图。我在您的应用程序中添加了 getVertices(int[][] cornernessMap, int minDistanceBetweenPoints) 方法,以获取顶点的正确位置。

    解决方案

    输出图像:

    输出文本:

    Number of objects: 1
    Vertex: (147,54)
    Vertex: (147,105)
    Vertex: (200,54)
    Vertex: (200,105)
    

    源代码:

    import static marvin.MarvinPluginCollection.boundaryFill;
    import static marvin.MarvinPluginCollection.floodfillSegmentation;
    import static marvin.MarvinPluginCollection.invertColors;
    import static marvin.MarvinPluginCollection.moravec;
    import static marvin.MarvinPluginCollection.scale;
    
    import java.awt.Color;
    import java.awt.Point;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    import marvin.image.MarvinImage;
    import marvin.image.MarvinSegment;
    import marvin.io.MarvinImageIO;
    
    public class ShapesExample {
    
        private FileWriter fw = null;
    
        public ShapesExample() throws IOException{
            fw = new FileWriter("out.txt");
    
            // Scale down the image since the desired features can be extracted
            // in a lower resolution.
            MarvinImage image = MarvinImageIO.loadImage("./res/square.png");
            scale(image.clone(), image, 400);
    
            // Transform the square in a solid shape
            boundaryFill(image.clone(), image, 1, 1, Color.BLACK);
            invertColors(image);
    
            MarvinImageIO.saveImage(image, "./res/square_2.png");
    
            // segment each object
            MarvinSegment[] objs = floodfillSegmentation(image);
            MarvinSegment seg;  
    
            OUT("Number of objects: " + (objs.length-1));
    
            int MATRIX_SIZE = 5;
            // For each object...
            // Skip position 0 which is just the background
            for(int i=1; i<objs.length; i++){
                seg = objs[i];
    
                int[][] output = moravec(image, null, MATRIX_SIZE, 1000);
                List<Point> vertices = getVertices(output, 10);
    
                // Draw the vertices and print coordinates
                for(Point p:vertices) {
                    image.fillRect(p.x-(MATRIX_SIZE/2), p.y-(MATRIX_SIZE/2), 5, 5, Color.red); 
                    OUT("Vertex: ("+p.x+","+p.y+")");
                 }
            }
    
            MarvinImageIO.saveImage(image, "./res/square_out.png");
            fw.close();
        }
    
        private List<Point> getVertices(int[][] cornernessMap, int minDistanceBetweenPoints){
            int corners=0;
            List<Point> points = new ArrayList<Point>();
            for(int x=0; x<cornernessMap.length; x++){
                for(int y=0; y<cornernessMap[0].length; y++){
                    // Is it a corner?
                    if(cornernessMap[x][y] > 0){
                        // This part of the algorithm avoid inexistent corners
                        // detected almost in the same position due to noise.
                        Point newPoint = new Point(x,y);
                        if(points.size() == 0){
                            points.add(newPoint); corners++;
                        }else {
                            boolean valid=true;
                            for(Point p:points){
                                if(newPoint.distance(p) < minDistanceBetweenPoints){
                                    valid=false;
                                }
                            }
                            if(valid){
                                points.add(newPoint); corners++;
                            }
                        }
                    }
                }
            }
            return points;
        }
    
        private void OUTNONL(String str) throws IOException {
            System.out.print(str);
        }
    
        private void OUT(String str) throws IOException {
            System.out.println(str);
        }
    
        public static void main(String[] args) throws IOException {
            new ShapesExample();
        }
    }
    

    【讨论】:

    • 嗨加布里埃尔,非常感谢!我的目标是给定输入图像,识别形状。给定顶点,我可以通过自己的算法确定形状。但是,该算法接受输入:顶点数 (v) 和顶点坐标 (c)。例如:v=4, c=0,0;0,10;10,0;10,10 是正方形,v=3, c=0,0;0,10,10,0 是三角形。等
    • (续) 两个选项: 1. 让marvin 直接从图像中检测形状(有这样的功能吗?) 2. Marvin 给出上述格式的输出。当前输出有很多坐标,不一定是顶点。你认为我可以得到所需格式的输出吗?您建议以上两个选项中的哪一个? (我接受您的回答,因为它回答了我最初的问题。这是一个附加问题 - 如果您愿意,将单独发布)
    猜你喜欢
    • 1970-01-01
    • 2012-01-18
    • 2019-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多