BufferedImage的边缘检测代码

时间:2014-12-31 01:50:53

标签: java bufferedimage

我正在尝试创建一个给定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());

            }
        }

    }

1 个答案:

答案 0 :(得分:1)

对于任何有兴趣的人,我使用Stack解决了这个问题。

按照要采取的指示顺序预先填充堆栈。 开始向一个方向移动。 如果它可以移动方向从堆栈弹出 其他 打边境 将那个方向推向堆栈 将边框添加到边框集 如果border已经在set break中,那么 相对于方向转90度