當影像的色階集中於集中於某些極端的位置時,會導致影像顏色非常相近,因此人眼難以辨別其細節。

此時可以採用"Histogram equalization",將其資訊等比例放大後影像則可更清晰可視。

 

直方圖等化使用機率分佈, 將原先的亮度分佈重新均勻的等化到新的亮度值.。

其數學式如下所示 :

 

 

 

較為常見之效果如下圖所示,

原本R,G,B之顏色較為集中於某個區間,經過"Histogram equalization"後,其資訊被平均分配使得該影像經由"Histogram equalization"後影像更為清晰。

 

image

 


 

C#
 

private static Bitmap histogramEqualization(Bitmap bitmap)
{
    //統計
    int[,] statistics = new int[3,COLOR_SIZE_RANGE];
    int w = bitmap.Width;
    int h = bitmap.Height;
    int total = w * h;

    HistogramEqualizationStatistics(bitmap, ref statistics); //統計

    //運算
    Console.WriteLine(statistics[0, 72]);
    for (int i = 0; i < COLOR_SIZE_RANGE; i++)
    {
        int rCount = 0, gCount = 0, bCount = 0;

        rCount = (int)(statistics[ImageExtract.COLOR_R, i] + ((i == 0) ? 0 : statistics[ImageExtract.COLOR_R, i - 1]));
        gCount = (int)(statistics[ImageExtract.COLOR_G, i] + ((i == 0) ? 0 : statistics[ImageExtract.COLOR_G, i - 1]));
        bCount = (int)(statistics[ImageExtract.COLOR_B, i] + ((i == 0) ? 0 : statistics[ImageExtract.COLOR_B, i - 1]));

        statistics[ImageExtract.COLOR_R, i] = rCount;
        statistics[ImageExtract.COLOR_G, i] = gCount;
        statistics[ImageExtract.COLOR_B, i] = bCount;
    }

    //填數
    Bitmap resBitmap = HistogramEqualizationFillIn(bitmap, total, statistics);

    return resBitmap;
}

 

HistogramEqualizationFillIn 負責將影像進行直方圖等化之運算。

private static Bitmap HistogramEqualizationFillIn(Bitmap bitmap, int total, int[,] statistics)
{
	int width = bitmap.Width;
	int height = bitmap.Height;
	int R = 0, G = 1, B = 2;

	System.IntPtr srcScan, dstScan;
	BitmapData srcBmData, dstBmData;
	Bitmap dstBitmap = ImageExtract.InitPonitMethod(bitmap, width, height, out srcScan, out dstScan, out srcBmData, out dstBmData);

	unsafe //啟動不安全代碼
	{
		byte* srcP = (byte*)srcScan;
		byte* dstP = (byte*)dstScan;
		int srcOffset = srcBmData.Stride - width * 3;
		int dstOffset = dstBmData.Stride - width * 3;

		for (int y = 0; y < height; y++)
		{
			for (int x = 0; x < width; x++, srcP += 3, dstP += 3)
			{
				dstP[2] = (byte)(((double)statistics[R, srcP[2]] / total) * (COLOR_SIZE_RANGE - 1));
				dstP[1] = (byte)(((double)statistics[G, srcP[1]] / total) * (COLOR_SIZE_RANGE - 1));
				dstP[0] = (byte)(((double)statistics[B, srcP[0]] / total) * (COLOR_SIZE_RANGE - 1));
			}
			srcP += srcOffset;
			dstP += dstOffset;
		}
	}

	bitmap.UnlockBits(srcBmData);
	dstBitmap.UnlockBits(dstBmData);

	return dstBitmap;
}

 

完整程式碼(連結)

 

arrow
arrow
    文章標籤
    Image Process Point processing
    全站熱搜

    Lung-Yu,Tsai 發表在 痞客邦 留言(0) 人氣()