2

我得到了下面的图像。我想获得矩形的 (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;
    }
4

2 回答 2

1

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

  1. 查找洪水填充的工作原理并理解它。
    对于以下两个步骤,将您遇到的每个像素标记为“已访问”,这样您就不会两次查看相同的像素。
  2. 从图像中的任何位置开始填充填充,直到找到黑色像素p(换句话说,直到找到矩形)。
  3. For 循环遍历 +x(增加 x)、-x(减少 x)、+y、-y 的 4 个方向中的每个方向的像素,以找到矩形的边界。换句话说,这将为您提供定义矩形的最小 x、最大 x、最小 y 和最大 y 值。
  4. 在上一步中的填充结束后,您从第 2 步开始从任何相邻的背景像素开始填充,并从那里重复上述步骤,直到您探索了整个图像。
于 2013-07-04T16:45:44.597 回答
1

我为此制作了一个 java 程序
因为 JPEG 是一种有损格式,所以我在 RGB 中为黑色设置了 30 个单位的容差
我已经编辑了源以打印坐标。对于三角形 ABCD,顶点 A 和 C 的坐标将在此打印为 在此处输入图像描述
您可以从这里下载 java 源
现在您知道了 2 个坐标,您可以轻松计算高度和宽度以及其他 2 个坐标。

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;
    }
}
于 2013-07-04T19:10:18.160 回答