问题描述
我正在尝试使用marvin框架找到简单几何形状的顶点及其坐标。
这是我的代码(基于
这是我看到的输出:
对象数:3
seq:{x1:97,x2:136 ,y1:35,y2:72,宽度:40,高度:38,区域: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,宽度:37,高度:36,区域: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种形状?
为什么它会检测到图像中的3种形状?
FloodfillSegmentation填充具有不同颜色的像素区域。在您的情况下,有三个单独的区域:(1)白色背景,(2)正方形线,(3)正方形内部。为了解决这个问题,我只是将您的正方形变为实心形状:
boundaryFill(image.clone(),image,1, 1,Color.BLACK);
invertColors(image);
我在获取坐标时缺少什么?
moravec输出为不是顶点列表。这是像素图,其强度值与拐角位置有关。我向您的应用程序添加了 getVertices(int [] [] cornernessMap,int minDistanceBetweenPoints)方法,以便获得正确的顶点位置。
解决方案
输出图像:
输出文本:
对象数:1
顶点:(147,54)
顶点:(147,105)
顶点:(200,54)
顶点:(200,105)
源代码:
导入静态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;
导入marvin.image.MarvinImage;
import marvin.image.MarvinSegment;
import marvin.io.MarvinImageIO;
公共类ShapesExample {
private FileWriter fw = null;
public ShapesExample()引发IOException {
fw = new FileWriter( out.txt);
//缩小图像,因为可以以较低的分辨率提取所需的特征
//。
MarvinImage image = MarvinImageIO.loadImage( ./ res / square.png);
scale(image.clone(),image,400);
//将正方形变换为实心形状
boundaryFill(image.clone(),image,1,1,Color.BLACK);
invertColors(image);
MarvinImageIO.saveImage(image, ./res/square_2.png);
//分割每个对象
MarvinSegment [] objs = floodfillSegmentation(image);
MarvinSegment段;
OUT(对象数: +(objs.length-1));
int MATRIX_SIZE = 5;
//对于每个对象...
//跳过仅是背景
的位置0 for(int i = 1; i< objs.length; i ++){
seg = objs [i];
int [] []输出= moravec(image,null,MATRIX_SIZE,1000);
List< Point>顶点= getVertices(输出,10);
//为(点p:vertices){
image.fillRect(px-(MATRIX_SIZE / 2),py-(MATRIX_SIZE / 2)绘制顶点并打印坐标
),5,5,Color.red);
OUT(顶点:( + p.x +, + p.y +));
}
}
MarvinImageIO.saveImage(image, ./res/square_out.png);
fw.close();
}
私人列表< Point> getVertices(int [] [] cornernessMap,int minDistanceBetweenPoints){
int corners = 0;
List< Point> points =新的ArrayList< Point>();
for(int x = 0; x< cornernessMap.length; x ++){
for(int y = 0; y< cornernessMap [0] .length; y ++){
//是它是一个角落?
if(cornernessMap [x] [y]> 0){
//这部分算法避免了由于噪声而在几乎相同的位置检测到的不存在的角
//。
Point newPoint =新Point(x,y);
if(points.size()== 0){
points.add(newPoint);角落++;
} else {
boolean valid = true;
for(Point p:points){
if(newPoint.distance(p)< minDistanceBetweenPoints){
valid = false;
}
}
if(valid){
points.add(newPoint);角落++;
}
}
}
}
}
返回点;
}
私有无效OUTNONL(String str)抛出IOException {
System.out.print(str);
}
私有无效OUT(String str)抛出IOException {
System.out.println(str);
}
public static void main(String [] args)引发IOException {
new ShapesExample();
}
}
I am trying to find the vertices and their coordinates for simple geometric shape using marvin-framework.
This is the code I have (based on 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
contains the shape image
This is the output I see:
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
(where i is nth object detected in image, x is row, y is column)As you can see all values are 0.
Question:
- what am i missing in getting the coordinates?
- why does it detect 3 shapes in the image?
"why does it detect 3 shapes in the image?"
FloodfillSegmentation fill areas of pixels having distinct colors. In your case there are three separated areas: (1) white background, (2) square lines, (3) square interior. To solve this, I simply transformed your square in a solid shape:
boundaryFill(image.clone(), image, 1, 1, Color.BLACK);
invertColors(image);
"what am i missing in getting the coordinates?"
The moravec output is not a list of vertices. It's a map of pixels having an intensity value related to corners positions. I added getVertices(int[][] cornernessMap, int minDistanceBetweenPoints) method to your application in order to get the correct position of the vertices.
SOLUTION
output image:
output text:
Number of objects: 1
Vertex: (147,54)
Vertex: (147,105)
Vertex: (200,54)
Vertex: (200,105)
source code:
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();
}
}
这篇关于2D几何形状顶点坐标检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!