這篇文章主要介紹顯著性檢測的LC和HC算法的java實現
1.LC算法
1.1基本思想
LC算法由Yun 和Mubarak 在2006年的視頻顯著性檢測中提出,其在論文中提出當觀眾觀看視頻序列時,他們不僅會被有趣的事件吸引,有時還會被靜止圖像中有趣的物體吸引。這就是空間注意力。在心理學研究的基礎上,人的感知系統對視覺信息之間的對比更敏感,如顏色、強度和質地。以這一假設為基礎,提出了一種利用圖像顏色統計計算空間顯著性圖的有效方法。該算法的設計考慮了圖像像素數目的線性計算復雜性。圖像的顯著性映射建立在圖像像素之間的灰度對比度上。即為該像素與圖中所有像素在灰度值上的距離之和作為該像素的顯著性值。
1.2顯著值計算過程
圖像I中像素Ik的顯著性值定義為:
其中,Ii的值在(0,255)范圍內, || . ||表示灰度距離度量。將該方程展開為以下形式:
即圖中一個像素的顯著性定義為該像素的灰度值與全圖所有像素的灰度值差值的和
1.3 代碼如下
1 import org.opencv.core.Core; 2 import org.opencv.core.CvType; 3 import org.opencv.core.Mat; 4 import org.opencv.imgcodecs.Imgcodecs; 5 6 public class LC { 7 8 //src:讀取的圖片mat 9 //path:圖片所在目錄 10 //name:圖片名字 11 public static void SalientRegionDetectionBasedonLC(Mat Src,String path,String name) 12 { 13 int X, Y, Index, CurIndex ,Value; //XY用於遍歷,其他的下面有注釋 14 int width=Src.cols(); 15 int height=Src.rows(); 16 17 byte[] Gray = new byte[width*height] ; //灰度圖,用byte類型是為了節省空間 18 int[] Dist = new int[256]; //存放每種灰度值對全圖的距離 19 int[] HistGram = new int[256]; //記錄每個灰度值的存在個數 20 int[] DistMap = new int[height * width]; //顯著圖,沒有用byte類型是因為算出來每個像素的顯著性值會超過byte的最大值 21 22 /*{ 23 byte a = -127; 24 System.out.print(a + " " + (a & 0xff)); //Java 總是把 byte 當做有符處理;我們可以通過將其和 0xFF 進行二進制與得到它的無符值 25 int b = a & 0xff; //與完結果為int 26 a = (byte) b; //強制轉換能把128以外的數轉為負數 27 }*/ 28 29 byte[] temp= new byte[Src.cols()*Src.rows()*Src.channels()]; //從mat中得到rgb信息,大小為像素數*通道數 30 Src.get(0,0,temp); //像素信息存入temp 31 32 Index=0; //用於遍歷每個像素 33 for(X=0;X<height;X++){ 34 for(Y=0;Y<width;Y++){ 35 Value = ((temp[Index]&0xff)*30+(temp[Index+1]&0xff)*59+(temp[Index+2]&0xff)*11)/100; 36 //得到每個像素灰度值,灰度值公式 Gray = (R*30 + G*59 + B*11 + 50) / 100,opencv讀取是BGR順序,我這里寫反了,影響不大 37 HistGram[Value]++; //存放每個灰度值存在的個數,為int型,下標范圍0-255; 38 Gray[Index/3]= (byte)Value; //除法可以優化,將灰度值存入每個像素中 39 Index +=3; 40 } 41 } 42 //計算顯著性 43 for (Y = 0; Y < 256; Y++) //計算灰度值為Y的顯著性 44 { 45 Value = 0; 46 for (X = 0; X < 256; X++) //遍歷所有灰度值。計算與Y的距離 47 Value += Math.abs(Y - X) * HistGram[X]; //灰度的距離只有絕對值,距離*該種灰度值存在數量 48 Dist[Y] = Value; //存放灰度值Y全圖像素的距離 49 } 50 51 CurIndex=0; //用於遍歷每個像素 52 for (Y = 0; Y < height; Y++) 53 { 54 for (X = 0; X < width; X++) 55 { 56 DistMap[CurIndex] = Dist[Gray[CurIndex]&0xff]; 57 //計算全圖每個像素的顯著性,CurIndex為當前遍歷的像素,Gray[CurIndex]&0xff為該像素的灰度值 58 CurIndex ++; 59 } 60 } 61 62 Mat grayimg = new Mat(height, width, CvType.CV_32SC1); //創建mat,類型為32位無符號一通道灰度圖,先高度(多少行)后寬度 63 grayimg.put(0, 0, DistMap); //將全圖顯著性存入grayimg 64 65 Core.normalize(grayimg,grayimg,0,255,Core.NORM_MINMAX); //歸一化,NORM_MINMAX為線性歸一化 66 Imgcodecs.imwrite(path+"/result/LC/"+name+".png", grayimg); //生成圖片 67 } 68 }
1.4 效果
可以看到對於背景不復雜的圖片lc算法的效果還是可以的,背景復雜起來,這些傳統的自底向上的方法效果都不會很好。
2 HC算法
2.1基本思想
2.2原理
2.3代碼