圖像處理之基於圖的廣度優先搜索組件標記算法

圖像處理之基於圖的廣度優先搜索組件標記算法java

一:圖的遍歷與廣度優先搜索算法算法

圖的遍歷算法最經常使用是廣度優先搜索算法(BFS)與深度優先搜索算法(DFS),從一個的ide

節點開始,訪問相鄰的全部子節點,接着從這些子節點出發訪問下個相鄰子節點,如post

此重複直到全部節點都被訪問。this

20140329134814359


二:二值圖像組件標記實現流程spa

若是把圖像的每一個像素點當作爲圖的一個節點,則二值圖像中的每一個連通區域均可以get

當作一個無向圖,只要遍歷圖像中的每一個像素點就能夠找出每一個連通區域,實現對二it

值圖像連通區域組件的標記。大體步驟爲:io

1.      掃描圖像的每一個像素點,得到位置信息與圖像的灰度值強度(0~255)成爲圖的節點圖像處理

2.      對每一個節點,初始化狀態與獲取它的上下左右四個鄰域節點

20140329134906984


1.      遍歷每一個節點- BFS

2.      輸出結果與顯示

三:運行效果

20140329135014578


四:關鍵程序實現代碼

圖的搜索算法,節點狀態有三種,未訪問(Unvisit),已經訪問(Visited),已經標記(Marked)


package com.gloomyfish.p_w_picpath.watershed; 
       
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
       
/**
 * Breath First Search for graphics
 * @author gloomyfish
 *
 */ 
public class BFSAlgorithm { 
    private List<PixelPoint> pixelList = null; 
    private int grayLevel = 1; 
    public int getGrayLevel() { 
        return grayLevel; 
    } 
           
    public int getTotalOfLabels() 
    { 
        Map<Integer, Integer> labelMap = new HashMap<Integer, Integer>(); 
        for(PixelPoint p : pixelList) 
        { 
            if(p.getValue() >= grayLevel) 
            { 
                if(labelMap.containsKey(p.getLabel())) 
                { 
                    Integer count = labelMap.get(p.getLabel()); 
                    count += 1; 
                    labelMap.put(p.getLabel(), count); 
                } 
                else 
                { 
                    labelMap.put(p.getLabel(), new Integer(1)); 
                } 
            } 
        } 
        Integer[] keys = labelMap.keySet().toArray(new Integer[0]); 
        for(Integer key : keys) 
        { 
            System.out.println("Label index : " + key); 
        } 
        System.out.println("total labels : " + labelMap.size()); 
        return labelMap.size(); 
    } 
       
    public void setGrayLevel(int grayLevel) { 
        this.grayLevel = grayLevel; 
    } 
       
    public BFSAlgorithm(List<PixelPoint> pixelList) 
    { 
        this.pixelList = pixelList; 
        grayLevel = 1; // front color - target pixel 
    } 
           
    public void process() 
    { 
        if(this.pixelList == null) return; 
        int label = 1; 
        for(PixelPoint pp : pixelList) 
        { 
            if(pp.getValue() >= grayLevel) 
            { 
                if(pp.getStatus() == PixelPoint.UNMARKED) 
                { 
                    pp.setStatus(PixelPoint.VISITED); 
                    pp.setLabel(label); 
                    MyQueue mq = new MyQueue(10000); 
                    for(PixelPoint npp : pp.getNeighbours()) 
                    { 
                        if(npp.getStatus() == PixelPoint.UNMARKED && npp.getValue() >= grayLevel) 
                        { 
                            npp.setStatus(PixelPoint.MARKED); 
                            mq.enqueue(npp); 
                        } 
                    } 
                    while(!mq.isEmpty()) 
                    { 
                        PixelPoint obj = (PixelPoint)mq.dequeue(); 
                        if(obj.getStatus() == PixelPoint.MARKED) 
                        { 
                            obj.setLabel(label); 
                            obj.setStatus(PixelPoint.VISITED); 
                        } 
                        for(PixelPoint nnpp : obj.getNeighbours()) 
                        { 
                            if(nnpp.getStatus() == PixelPoint.UNMARKED && nnpp.getValue() >= grayLevel) 
                            { 
                                nnpp.setStatus(PixelPoint.MARKED); 
                                mq.enqueue(nnpp); 
                            } 
                        } 
                    } 
                    label++; 
                } 
            } 
        } 
    } 
       
}

圖像組件標記算法代碼:



package com.gloomyfish.p_w_picpath.watershed; 
    
import java.awt.p_w_picpath.BufferedImage; 
import java.util.ArrayList; 
import java.util.List; 
    
import com.gloomyfish.filter.study.AbstractBufferedImageOp; 
/**
 * work for binary p_w_picpath
 * @author fish
 *
 */ 
public class LabelledConnectedRegionAlg extends AbstractBufferedImageOp { 
    
    @Override 
    public BufferedImage filter(BufferedImage src, BufferedImage dest) { 
        int width = src.getWidth(); 
        int height = src.getHeight(); 
    
        if ( dest == null ) 
            dest = createCompatibleDestImage( src, null ); 
        List<PixelPoint> pixelList = new ArrayList<PixelPoint>(); 
        int[] inPixels = new int[width*height]; 
        int[] outPixels = new int[width*height]; 
        getRGB( src, 0, 0, width, height, inPixels ); 
        int index = 0; 
        for(int row=0; row<height; row++) { 
            for(int col=0; col<width; col++) { 
                index = row * width + col; 
                PixelPoint p = new PixelPoint(row, col, (inPixels[index] >> 16) & 0xff); 
                pixelList.add(p); 
            } 
        } 
            
        for(int row=0; row<height; row++) { 
            for(int col=0; col<width; col++) { 
                index = row * width + col; 
                PixelPoint p = pixelList.get(index); 
                    
                // add four neighbors for each pixel 
                if((row - 1) >= 0) 
                { 
                    index = (row-1) * width + col; 
                    p.addNeighour(pixelList.get(index)); 
                } 
                if((row + 1) < height) 
                { 
                    index = (row+1) * width + col; 
                    p.addNeighour(pixelList.get(index)); 
                } 
                if((col - 1) >= 0) 
                { 
                    index = row * width + col-1; 
                    p.addNeighour(pixelList.get(index)); 
                } 
                if((col+1) < width) 
                { 
                    index = row * width + col+1; 
                    p.addNeighour(pixelList.get(index)); 
                } 
            } 
        } 
    
        BFSAlgorithm bfs = new BFSAlgorithm(pixelList); 
        bfs.process(); 
        int labels = bfs.getTotalOfLabels(); 
        int unit = 255 / (labels+1); 
            
        // post process - color different labels 
        for(int row=0; row<height; row++) { 
            int ta = 0, tr = 0, tg = 0, tb = 0; 
            for(int col=0; col<width; col++) { 
                index = row * width + col; 
                PixelPoint p = pixelList.get(index); 
                ta = 255; 
                if(p.getLabel() > 0) 
                { 
                    tr = 0; // unit * p.getLabel(); 
                    tg = unit * p.getLabel(); 
                    tb = unit * p.getLabel(); 
                } 
                else 
                { 
                    tr = p.getValue(); 
                    tg = p.getValue(); 
                    tb = p.getValue(); 
                } 
                outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb; 
            } 
        } 
            
        setRGB( dest, 0, 0, width, height, outPixels ); 
        return dest; 
    } 
    
}

轉載請務必註明

相關文章
相關標籤/搜索