我需要识别二进制图像中的对象。
我在互联网上搜索可能的算法,其中有很多,但不幸的是,我个人很难将原始公式转换为代码算法而没有任何直观的解释。
我找到了这个算法http://www.izbi.uni-leipzig.de/izbi/publikationen/publi_2004/IMS2004_JankowskiKuska.pdf。
此外,本文还介绍了Java
实现。
正如作者写的那样
方法labelImage现在可用作任何Mathematica 内置或用户定义的功能
不幸的是,如果1
在角落,第一个,最后一个位置,因为如果检查丢失,这个算法会失败。
如果我们发现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 - 当前小区)
C C U单元格[7,8]有什么问题被标记,哪里出错?
总而言之,我在图像处理和识别方面没有太多经验,所以如果有更好的算法和使用示例的帮助或建议,我将不胜感激。
感谢。