我需要识别二进制图像中的对象。
我在互联网上搜索了可能的算法,其中有很多,但不幸的是,我个人很难在没有任何视觉解释的情况下将原始公式转换为代码算法。
我找到了这个算法http://www.izbi.uni-leipzig.de/izbi/publikationen/publi_2004/IMS2004_JankowskiKuska.pdf。
此外,Java
本文中还描述了实现。
正如作者所写
labelImage 方法现在可用作任何 Mathematica 内置函数或用户定义函数
不幸的是,1
由于缺少 if 检查,该算法将在角落、第一个、最后一个位置的情况下失败。
1
如果我们找到单元格并且它没有被标记,则 该算法非常简单,我们检查邻居推入堆栈找到的项目。
但我不确定它是否正常工作。我已经修改了它,添加了一些if
检查,以免越界。
这里是。
public int[][] labelImage(int stackSize) {
int nRow = img.length;
int nCol = img[0].length;
int marker = 1;
int[] pos;
mStack = new SizedStack<>(stackSize);
int[][] label = new int[nRow][nCol];
for (int r = 0; r < nRow ; r++)
for (int c = 0; c < nCol; c++) {
if (img[r][c] == 0) continue;
if (label[r][c] > 0) continue;
/* encountered unlabeled foreground pixel at position r, c */
/* push the position on the stack and assign label */
mStack.push(new int[]{r, c});
label[r][c] = marker;
/* start the float fill */
while (!mStack.isEmpty()) {
pos = mStack.pop();
int i = pos[0];
int j = pos[1];
// Check if this is not first row, in this case we don't need to check top cells
if (i > 0) {
if (img[i - 1][j - 1] == 1 && label[i - 1][j - 1] == 0) {
mStack.push(new int[]{i - 1, j - 1});
label[i - 1][j - 1] = marker;
}
if (img[i - 1][j] == 1 && label[i - 1][j] == 0) {
mStack.push(new int[]{i - 1, j});
label[i - 1][j] = marker;
}
// Check if this is not the last column cell
if (j != nCol - 1) {
if (img[i - 1][j + 1] == 1 && label[i - 1][j + 1] == 0) {
mStack.push(new int[]{i - 1, j + 1});
label[i - 1][j + 1] = marker;
}
}
}
// Check if this is not first column
if (j > 0) {
if (img[i][j - 1] == 1 && label[i][j - 1] == 0) {
mStack.push(new int[]{i, j + 1});
label[i][j + 1] = marker;
}
// Check if this is not last row
if (i != nRow - 1) {
if (img[i + 1][j - 1] == 1 && label[i + 1][j - 1] == 0) {
mStack.push(new int[]{i + 1, j - 1});
label[i + 1][j - 1] = marker;
}
}
}
// Check if this is not last row
if (i != nRow - 1) {
if (img[i + 1][j] == 1 && label[i + 1][j] == 0) {
mStack.push(new int[]{i + 1, j});
label[i + 1][j] = marker;
}
// Check if this is not first column
if (j != nCol - 1) {
if (img[i + 1][j + 1] == 1 && label[i + 1][j + 1] == 0) {
mStack.push(new int[]{i + 1, j + 1});
label[i + 1][j + 1] = marker;
}
}
}
}
marker++;
}
return label;
}
}
这是一个例子和结果。
考虑下图
{1, 0, 0, 0, 0, 1, 0, 1},
{0, 0, 1, 1, 0, 1, 0, 0},
{0, 0, 0, 1, 0, 1, 0, 0},
{0, 1, 0, 1, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 1, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
结果
[1, 0, 0, 0, 0, 2, 0, 3]
[0, 0, 4, 4, 0, 2, 0, 0]
[0, 0, 0, 4, 0, 2, 0, 0]
[0, 5, 0, 4, 0, 0, 0, 6]
[0, 0, 0, 0, 0, 7, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 8]
[0, 0, 0, 0, 0, 9, 8, 8]
[0, 0, 0, 0, 0, 0, 0, 0]
这里的问题是第 6 行和第 7 行(从 1 开始)
据我所知,该算法使用 8-cohesion,但我以其他方式考虑了它。
是否正确地将 9 识别为新对象?该算法以这种方式检查邻居(U - 未检查,C-检查,X - 当前单元格)
CCU
CXU
CCU单元格 [7,8] 有什么问题,为什么它被标记,错误在哪里?
总而言之,我在图像处理和识别方面没有太多经验,所以如果有更好的算法和使用示例的任何帮助或建议,我将不胜感激。
谢谢。