我正在尝试创建一个给定Image和Point的Object,它将跟踪该Image的内边缘。
为简单起见,边缘始终为RGB Color Black。
我定义向右下行(顺时针)的枚举
我从Point p开始。
我根据当前方向从RIGHT开始移动图像中的像素。
如果这不是边框Pixel我将我的方向向后移动一步反向顺时针方向。例如(左 - >下) 如果我不能移动我选择的方向,我会转向下一个方向。 我将Point添加到我的边框数组。
我这样做直到我们回到Pixel的第一个边界。
多数计划......
到目前为止,当我必须从UP向右移动然后立即再次回到右边时,为了保持方向聚焦在边缘而不是转回图像,我遇到了障碍。
如果使用了UP,我尝试使用布尔标志,将右边的下一个方向指示为UP和Not DOWN。
非常感谢任何指导。 我在下面有完整的代码。
CODE:
package edgedection;
import static edgedection.EdgeDection.testImage;
import java.awt.Color;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
/**
*
* @author Fionán
*/
public class EdgeDection {
/**
* @param args the command line arguments
*/
static BufferedImage testImage = null;
{
try {
testImage = ImageIO.read(this.getClass().getResourceAsStream("testImage2.png"));
} catch (IOException ex) {
Logger.getLogger(EdgeDection.class.getName()).log(Level.SEVERE, null, ex);
}
}
static enum DIRECTION {
RIGHT, DOWN, LEFT, UP, NOMOVE
}
BufferedImage bi;
int borderColor = Color.black.getRGB();
DIRECTION facing;
Point p;
ArrayList<Point> borders;
boolean upFlag = false;
int x = p.x;
int y = p.y;
public static void main(String[] args) {
int x = 150;
int y = 60;
//forcing instance for loading Images only.
EdgeDection test= new EdgeDection();
JFrame show = new JFrame();
show.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel picLabel = new JLabel(new ImageIcon(testImage));
show.add(picLabel);
show.pack();
show.setVisible(true);
EdgeDection dector = new EdgeDection(testImage, new Point(x, y));
dector.start();
dector.highLightEdge();
show.repaint();
}
boolean canMove(DIRECTION d, Point p) {
switch (d) {
case RIGHT:
return bi.getRGB(p.x + 1, p.y) != borderColor;
case DOWN:
return bi.getRGB(p.x, p.y + 1) != borderColor;
case LEFT:
return bi.getRGB(p.x - 1, p.y) != borderColor;
//Deafult is up
case UP:
return bi.getRGB(p.x, p.y - 1) != borderColor;
default:
return false;
}
}
public EdgeDection(BufferedImage bi, Point p) {
this.facing = DIRECTION.RIGHT;
this.bi = bi;
this.p = p;
this.borders = new ArrayList<>();
}
public EdgeDection() {
}
DIRECTION getDirection() {
return null;
}
void addBorder(Point p) {
if(borders.isEmpty()){
x = p.x;
y = p.y;
}
borders.add(p);
}
void start() {
do {
System.out.println("Checking " + p.x + " " + p.y + facing);
if (canMove(facing, p)) {
if (upFlag) {
facing = DIRECTION.UP;
// p =new Point(p.x+1,p.y);
}
p = NextPointByDirection();
if(!upFlag) stepBackDirection();
if(upFlag)upFlag=false;
} else {
addBorder(p);
setNextDirection();
System.out.println("going " + facing + " border array size = "+ borders.size());
System.out.println("Up Flag status "+upFlag);
}
} while (facing != DIRECTION.NOMOVE && (p.x != x || p.y != y));
}
private void stepBackDirection() {
switch (facing) {
case RIGHT:
if(upFlag) {facing = DIRECTION.UP;}else{
facing = DIRECTION.RIGHT;
}
break;
case DOWN:
facing = DIRECTION.RIGHT;
break;
case LEFT:
facing = DIRECTION.DOWN;
break;
case UP:
facing = DIRECTION.LEFT;
}
}
private void setNextDirection() {
switch (facing) {
case RIGHT:
facing = DIRECTION.DOWN;
if (upFlag) {
facing = DIRECTION.UP;
upFlag = false;
}
return;
case DOWN:
facing = DIRECTION.LEFT;
return;
case LEFT:
facing = DIRECTION.UP;
return;
case UP:
upFlag = true;
facing = DIRECTION.RIGHT;
// upFlag = true;
// if (canMove(facing, new Point(p.x + 1, p.y - 1))){
// p = new Point(p.x + 1, p.y - 1);
//
// } ;
//
// if (upFlag) {
// facing = DIRECTION.RIGHT;
// }
}
}
private Point NextPointByDirection() {
// if (upFlag) {
// facing = DIRECTION.UP;
// upFlag = !upFlag;
// }
switch (facing) {
case RIGHT:
return new Point(p.x + 1, p.y);
case DOWN:
return new Point(p.x, p.y + 1);
case LEFT:
return new Point(p.x - 1, p.y);
default:
return new Point(p.x, p.y - 1);
}
}
private void print() {
for (Point p : borders) {
System.out.print(p.x + " " + p.y + " ");
}
}
void highLightEdge() {
for (Point p : borders) {
bi.setRGB(p.x, p.y, Color.RED.getRGB());
}
}
}
答案 0 :(得分:1)
对于任何有兴趣的人,我使用Stack解决了这个问题。
按照要采取的指示顺序预先填充堆栈。 开始向一个方向移动。 如果它可以移动方向从堆栈弹出 其他 打边境 将那个方向推向堆栈 将边框添加到边框集 如果border已经在set break中,那么 相对于方向转90度