我得到了下面的图片。我想获取矩形的 (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;
}
最佳答案
假设您只处理统一背景中统一颜色的矩形,那么以下方法应该有效:
- 查找方式 flood fill有效并理解它。
对于下面的两个步骤,将您遇到的每个像素标记为“已访问”,这样您就不会两次查看同一像素。 - 从图像中的任意位置开始进行洪水填充,直到找到黑色像素
p
(换句话说,直到找到矩形)。 - For 循环遍历 +x(增加 x)、-x(减少 x)、+y、-y 4 个方向中每一个方向的像素来查找矩形的边界。换句话说,这将为您提供定义矩形的最小 x、最大 x、最小 y 和最大 y 值。
- 上一步中的洪水填充终止后,您可以从任何相邻的背景像素开始继续执行步骤 2 的洪水填充,并从那里开始重复上述步骤,直到探索整个图像。
关于java - 如何计算图像中的矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17474912/