java hough變換(霍夫變換)檢測直線

閱讀前請看<前言>,謝謝!

霍夫變換(Hough Transform)是圖像處理中的一種特徵提取技術,他是檢測和定位直線和解析曲線的有效方法,它通過將邊緣二值圖像變換到Hough空間,在參數空間用極值點的檢測來完成目標的檢測。

就直線檢測而言:

在極座標中ρ = x cos(θ) + y sin(θ)表示一條直線。其中(ρ,θ)確定一條直線,因此可以先將圖片進行邊緣檢測,然後對圖像上每一個非零像素點,在參數座標下變換爲一條直線,然後構建hist(ρ,θ)二維直方圖。在二維直方圖中找到大於給定閾值的值,即爲檢測到的直線。對θ的取值爲0-90度,ρ的取值爲0-sqrt(h*h+w*w),其中邊緣檢測算子我採用sobel算子,也可以用我前兩篇提到的另外兩種邊緣檢測算子。

程序代碼如下:

public void hough(){
		Image im = this.clone();
		im.sobel();
		im.IterBinary();
		
		int ro = (int)Math.sqrt(h*h+w*w);
		int theta = 180;
		int[][] hist = new int[ro][theta];
		
		for(int k=0;k<theta;k++){
			for(int i=0;i<h;i++){
				for(int j=0;j<w;j++){
					if(im.data[j+i*w] != 0){
						int rho=(int)(j*Math.cos(k*Math.PI/(theta*2))+i*Math.sin(k*Math.PI/(theta*2)));
			            hist[rho][k]++;
					}      
				}
			}
		}
		
		ArrayList<h> index = math.maxIndex(hist,70); //找到大於最大值*0.7的二維直方圖的點
		
		for(int k =0;k<index.size();k++){
			
			double resTheta = index.get(k).angle*Math.PI/(theta*2);

		    for(int i=0;i<h;i++){
		    	for(int j=0;j<w;j++){
		    		int rho = (int)(j*Math.cos(resTheta)+i*Math.sin(resTheta));
		            if(im.data[j+i*w] != 0 && rho == index.get(k).ro){
		            	data[j+i*w] = setRed();   //在直線上的點設爲紅色
		            }else{
		            	data[j+i*this.w] = (255<<24)|(data[j+i*this.w]<<16)|(data[j+i*this.w]<<8)|(data[j+i*this.w]);
		            } 	
		    	}   
		    }
		}
	    
	    this.gray = false;
	}
其中
/*
 * to save the hough transform's results
 */
class h{
	int ro;
	int angle;
	
	public h(int r,int a){
		this.ro = r;
		this.angle = a;
	}
}
 
運行結果如下:

soble算子處理加二值化的結果如下:


該程序只能檢測到0-90度的直線。

發佈了53 篇原創文章 · 獲贊 32 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章