Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何计算图像中的矩形_Java_Image - Fatal编程技术网

Java 如何计算图像中的矩形

Java 如何计算图像中的矩形,java,image,Java,Image,我看到了下图。我想得到(x,y)和矩形的宽度和高度。 我在下面发布了我到目前为止所做的尝试,但没有给出好的结果。所以,如果有人知道,请告诉我一个好的算法来解决这个问题。提前谢谢 public static List<Rectangle> targetLists(final BufferedImage image) { final List<List<Integer>> getPixels = getPixels(image);

我看到了下图。我想得到(x,y)和矩形的宽度和高度。

我在下面发布了我到目前为止所做的尝试,但没有给出好的结果。所以,如果有人知道,请告诉我一个好的算法来解决这个问题。提前谢谢

public static List<Rectangle> targetLists(final BufferedImage image) {
        final List<List<Integer>> getPixels = getPixels(image);
        final List<Rectangle> rectangleList = new ArrayList<Rectangle>();
        final List<Integer> setX = new ArrayList<Integer>(new HashSet<Integer>(
                getPixels.get(0)));
        final List<Integer> setY = new ArrayList<Integer>(new HashSet<Integer>(
                getPixels.get(1)));
        List<Integer> xPointsList;
        List<Integer> yPointsList;
        if (setX != null) {
            xPointsList = getListOfExactXandYpoints(setX);
            if (xPointsList != null) {
                yPointsList = getListOfExactXandYpoints(setY);
                if (xPointsList.size() >= yPointsList.size()) {
                    return getRectangleListInXmostPoint(xPointsList,
                            yPointsList, rectangleList);
                } else {
                    return getRectangleListInYmostPoint(yPointsList,
                            xPointsList, rectangleList);
                }
            }
        }
        return null;
    }

private static List<List<Integer>> getPixels(BufferedImage image) {
        final List<List<Integer>> lists = new ArrayList<List<Integer>>();
        final List<Integer> targetsListX = new ArrayList<Integer>();
        final List<Integer> targetsListY = new ArrayList<Integer>();
        for(int y=0; y<image.getHeight(); y++) {
            for(int x=0; x<image.getWidth(); x++) {
                if(Color.BLACK.getRGB() == image.getRGB(x, y)) {
                    targetsListX.add(x);
                    targetsListY.add(y);
                }
            }
        }
        lists.add(targetsListX);
        lists.add(targetsListY);
        return lists;
    }

private static List<Rectangle> getRectangleListInYmostPoint(
            final List<Integer> list1, final List<Integer> list2,
            final List<Rectangle> rectangleList) {
        int step = 0;
        for (int i = 0; i < list1.size(); i += 2) {
            rectangleList.add(new Rectangle(new Point(list2.get(step), list1
                    .get(i)), new Dimension(Math.abs(list2.get(step)
                    - list2.get(step + 1)) + 1, Math.abs(list1.get(i)
                    - list1.get(i + 1) + 1))));
            if (!((step + 2) >= list2.size())) {
                step += 2;
            }
        }
        return rectangleList;
    }

    private static List<Rectangle> getRectangleListInXmostPoint(
            final List<Integer> list1, final List<Integer> list2,
            final List<Rectangle> rectangleList) {
        int step = 0;
        for (int i = 0; i < list1.size(); i += 2) {
            rectangleList.add(new Rectangle(new Point(list1.get(i), list2
                    .get(step)), new Dimension(Math.abs(list1.get(i)
                    - list1.get(i + 1)) + 1, Math.abs(list2.get(step)
                    - list2.get(step + 1) + 1))));
            if (!((step + 2) >= list2.size())) {
                step += 2;
            }
        }
        return rectangleList;
    }

    private static List<Integer> getListOfExactXandYpoints(
            final List<Integer> set) {
        final List<Integer> list = new ArrayList<Integer>(set);
        Collections.sort(list);
        final ListIterator<Integer> iterator = list.listIterator();
        final List<Integer> pointsSet = new ArrayList<Integer>();
        int prev = 0;
        while (iterator.hasNext()) {
            final int i = iterator.next();
            if (pointsSet.size() != 0) {
                if (Math.abs(i - prev) > 15) {
                    pointsSet.add(prev);
                    pointsSet.add(i);
                    prev = i;
                } else {
                    prev = i;
                }
            } else {
                pointsSet.add(i);
                prev = i;
            }
        }
        if (pointsSet.size() != 0) {
            if (pointsSet.size() % 2 == 0) {
                pointsSet.remove(pointsSet.size() - 1);
            }
            pointsSet.add(list.get(list.size() - 1));
        }
        return pointsSet;
    }
公共静态列表目标列表(最终BuffereImage图像){
最终列表getPixels=getPixels(图像);
最终列表矩形列表=新的ArrayList();
最终列表setX=新的ArrayList(新的HashSet(
getPixels.get(0));
最终列表setY=newarraylist(newhashset(
getPixels.get(1));
列表xPointsList;
列表点列表;
如果(setX!=null){
xPointsList=getListOfExactXandYpoints(setX);
如果(xPointsList!=null){
yPointsList=getListOfExactXandYpoints(setY);
如果(xPointsList.size()>=yPointsList.size()){
返回getRectangleListInXmostPoint(xPointsList,
点列表、矩形列表);
}否则{
返回getRectangleListInYmostPoint(yPointsList,
xPointsList、矩形列表);
}
}
}
返回null;
}
私有静态列表getPixels(BuffereImage图像){
最终列表列表=新的ArrayList();
最终列表targetsListX=新的ArrayList();
最终列表targetsListY=new ArrayList();
对于(int y=0;y=list2.size()){
步骤+=2;
}
}
返回矩形列表;
}
私有静态列表getListOfExactXandYpoints(
最终列表集){
最终列表=新的ArrayList(集合);
集合。排序(列表);
最终ListIterator迭代器=list.ListIterator();
最终列表点set=new ArrayList();
int prev=0;
while(iterator.hasNext()){
final int i=iterator.next();
如果(pointsSet.size()!=0){
如果(数学绝对值(i-上一个)>15){
点集添加(上一个);
点集。添加(i);
prev=i;
}否则{
prev=i;
}
}否则{
点集。添加(i);
prev=i;
}
}
如果(pointsSet.size()!=0){
if(pointsSet.size()%2==0){
pointsSet.remove(pointsSet.size()-1);
}
pointsSet.add(list.get(list.size()-1));
}
返回点集合;
}

假设您只处理均匀背景中颜色一致的矩形,那么以下方法应该有效:

  • 查找工作原理并理解它。
    对于以下两个步骤,请将遇到的每个像素标记为“已访问”,这样您就不会看同一个像素两次。
  • 整体填充从图像中的任意位置开始,直到找到一个黑色像素
    p
    (换句话说,直到找到一个矩形)
  • 在+x(增加x),-x(减少x),+y,-y的4个方向上循环像素,以查找矩形的边界。换句话说,这将为您提供定义矩形的最小x、最大x、最小y和最大y值
  • 在上一步中的泛光填充终止后,从任何相邻背景像素开始,从第2步继续泛光填充,并从那里重复上述步骤,直到浏览整个图像

  • 我已经为此制作了一个java程序
    因为JPEG是一种有损格式,所以我对黑色的RGB进行了30个单位的参考
    我已编辑源以打印坐标。对于三角形ABCD,顶点A和C的坐标将在此处打印为

    现在您知道了这两个坐标,您可以轻松地计算高度和宽度以及其他两个坐标

    import java.awt.Color;
    import java.awt.image.BufferedImage;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import java.util.*;
    class GetPixelColor {
    
    static List rectList=new ArrayList();
    
        //int y, x, tofind, col;
        /**
         * @param args the command line arguments
         * @throws IOException  
         */
        public static void main(String args[]) throws IOException {
        int x1=0,x2=0,y1=0,y2=0;
            try {
                //read image file
                File file1 = new File("pic.jpg");
                BufferedImage image1 = ImageIO.read(file1);
    
                  for (int y = 0; y < image1.getHeight(); y++) {
                  for (int x = 0; x < image1.getWidth(); x++) {
    
                      int c = image1.getRGB(x,y);
                      Color color = new Color(c);
                    if(color.getRed()<30 &&color.getGreen()<30 &&color.getBlue()<30 && !contains(new Coordinate(x,y)))
                    {
                        x1=x;
                        y1=y;
                        for(int i=x;i< image1.getWidth(); i++)
                        {
                            c = image1.getRGB(i,y);
                            color = new Color(c);
                            if(!(color.getRed()<30 && color.getGreen()<30 && color.getBlue()<30) || i==image1.getWidth())
                            {
                                x2=i;
                                break;
                            }
                        }
                        for(int i=y;i<image1.getHeight();i++)
                        {
                            c = image1.getRGB(x,i);
                            color = new Color(c);
                            if(!(color.getRed()<30 &&color.getGreen()<30 &&color.getBlue()<30) || i==image1.getHeight())
                            {
                                y2=i;
                                break;
                            }
                        }
    
                        rectList.add(new Rectangle(new Coordinate(x1,y1),new Coordinate(x2,y2)));
                       }
            }
            }} catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println("No of rectangles = "+rectList.size()+"\n");
            printRect();
        }
    static void printRect()
    {
        Rectangle r=null;
        for(int i=0;i<rectList.size();i++)
        {
            r=(Rectangle)rectList.get(i);
            System.out.println("("+r.a.x+","+r.a.y+")      ("+r.b.x+","+r.b.y+")");
        }
    }
    static boolean contains(Coordinate a)
    {
        Rectangle r=null;
        for(int i=0;i<rectList.size();i++)
        {
            r=(Rectangle)rectList.get(i);
            if(a.x>=r.a.x && a.x<=r.b.x && a.y>=r.a.y && a.y<=r.b.y)        
                return true;
        }
        return false;
    }
    }
    class Rectangle
    {
        Coordinate a,b;
        Rectangle(Coordinate a,Coordinate b)
        {
            this.a=a;
            this.b=b;
        }
    }
    class Coordinate
    {
        int x,y;
        Coordinate(int x,int y)
        {
            this.x=x;
            this.y=y;
        }
    }
    
    导入java.awt.Color;
    导入java.awt.image.buffereImage;
    导入java.io.BufferedWriter;
    导入java.io.File;
    导入java.io.FileWriter;
    导入java.io.IOException;
    导入javax.imageio.imageio;
    导入java.util.*;
    类获取像素颜色{
    静态列表rectList=newarraylist();
    //int y,x,tofind,col;
    /**
    *@param指定命令行参数
    *@抛出异常
    */
    公共静态void main(字符串args[])引发IOException{
    int-x1=0,x2=0,y1=0,y2=0;
    试一试{
    //读取图像文件
    文件file1=新文件(“pic.jpg”);
    BuffereImage image1=ImageIO.read(文件1);
    对于(int y=0;y如果(color.getRed(),也许一个好的起点是边缘检测算法?代码很长,放在这里只是把相关的代码放在这里,而不是完整的代码。或者至少是你尝试过的代码的一部分。还要解释为什么你得到的结果不好请定义“没有给出好的结果”.你的算法是什么样子的。高级伪代码和它不起作用的地方将帮助我们。在你的输入图像中除了黑色矩形之外还有什么其他东西吗?一旦你找到了一个矩形,你就不需要填充它。只需尽可能沿每个主方向填充。你是对的,我忘记了它对于某些r来说是严格意义上的矩形伊森。编辑以包含您的建议。