这篇文章主要介绍显著性检测的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代码