灰度拉伸属于线性点运算的一种。灰度拉伸。也称对比度拉伸,是一种简单的线性点运算。它扩展图像的直方图,使其充满整个灰度级范围内。
设f(x,y)为输入图像,它的最小灰度级A和最大灰度级B的定义,如下:
A = min[f(x,y)] B = max[f(x,y)]
将A和B分别线性映射到0和255,最终得到的图像g(x,y)为:
以下为源代码(C#实现)
- /// <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;
- }