1

我有这个程序来检测二值化 BufferedImage 中的对象,该图像是多选答题纸。
我正在尝试使用 4-Connectivity 来检测每个对象(工作表上的答案)。
到目前为止,我手头的来源是这些:

  1. http://en.wikipedia.org/wiki/Connected-component_labeling
  2. http://homepages.inf.ed.ac.uk/rbf/HIPR2/label.htm

我想出了这个,按照维基百科的说明:

if(getPixel(image, x, y) != 0){
    if(getPixel(image, x-1, y) !=0){
        System.out.println("we are in the same region");
        region[x][y] = region[x-1][y];
    } 
    else if(getPixel(image, x-1, y) !=0 && getPixel(image, x, y-1) !=0){
        System.out.println("North and West pixels belong to the same region and must be merged");
        region[x][y] = Math.min(region[x-1][y], region[x][y-1]);
    }
    else if( getPixel(image, x-1, y) ==0 && getPixel(image, x, y-1) !=0){
        System.out.println("Assign the label of the North pixel to the current pixel");
        region[x][y] = region[x][y-1];
    }
    else if(getPixel(image, x-1, y) ==0 && getPixel(image, x, y-1) ==0){
        System.out.println("Create a new label id and assign it to the current pixel");
        cpt++;
        region[x][y] = cpt;
    }

但问题是它创建了 51 个区域!它只打印每个对象的几个顶部像素(不是所有像素)。
谁能帮我找出问题所在以及如何检测我的对象?
我将不胜感激任何帮助。

4

2 回答 2

1

您可能会得到很多区域,因为您似乎没有合并相等的标签。在您的代码片段中没有用于存储相等标签的代码。该算法是一个两遍算法,其中第一遍分配标签,第二遍合并相等的标签。

以下是维基百科页面引用的条件检查:

检查条件:

  1. 左侧(西)的像素是否与当前像素具有相同的值?
    1. 的——我们在同一个地区。为当前像素分配相同的标签
    2. - 检查下一个条件
  2. 当前像素以北和以西的两个像素是否与当前像素具有相同的值但不同的标签?
    1. ——我们知道 North 和 West 像素属于同一区域,必须合并。为当前像素分配North和West标签中的最小值,并记录它们的等价关系
    2. - 检查下一个条件
  3. 左侧(西)的像素是否具有不同的值,而北侧的像素是否与当前像素具有相同的值?
    1. - 将北像素的标签分配给当前像素
    2. - 检查下一个条件
  4. 像素的北邻和西邻是否具有与当前像素不同的像素值?
    1. - 创建一个新的标签 id 并将其分配给当前像素

你的第二个条件检查,

else if(getPixel(image, x-1, y) !=0 && getPixel(image, x, y-1) !=0)

不检查左像素和上像素是否有不同的标签。

此外,就像评论中提到的 supersam654 一样,else if永远不会调用第一个。似乎维基百科页面上的条件检查 (1) 和 (2) 的顺序应该相反。即首先检查左上像素是否与当前像素具有相同的值但不同的标签。然后,如果该检查失败,请检查左侧像素是否与当前像素具有相同的值。

所以尝试以下方法:

  1. 将标签条件添加到您的第二个条件检查中。
  2. 切换前两个条件检查的顺序。
  3. 跟踪相同的标签(即,哪些标签代表相同的区域)。
  4. 对图像进行第二次遍历并合并相等的标签。

我希望这有帮助。

于 2013-11-14T07:22:26.077 回答
0

虽然我不完全确定这是否能回答您的问题,但我会将您的代码修改为如下所示:

if(getPixel(image, x, y) != 0){
    if(getPixel(image, x-1, y) !=0){
        if(getPixel(image, x, y-1) !=0) {
            System.out.println("North and West pixels belong to the same region and must be merged");
            region[x][y] = Math.min(region[x-1][y], region[x][y-1]);
        } else {
            System.out.println("we are in the same region");
            region[x][y] = region[x-1][y];
        }
    } else if(getPixel(image, x-1, y) ==0) {
        if(getPixel(image, x, y-1) !=0) {
            System.out.println("Assign the label of the North pixel to the current pixel");
            region[x][y] = region[x][y-1];
        } else if (getPixel(image, x, y-1) ==0) {
            System.out.println("Create a new label id and assign it to the current pixel");
            cpt++;
            region[x][y] = cpt;
        }
    }
于 2013-05-07T20:32:20.840 回答