Java Image Connective组件

时间:2013-05-07 12:28:27

标签: java image-processing bufferedimage

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

  1. http://en.wikipedia.org/wiki/Connected-component_labeling
  2. http://homepages.inf.ed.ac.uk/rbf/HIPR2/label.htm
  3. 我按照维基百科的指示提出了这个问题:

    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个地区!它只打印每个对象的几个顶部像素(不是所有像素) 任何人都可以帮我找到问题是什么,如何检测我的物体? 我将不胜感激任何帮助。

2 个答案:

答案 0 :(得分:1)

您可能会获得很多区域,因为您似乎没有合并相同的标签。没有用于在代码段中存储相同标签的代码。该算法是双通算法,其中第一个传递分配标签,第二个传递合并相同的标签。

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

  

检查条件:

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

你的第二个条件检查,

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

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

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

请尝试以下方法:

  1. 将标签条件添加到第二次条件检查中。
  2. 切换前两次条件检查的顺序。
  3. 跟踪相同的标签(即哪些标签代表相同的区域)。
  4. 对图像进行第二次传递并合并相同的标签。
  5. 我希望这会有所帮助。

答案 1 :(得分: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;
        }
    }