灰度拉伸也屬於線性點運算的一種,也可以通過上一節的程序得到。但由於它在點運算的特殊性,所以把它單獨列出來進行介紹。
灰度拉伸定義
如果一幅圖像的灰度值分布在全等級灰度范圍內,即在0~255之間,那么它更容易被區別確認出來。
灰度拉伸,也稱對比度拉伸,是一種簡單的線性點運算。它擴展圖像的直方圖,使其充滿整個灰度等級范圍內。
設f(x,y)為輸入圖像,它的最小灰度級A和最大灰度級B的定義為:
A=min[f(x,y) B=max[f(x,y)]
我們的目標是按照公式 g(x, y)=pf(x,y)+L , 把A和B分別線性映射到0和255,因此,最終的圖像g(x,y)為:
private void stretch_Click(object sender, EventArgs e) { Stretch(curBitmpap, out curBitmpap); Invalidate(); } /// <summary> /// 全等級灰度拉伸 (圖像增強) /// </summary> /// <param name="srcBmp">原圖像</param> /// <param name="dstBmp">處理后圖像</param> /// <returns>處理成功 true 失敗 false</returns> public static bool Stretch(Bitmap srcBmp, out Bitmap dstBmp) { if (srcBmp == null) { dstBmp = null; return false; } double pR = 0.0;//斜率 double pG = 0.0;//斜率 double pB = 0.0;//斜率 byte minGrayDegree = 255; byte maxGrayDegree = 0; byte minGrayDegreeR = 255; byte maxGrayDegreeR = 0; byte minGrayDegreeG = 255; byte maxGrayDegreeG = 0; byte minGrayDegreeB = 255; byte maxGrayDegreeB = 0; dstBmp = new Bitmap(srcBmp); Rectangle rt = new Rectangle(0, 0, dstBmp.Width, dstBmp.Height); BitmapData bmpData = dstBmp.LockBits(rt, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); unsafe { for (int i = 0; i < bmpData.Height; i++) { byte* ptr = (byte*)bmpData.Scan0 + i * bmpData.Stride; for (int j = 0; j < bmpData.Width; j++) { if (minGrayDegreeR > *(ptr + j * 3 + 2)) minGrayDegreeR = *(ptr + j * 3 + 2); if (maxGrayDegreeR < *(ptr + j * 3 + 2)) maxGrayDegreeR = *(ptr + j * 3 + 2); if (minGrayDegreeG > *(ptr + j * 3 + 1)) minGrayDegreeG = *(ptr + j * 3 + 1); if (maxGrayDegreeG < *(ptr + j * 3 + 1)) maxGrayDegreeG = *(ptr + j * 3 + 1); if (minGrayDegreeB > *(ptr + j * 3)) minGrayDegreeB = *(ptr + j * 3); if (maxGrayDegreeB < *(ptr + j * 3)) maxGrayDegreeB = *(ptr + j * 3); } } pR = 255.0 / (maxGrayDegreeR - minGrayDegreeR); pG = 255.0 / (maxGrayDegreeG - minGrayDegreeG); pB = 255.0 / (maxGrayDegreeB - minGrayDegreeB); for (int i = 0; i < bmpData.Height; i++) { byte* ptr1 = (byte*)bmpData.Scan0 + i * bmpData.Stride; for (int j = 0; j < bmpData.Width; j++) { *(ptr1 + j * 3) = (byte)((*(ptr1 + j * 3) - minGrayDegreeB) * pB + 0.5); *(ptr1 + j * 3 + 1) = (byte)((*(ptr1 + j * 3 + 1) - minGrayDegreeG) * pG + 0.5); *(ptr1 + j * 3 + 2) = (byte)((*(ptr1 + j * 3 + 2) - minGrayDegreeR) * pR + 0.5); } } } dstBmp.UnlockBits(bmpData); return true; }
增強后: