/// <summary>
/// 实现功能: 基于全局对比度的图像显著性检测
/// 参考论文: 2011 CVPR Global Contrast based salient region detection Ming-Ming Cheng
/// http://mmcheng.net/salobj/
/// 整理时间: 2014.8.3
/// </summary>
/// <param name="Src">需要进行检测的图像数据,只支持24位图像。</param>
/// <param name="SaliencyMap">输出的显著性图像,也是24位的。</param>
/// <param name="Width">输入的彩色数据的对应的灰度数据。</param>
/// <param name="Height">输入图像数据的高度。</param>
/// <param name="Stride">图像的扫描行大小。</param>
/// <remarks> 在Lab空间进行的处理,使用了整形的LAB转换,采用抖动技术将图像颜色总数量降低为256种,在利用直方图计算出显著性查找表,最后采用高斯模糊降低量化后的颗粒感。</remarks>
void __stdcall SalientRegionDetectionBasedonHC(unsigned char *Src, unsigned char *SaliencyMap, int Width, int Height, int Stride)
{
int X, Y, XX, YY, Index, Fast, CurIndex;
int FitX, FitY, FitWidth, FitHeight;
float Value;
unsigned char *Lab = (unsigned char *) malloc(Height * Stride);
unsigned char *Mask = (unsigned char *) malloc(Height * Width);
float *DistMap = (float *) malloc(Height * Width * sizeof(float));
float *Dist = (float *)malloc(256 * sizeof(float));
int *HistGram = (int *)malloc(256 * sizeof(int));
GetBestFitInfoEx(Width, Height, 256, 256, FitX, FitY, FitWidth, FitHeight);
unsigned char *Sample = (unsigned char *) malloc(FitWidth * FitHeight * 3);
InitRGBLAB();
for (Y = 0; Y < Height; Y++)
RGBToLAB(Src + Y * Stride, Lab + Y * Stride, Width);
Resample (Lab, Width, Height, Stride, Sample, FitWidth, FitHeight, FitWidth * 3, 0); // 最近邻插值
RGBQUAD *Palette = ( RGBQUAD *)malloc( 256 * sizeof(RGBQUAD));
GetOptimalPalette(Sample, FitWidth, FitHeight, FitWidth * 3, 256, Palette);
ErrorDiffusionFloydSteinberg(Lab, Mask, Width, Height, Stride, Palette, true); // 先把图像信息量化到较少的范围内,这里量化到256种彩色
memset(HistGram, 0, 256 * sizeof(int));
for (Y = 0; Y < Height; Y++)
{
CurIndex = Y * Width;
for (X = 0; X < Width; X++)
{
HistGram[Mask[CurIndex]] ++;
CurIndex ++;
}
}
for (Y = 0; Y < 256; Y++) // 采用类似LC的方式进行显著性计算
{
Value = 0;
for (X = 0; X < 256; X++)
Value += sqrt((Palette[Y].rgbBlue - Palette[X].rgbBlue)*(Palette[Y].rgbBlue - Palette[X].rgbBlue) + (Palette[Y].rgbGreen- Palette[X].rgbGreen)*(Palette[Y].rgbGreen - Palette[X].rgbGreen) + (Palette[Y].rgbRed- Palette[X].rgbRed)*(Palette[Y].rgbRed - Palette[X].rgbRed)+ 0.0 ) * HistGram[X];
Dist[Y] = Value;
}
for (Y = 0; Y < Height; Y++)
{
CurIndex = Y * Width;
for (X = 0; X < Width; X++)
{
DistMap[CurIndex] = Dist[Mask[CurIndex]];
CurIndex ++;
}
}
Normalize(DistMap, SaliencyMap, Width, Height, Stride); // 归一化图像数据
GuassBlur(SaliencyMap, Width, Height, Stride, 1); // 最后做个模糊以消除分层的现象
free(Dist);
free(HistGram);
free(Lab);
free(Palette);
free(Mask);
free(DistMap);
free(Sample);
FreeRGBLAB();
}