圖像處理之基於圖的廣度優先搜索組件標記算法java
一:圖的遍歷與廣度優先搜索算法算法
圖的遍歷算法最經常使用是廣度優先搜索算法(BFS)與深度優先搜索算法(DFS),從一個的ide
節點開始,訪問相鄰的全部子節點,接着從這些子節點出發訪問下個相鄰子節點,如post
此重複直到全部節點都被訪問。this
二:二值圖像組件標記實現流程spa
若是把圖像的每一個像素點當作爲圖的一個節點,則二值圖像中的每一個連通區域均可以get
當作一個無向圖,只要遍歷圖像中的每一個像素點就能夠找出每一個連通區域,實現對二it
值圖像連通區域組件的標記。大體步驟爲:io
1. 掃描圖像的每一個像素點,得到位置信息與圖像的灰度值強度(0~255)成爲圖的節點圖像處理
2. 對每一個節點,初始化狀態與獲取它的上下左右四個鄰域節點
1. 遍歷每一個節點- BFS
2. 輸出結果與顯示
三:運行效果
四:關鍵程序實現代碼
圖的搜索算法,節點狀態有三種,未訪問(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; } }
轉載請務必註明