基于c#图像灰度化、灰度反转、二值化的实现方法详解
程序员文章站
2023-12-18 11:15:52
图像灰度化:将彩色图像转化成为灰度图像的过程成为图像的灰度化处理。彩色图像中的每个像素的颜色有r、g、b三个分量决定,而每个分量有255中值可取,这样一个像素点可以有160...
图像灰度化:
将彩色图像转化成为灰度图像的过程成为图像的灰度化处理。彩色图像中的每个像素的颜色有r、g、b三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围。而灰度图像是r、g、b三个分量相同的一种特殊的彩色图像,其一个像素点的变化范围为255种,所以在数字图像处理种一般先将各种格式的图像转变成灰度图像以使后续的图像的计算量变得少一些。灰度图像的描述与彩色图像一样仍然反映了整幅图像的整体和局部的色度和亮度等级的分布和特征。图像的灰度化处理可用两种方法来实现。
第一种方法使求出每个像素点的r、g、b三个分量的平均值,然后将这个平均值赋予给这个像素的三个分量。
第二种方法是根据yuv的颜色空间中,y的分量的物理意义是点的亮度,由该值反映亮度等级,根据rgb和yuv颜色空间的变化关系可建立亮度y与r、g、b三个颜色分量的对应:y=0.3r+0.59g+0.11b,以这个亮度值表达图像的灰度值。
/// <summary>
/// 图像灰度化
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
public static bitmap togray(bitmap bmp)
{
for (int i = 0; i < bmp.width; i++)
{
for (int j = 0; j < bmp.height; j++)
{
//获取该点的像素的rgb的颜色
color color = bmp.getpixel(i, j);
//利用公式计算灰度值
int gray = (int)(color.r * 0.3 + color.g * 0.59 + color.b * 0.11);
color newcolor = color.fromargb(gray, gray, gray);
bmp.setpixel(i, j, newcolor);
}
}
return bmp;
}
灰度反转:
把每个像素点的r、g、b三个分量的值0的设为255,255的设为0。
/// <summary>
/// 图像灰度反转
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
public static bitmap grayreverse(bitmap bmp)
{
for (int i = 0; i < bmp.width; i++)
{
for (int j = 0; j < bmp.height; j++)
{
//获取该点的像素的rgb的颜色
color color = bmp.getpixel(i, j);
color newcolor = color.fromargb(255 - color.r, 255 - color.g, 255 - color.b);
bmp.setpixel(i, j, newcolor);
}
}
return bmp;
}
灰度图像二值化:
在进行了灰度化处理之后,图像中的每个象素只有一个值,那就是象素的灰度值。它的大小决定了象素的亮暗程度。为了更加便利的开展下面的图像处理操作,还需要对已经得到的灰度图像做一个二值化处理。图像的二值化就是把图像中的象素根据一定的标准分化成两种颜色。在系统中是根据象素的灰度值处理成黑白两种颜色。和灰度化相似的,图像的二值化也有很多成熟的算法。它可以采用自适应阀值法,也可以采用给定阀值法。
/// <summary>
/// 图像二值化1:取图片的平均灰度作为阈值,低于该值的全都为0,高于该值的全都为255
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
public static bitmap convertto1bpp1(bitmap bmp)
{
int average = 0;
for (int i = 0; i < bmp.width; i++)
{
for (int j = 0; j < bmp.height; j++)
{
color color = bmp.getpixel(i, j);
average += color.b;
}
}
average = (int)average / (bmp.width * bmp.height);
for (int i = 0; i < bmp.width; i++)
{
for (int j = 0; j < bmp.height; j++)
{
//获取该点的像素的rgb的颜色
color color = bmp.getpixel(i, j);
int value = 255 - color.b;
color newcolor = value > average ? color.fromargb(0, 0, 0): color.fromargb(255,
255, 255);
bmp.setpixel(i, j, newcolor);
}
}
return bmp;
}
/// <summary>
/// 图像二值化2
/// </summary>
/// <param name="img"></param>
/// <returns></returns>
public static bitmap convertto1bpp2(bitmap img)
{
int w = img.width;
int h = img.height;
bitmap bmp = new bitmap(w, h, pixelformat.format1bppindexed);
bitmapdata data = bmp.lockbits(new rectangle(0, 0, w, h), imagelockmode.readwrite,
pixelformat.format1bppindexed);
for (int y = 0; y < h; y++)
{
byte[] scan = new byte[(w + 7) / 8];
for (int x = 0; x < w; x++)
{
color c = img.getpixel(x, y);
if (c.getbrightness() >= 0.5) scan[x / 8] |= (byte)(0x80 >> (x % 8));
}
marshal.copy(scan, 0, (intptr)((int)data.scan0 + data.stride * y), scan.length);
}
return bmp;
}
将彩色图像转化成为灰度图像的过程成为图像的灰度化处理。彩色图像中的每个像素的颜色有r、g、b三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围。而灰度图像是r、g、b三个分量相同的一种特殊的彩色图像,其一个像素点的变化范围为255种,所以在数字图像处理种一般先将各种格式的图像转变成灰度图像以使后续的图像的计算量变得少一些。灰度图像的描述与彩色图像一样仍然反映了整幅图像的整体和局部的色度和亮度等级的分布和特征。图像的灰度化处理可用两种方法来实现。
第一种方法使求出每个像素点的r、g、b三个分量的平均值,然后将这个平均值赋予给这个像素的三个分量。
第二种方法是根据yuv的颜色空间中,y的分量的物理意义是点的亮度,由该值反映亮度等级,根据rgb和yuv颜色空间的变化关系可建立亮度y与r、g、b三个颜色分量的对应:y=0.3r+0.59g+0.11b,以这个亮度值表达图像的灰度值。
复制代码 代码如下:
/// <summary>
/// 图像灰度化
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
public static bitmap togray(bitmap bmp)
{
for (int i = 0; i < bmp.width; i++)
{
for (int j = 0; j < bmp.height; j++)
{
//获取该点的像素的rgb的颜色
color color = bmp.getpixel(i, j);
//利用公式计算灰度值
int gray = (int)(color.r * 0.3 + color.g * 0.59 + color.b * 0.11);
color newcolor = color.fromargb(gray, gray, gray);
bmp.setpixel(i, j, newcolor);
}
}
return bmp;
}
灰度反转:
把每个像素点的r、g、b三个分量的值0的设为255,255的设为0。
复制代码 代码如下:
/// <summary>
/// 图像灰度反转
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
public static bitmap grayreverse(bitmap bmp)
{
for (int i = 0; i < bmp.width; i++)
{
for (int j = 0; j < bmp.height; j++)
{
//获取该点的像素的rgb的颜色
color color = bmp.getpixel(i, j);
color newcolor = color.fromargb(255 - color.r, 255 - color.g, 255 - color.b);
bmp.setpixel(i, j, newcolor);
}
}
return bmp;
}
灰度图像二值化:
在进行了灰度化处理之后,图像中的每个象素只有一个值,那就是象素的灰度值。它的大小决定了象素的亮暗程度。为了更加便利的开展下面的图像处理操作,还需要对已经得到的灰度图像做一个二值化处理。图像的二值化就是把图像中的象素根据一定的标准分化成两种颜色。在系统中是根据象素的灰度值处理成黑白两种颜色。和灰度化相似的,图像的二值化也有很多成熟的算法。它可以采用自适应阀值法,也可以采用给定阀值法。
复制代码 代码如下:
/// <summary>
/// 图像二值化1:取图片的平均灰度作为阈值,低于该值的全都为0,高于该值的全都为255
/// </summary>
/// <param name="bmp"></param>
/// <returns></returns>
public static bitmap convertto1bpp1(bitmap bmp)
{
int average = 0;
for (int i = 0; i < bmp.width; i++)
{
for (int j = 0; j < bmp.height; j++)
{
color color = bmp.getpixel(i, j);
average += color.b;
}
}
average = (int)average / (bmp.width * bmp.height);
for (int i = 0; i < bmp.width; i++)
{
for (int j = 0; j < bmp.height; j++)
{
//获取该点的像素的rgb的颜色
color color = bmp.getpixel(i, j);
int value = 255 - color.b;
color newcolor = value > average ? color.fromargb(0, 0, 0): color.fromargb(255,
255, 255);
bmp.setpixel(i, j, newcolor);
}
}
return bmp;
}
/// <summary>
/// 图像二值化2
/// </summary>
/// <param name="img"></param>
/// <returns></returns>
public static bitmap convertto1bpp2(bitmap img)
{
int w = img.width;
int h = img.height;
bitmap bmp = new bitmap(w, h, pixelformat.format1bppindexed);
bitmapdata data = bmp.lockbits(new rectangle(0, 0, w, h), imagelockmode.readwrite,
pixelformat.format1bppindexed);
for (int y = 0; y < h; y++)
{
byte[] scan = new byte[(w + 7) / 8];
for (int x = 0; x < w; x++)
{
color c = img.getpixel(x, y);
if (c.getbrightness() >= 0.5) scan[x / 8] |= (byte)(0x80 >> (x % 8));
}
marshal.copy(scan, 0, (intptr)((int)data.scan0 + data.stride * y), scan.length);
}
return bmp;
}