HC(Histogram-based Contrast) 基于直方图对比度的显著性(算法原理与代码分析)

来源于: 2011, Global contrast based salient region detection, ChengSaliencyCVPR2011.pdf (mmcheng.net)

详见作者主页: Global contrast based salient region detection – 程明明个人主页 (mmcheng.net)t

 HC算法中图像目标显著性定义:

图像中像素的显著性值可以它和图像中其它像素的对比度来定义, 具体公式为:

S(I_{k})=S(c_{l})=\sum_{j=1}^{n}f_{j}D(c_{l},c_{j})

其中, c_{l}为像素I_{k} 的颜色, n为图像中所有颜色的总数, f_{j} 为 c_{j} 在图像I中出现的概率, D(c_{l},c_{j})为颜色c_{l},c_{j}在彩色空间Lab之间的距离.

对于每个像素,使用上述公式就可以计算其显著性, 从而可以得到图像中目标的显著性.

然而,上述公式存在一个问题: 对于三维颜色空间,例如RGB颜色空间, 8bit数据的颜色总数为 255x255x255=16581375, 计算量异常庞大,不适合实际应用.

算法加速优化

对于三维颜色空间来说,可以将颜色进行量化,进而减少计算量;如将颜色量化到12个不同的值(在RGB颜色空间量化), 这样颜色总数为 12x12x12=1728. 同时丢弃部分频率较小的颜色, 用相近的颜色代替(在Lab颜色空间计算距离).

最后, 为了提高效率,对量化后的图像直方图进行操作, 避免对整幅图像进行处理。

颜色空间平滑

为了达到更好的效果,可以进行一步平滑操作。

一些相似的颜色可能被数量化为不同的值。为了减少这类由于随机性给显著结果引入的噪声,采取一套平滑程序来改善每个颜色的显著值。用相似颜色的显著值加权平均来代替每个颜色(以Lab*距离测量)的显著值。选择m=n/4个最近的颜色作为代表来改善颜色c的显著值,如方程:

S'(c)=\frac{1}{(m-1)T}\sum_{i=1}^{m}(T-D(c,c_{i}))S(c_{i})

其中, T=\sum_{i=1}^{m}D(c,c_{i})为颜色 c 和它最相似的 m 个颜色的距离之和.


算法步骤:

  • 量化颜色通道。找出图像中一共有多少种颜色以及对应的像素总数。
  • 按照像素总数从大到小排序,并同时记录相应颜色。
  • 找出像素数目覆盖图像不小于95%的高频颜色,以及其他的不高于5%的颜色种类,假设高频颜色共有maxnum种。
  • 把低频颜色的像素归类到与它lab颜色距离相距最近的高频颜色中。
  • 在maxnum种颜色中,计算颜色i到所有其他颜色j的颜色距离。并按照距离从小到大排序,记录相应j的颜色种类。
  • 计算每一种颜色的显著值。根据第5步,可以找到距离颜色i相距最近的m种颜色,从而可以计算每种颜色显著值,即最终的显著值。
  • 为图像中每一个像素分配显著值。像素(i,j)是什么颜色,就赋予它相应颜色的显著值。
  • 至此,显著图生成。进行归一化、线性空间滤波。

MATLAB算法

%读取图像
%orpic = imread(img_name);
clear all;
clc;
close all;
orpic = imread('test.jpg');
figure;imshow(orpic);
%获取图像的长、宽和通道值
[row ,column, nn] = size(orpic);
%生成调色板pallet(color,number),默认调色板大小为图像大小
pallet = zeros(row*column,2);
%设置阶梯值,为了将rgb量化后的结果化成一个12进制的数
w = [12*12,12,1];%RGB通道各自的权重,这里的权重不能设置为一样的,这是为了保证不一样的rgb组合得到的值不同
idx = uint32(1);%调色板像数值个数
SUM = uint32(0);%量化和
RGBSUM = zeros(row,column);%原图像为三维彩图,将RGB通道加权后每个像素的值
for i = 1 : row
   for j = 1 : column
       %获取第i行第j列的R、G、B通道的值,并量化为12阶后再转化为一个数
       a1 = floor((double(orpic(i,j,1))/255)*(12-0.0001))*w(3);
       a2 = floor((double(orpic(i,j,2))/255)*(12-0.0001))*w(2);
       a3 = floor((double(orpic(i,j,3))/255)*(12-0.0001))*w(1);
       SUM = int32(a1) + int32(a2) + int32(a3);
%        SUM = 3* int32(a1);
       RGBSUM(i,j) = SUM;
       
       %对于每个像数值,将其归类到调色板中,先在已经归类的pallet中查找,如果遍历完毕发现未归类,则将索引+1并归类
       %找出处理后的数据有多少种颜色值,以及其频数
       if idx == 1
           pallet(idx,1) = SUM;
           pallet(idx,2) = pallet(idx,2) + 1;
           idx = idx + 1;
           continue;
       end
       flag = 0;
       for m = 1 : idx-1
           if pallet(m,1) == SUM
               pallet(m,2) = pallet(m,2) + 1;
               flag = 1;
               break;
           end
       end
       if flag == 0 
            pallet(idx,1) = SUM;
            pallet(idx,2) = pallet(idx,2) + 1;
            idx = idx + 1;
       end
    end
end
%获取图中所有的颜色值
idx = idx -1;
pallet = pallet(1:idx,:);%调色板截断,保留真实调色个数

%生成新的调色板num(number,color),使得颜色按照频数从大到小排列,且一号位为频数大小,二号位为处理后的颜色值
palletemp = pallet(:,2);
[b,pos] = sort(palletemp,'descend');
num = zeros(idx,2);
for i = 1 : idx
    num(i,1) = b(i);
    num(i,2) = pallet(pos(i),1);
end

%计算如果要保留95%的处理后的颜色值,需要保留调色板的多少位
maxnum = idx;
maxdropnum = floor(row*column*(1-0.95));
crnt = num(maxnum,1);
while(crnt<maxdropnum && maxnum>1)
    crnt = crnt + num(maxnum-1,1);
    maxnum = maxnum - 1;
end
%保证保留的颜色值个数小于256且尽量不太小
maxnum = min(maxnum,256);
if maxnum < 10
    maxnum = min(idx,100);
end
 
%将处理后的颜色值转化回RGB对应的值,此处会有+-1的误差,影响不大
 color3i = zeros(idx,3);
 for i = 1:idx
    color3i(i,1) = round(num(i,2)/w(1));
    color3i(i,2) = round(mod(num(i,2),w(1))/w(2));
    color3i(i,3) = round(mod(num(i,2),w(2)));
 end

%建立色板pallet(number,color,pos),其中pos为保留颜色的序号
a = zeros(idx,1);
pallet = [num,a];
for i = 1:maxnum
    pallet(i,3) = i;
end    

%将舍弃的颜色归到其最相近的颜色当中
for i = (maxnum+1):idx
    simidx = 99999999;simval = 99999999;
    for j  = 1:maxnum
        d_ij = round((color3i(i,1)-color3i(j,1))^2 + (color3i(i,2)-color3i(j,2))^2 + (color3i(i,3)-color3i(j,3))^2);
        if d_ij < simval
            simval = d_ij;
            simidx = j;
        end
    end
    pallet(simidx,1) = pallet(simidx,1) + pallet(i,1);
    pallet(i,3) = simidx;
end
 
%将图像中属于某一“颜色值”的所有颜色的rgb值累加之后求平均再归一,即调整保留下来颜色值
 rgbcolor = zeros(idx,4);
 for n =1:idx
     for i = 1:row
         for j = 1:column
             if RGBSUM(i,j) == pallet(n,2)
                rgbcolor(n,1) = int32(rgbcolor(n,1)) + int32(orpic(i,j,1));
                rgbcolor(n,2) = int32(rgbcolor(n,2)) + int32(orpic(i,j,2));
                rgbcolor(n,3) = int32(rgbcolor(n,3)) + int32(orpic(i,j,3));
                rgbcolor(n,4) = double(pallet(n,3));
             end
         end
     end
 end
for i = 1:maxnum
    for j = (maxnum+1):idx
        if rgbcolor(j,4) == i
            rgbcolor(i,1) = (rgbcolor(i,1) + rgbcolor(j,1));
            rgbcolor(i,2) = (rgbcolor(i,2) + rgbcolor(j,2));
            rgbcolor(i,3) = (rgbcolor(i,3) + rgbcolor(j,3));
        end
    end
    rgbcolor(i,1) = (rgbcolor(i,1)/pallet(i,1))/255;
    rgbcolor(i,2) = (rgbcolor(i,2)/pallet(i,1))/255;
    rgbcolor(i,3) = (rgbcolor(i,3)/pallet(i,1))/255;
end

%将颜色格式由RGB转为Lab
labcolor = zeros(maxnum,3);
for i = 1:maxnum
    a = zeros(1,1,3);
    a(1,1,1) = rgbcolor(i,1);
    a(1,1,2) = rgbcolor(i,2);
    a(1,1,3) = rgbcolor(i,3);
    b = rgb2lab(a);
    labcolor(i,1) = b(1,1,1);
    labcolor(i,2) = b(1,1,2);
    labcolor(i,3) = b(1,1,3);
end

%存放颜色i与颜色j在Lab空间上的距离
distemp = zeros(maxnum,maxnum,2);
%每行将颜色j与颜色i的在Lab空间上的距离按从小到大排列
dist = zeros(maxnum,maxnum,2);
%存放平滑前的颜色显著值
colorsaltemp = zeros(maxnum,2);
for i = 1:maxnum
    for j = 1:maxnum
        %计算颜色i与颜色j在Lab空间上的距离
        distemp(i,j,1) = norm(labcolor(i,:)-labcolor(j,:),2);
        distemp(i,j,2) = j;
    end
    for k = 1:maxnum
        if k == i
            continue;
        end
        %颜色i在平滑之前的颜色显著值,为S(c)=ΣP(c)D(c,a),a为其他的颜色
        colorsaltemp(i,1) = colorsaltemp(i,1) + (pallet(k,1)/(row*column))*distemp(i,k,1);
        colorsaltemp(i,2) = i;
    end
    
    [b,pos] = sort(distemp(i,:,1),'ascend');  
    for k = 1:maxnum
        dist(i,k,1) = b(k);
        dist(i,k,2) = distemp(i,pos(k),2);
    end
end

%对各颜色进行平滑操作
colorsal = zeros(maxnum,2);
%计算权值时使用的颜色i与和其最邻近颜色的个数
n = double(round(maxnum/4));
%保存与颜色i在Lab空间上最相近的n=maxnum/4个点的距离的和
totaldist = zeros(maxnum,1);
for i = 1:maxnum
    %计算与颜色i在Lab空间上最相近的n=maxnum/4个点的距离的和
    for j = 2:n
        totaldist(i,1) = totaldist(i,1) + dist(i,j,1);
    end
    valcrnt = 0;
    for j = 1:n
        valcrnt = valcrnt + colorsaltemp(dist(i,j,2),1)*(totaldist(i,1)-dist(i,j,1));
    end
    colorsal(i,1) = valcrnt/((n-1)*totaldist(i,1));
    colorsal(i,2) = i;
end

%保存原图像各像素的显著值
sal = zeros(row,column);
for i = 1:row
    for j = 1:column
        for n = 1:idx
            if RGBSUM(i,j) == pallet(n,2)
                sal(i,j) = colorsal(pallet(n,3),1);
            end
        end
    end
end
saliency = (sal - min(min(sal)))/(max(max(sal)) - min(min(sal)));
A=fspecial('gaussian',[3,3],0.5);  
saliency=imfilter(saliency,A,'replicate');
%显示显著性图
subplot(1,2,1),imshow(saliency); 
subplot(1,2,2),imshow(sal,[]);

跟多资料请移步公众号:LonaXiao学长


参考链接:

【手撕算法】HC显著性检测算法_hc算法_qq_43667130的博客-CSDN博客

HC(Histogram-based Contrast) 基于直方图对比度的显著性 - 知乎

部分理论引用网络文献,若有侵权联系博主删除。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值