📄 grayscale.cs
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
namespace latihan1
{
class grayscale
{
byte threshold;
private Bitmap bmpimg;
public void setImage(Bitmap bmp)
{
bmpimg = (Bitmap)bmp.Clone();
}
public Bitmap getImage()
{
return (Bitmap)bmpimg.Clone();
}
public byte[,] componentMask(byte sE)
{
byte[,] mask = new byte[3, 3];
if (sE == 8)
{
mask[0, 0] = 1;
mask[0, 1] = 1;
mask[0, 2] = 1;
mask[1, 0] = 1;
mask[1, 1] = 1;
mask[1, 2] = 1;
mask[2, 0] = 1;
mask[2, 1] = 1;
mask[2, 2] = 1;
}
else if (sE == 4)
{
mask[0, 0] = 0;
mask[0, 1] = 1;
mask[0, 2] = 0;
mask[1, 0] = 1;
mask[1, 1] = 1;
mask[1, 2] = 1;
mask[2, 0] = 0;
mask[2, 1] = 1;
mask[2, 2] = 0;
}
return mask;
}
public Bitmap invert()
{
BitmapData data = bmpimg.LockBits(new Rectangle(0, 0, bmpimg.Width, bmpimg.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
unsafe
{
byte* ptr = (byte*)data.Scan0;
int remain = data.Stride - data.Width * 3;
for (int i = 0; i < data.Height; i++)
{
for (int j = 0; j < data.Width * 3; j++)
{
ptr[0] = (byte)(255 - ptr[0]);
ptr++;
}
ptr += remain;
}
}
bmpimg.UnlockBits(data);
return bmpimg;
}
public Bitmap imgGreyscale(Bitmap image)
{
Bitmap returnMap = new Bitmap(image.Width, image.Height,
PixelFormat.Format24bppRgb);
BitmapData bitmapData1 = image.LockBits(new Rectangle(0, 0,
image.Width, image.Height),
ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb);
BitmapData bitmapData2 = returnMap.LockBits(new Rectangle(0, 0,
returnMap.Width, returnMap.Height),
ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb);
int a = 0;
unsafe
{
byte* imagePointer1 = (byte*)bitmapData1.Scan0;
byte* imagePointer2 = (byte*)bitmapData2.Scan0;
for (int i = 0; i < bitmapData1.Height; i++)
{
for (int j = 0; j < bitmapData1.Width; j++)
{
// write the logic implementation here
a = (imagePointer1[0] + imagePointer1[1] +
imagePointer1[2]) / 3;
imagePointer2[0] = (byte)a;
imagePointer2[1] = (byte)a;
imagePointer2[2] = (byte)a;
//imagePointer2[3] = imagePointer1[3];
//4 bytes per pixel
imagePointer1 += 3;
imagePointer2 += 3;
}//end for j
//4 bytes per pixel
imagePointer1 += bitmapData1.Stride -
(bitmapData1.Width * 3);
imagePointer2 += bitmapData1.Stride -
(bitmapData1.Width * 3);
}//end for i
}//end unsafe
returnMap.UnlockBits(bitmapData2);
image.UnlockBits(bitmapData1);
return returnMap;
}//end processImage
public Bitmap imgBinary(Bitmap image)
{
byte ambang = otsuMethod(image) ;
Bitmap returnMap = new Bitmap(image.Width, image.Height,
PixelFormat.Format24bppRgb);
BitmapData bitmapData1 = image.LockBits(new Rectangle(0, 0,
image.Width, image.Height),
ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb);
BitmapData bitmapData2 = returnMap.LockBits(new Rectangle(0, 0,
returnMap.Width, returnMap.Height),
ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb);
int a = 0;
unsafe
{
byte* imagePointer1 = (byte*)bitmapData1.Scan0;
byte* imagePointer2 = (byte*)bitmapData2.Scan0;
for (int i = 0; i < bitmapData1.Height; i++)
{
for (int j = 0; j < bitmapData1.Width; j++)
{
// write the logic implementation here
if (Convert.ToByte(imagePointer1[0]) > ambang + 150)
{
a = 255;
}
else
{
a = 0;
}
imagePointer2[0] = (byte)a;
imagePointer2[1] = (byte)a;
imagePointer2[2] = (byte)a;
//imagePointer2[3] = imagePointer1[3];
//4 bytes per pixel
imagePointer1 += 3;
imagePointer2 += 3;
}//end for j
//4 bytes per pixel
imagePointer1 += bitmapData1.Stride -
(bitmapData1.Width * 3);
imagePointer2 += bitmapData1.Stride -
(bitmapData1.Width * 3);
}//end for i
}//end unsafe
returnMap.UnlockBits(bitmapData2);
image.UnlockBits(bitmapData1);
return returnMap;
}//end processImage
public byte otsuMethod(Bitmap image)
{
const int level = 256;
Double totalMean, variance, Maxvariance, zerothCumuMoment, firstCumuMoment;
int [] histogram = new int[256];
BitmapData data = image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
unsafe
{
byte* ptr = (byte*) data.Scan0;
int remain = data.Stride - data.Width*3;
for (int i = 0; i < histogram.Length; i++)
{
histogram [i] = 0;
}
for (int i = 0; i < data.Height; i++)
{
for (int j = 0; j < data.Width; j++)
{
int mean = ptr [0] + ptr [1] + ptr [2];
mean /= 3;
histogram[mean] ++;
ptr += 3;
}
ptr += remain;
}
image.UnlockBits(data);
}
// methode otsu
totalMean = 0;
Maxvariance = 0;
firstCumuMoment = 0;
zerothCumuMoment = 0;
long area = image.Height * image.Width;
for (int k = 0; k < level; k++)
{
totalMean += k * (double)histogram[k] / area;
}
for (int k = 0; k < level; k++)
{
zerothCumuMoment += (double)histogram[k] / area;
firstCumuMoment += k * (double)histogram[k] / area;
variance = (totalMean * zerothCumuMoment - firstCumuMoment);
//mencegah pembagian dengan nol
if (zerothCumuMoment != 0 && zerothCumuMoment != 1)
{
variance /= zerothCumuMoment * (1 - zerothCumuMoment);
if (Maxvariance < variance)
{
Maxvariance = variance;
threshold = (byte)k;
}
}
}
return threshold;
}
public void dilatasiMorphologi(byte tipeKernel)
{
Bitmap returnMap = (Bitmap)this.bmpimg.Clone();
//Bitmap returnMap = new Bitmap(image.Width, image.Height,
// PixelFormat.Format24bppRgb);
BitmapData bitmapData1 = bmpimg.LockBits(new Rectangle(0, 0,
bmpimg.Width, bmpimg.Height),
ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);
BitmapData bitmapData2 = returnMap.LockBits(new Rectangle(0, 0,
returnMap.Width, returnMap.Height),
ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);
byte[,] sElement = componentMask(tipeKernel);
unsafe
{
byte* imagePointer1 = (byte*)bitmapData1.Scan0;
byte* imagePointer2 = (byte*)bitmapData2.Scan0;
imagePointer1 += bitmapData1.Stride + 3;
imagePointer2 += bitmapData1.Stride + 3;
int remain = bitmapData1.Stride - (bitmapData1.Width * 3);
for (int i = 1; i < bitmapData1.Height-1; i++)
{
for (int j = 1; j < bitmapData1.Width-1; j++)
{
if (imagePointer1[0] == 255)
{
byte* temp = imagePointer2 - bitmapData1.Stride - 3;
for (int x = 0; x < 3; x++)
{
for (int y = 0; y < 3; y++)
{
temp[bitmapData1.Stride * x + y * 3] = temp[bitmapData1.Stride * x + y * 3 + 1] =
temp[bitmapData1.Stride * x + y * 3 + 2] = (byte)(sElement[x, y] * 255);
}
}
}
imagePointer1 += 3;
imagePointer2 += 3;
}
imagePointer1 += remain + 6;
imagePointer2 += remain + 6;
}
}
returnMap.UnlockBits(bitmapData2);
bmpimg.UnlockBits(bitmapData1);
bmpimg = (Bitmap)returnMap.Clone();
//return returnMap;
}
public void erosiMorphologi(byte tipeKernel)
{
Bitmap returnMap = (Bitmap)this.bmpimg.Clone();
//Bitmap returnMap = new Bitmap(image.Width, image.Height,
// PixelFormat.Format24bppRgb);
BitmapData bitmapData1 = bmpimg.LockBits(new Rectangle(0, 0,
bmpimg.Width, bmpimg.Height),
ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);
BitmapData bitmapData2 = returnMap.LockBits(new Rectangle(0, 0,
returnMap.Width, returnMap.Height),
ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);
byte[,] sElement = componentMask(tipeKernel);
unsafe
{
byte* imagePointer1 = (byte*)bitmapData1.Scan0;
byte* imagePointer2 = (byte*)bitmapData2.Scan0;
imagePointer1 += bitmapData1.Stride + 3;
imagePointer2 += bitmapData1.Stride + 3;
int remain = bitmapData1.Stride - bitmapData1.Width * 3;
for (int i = 1; i < bitmapData1.Height - 1; i++)
{
for (int j = 1; j < bitmapData1.Width - 1; j++)
{
if (imagePointer1[0] != 255)
{
byte* temp = imagePointer1 - bitmapData1.Stride - 3;
bool condition = false;
for (int x = 0; x < 3; x++)
{
for (int y = 0; y < 3; y++)
{
if( sElement[x , y] == 1 && temp[0] == 255 )
{
condition = true;
}
temp += 3;
}
temp += bitmapData1.Stride - 9;
}
if( condition )
{
imagePointer2[0] = imagePointer2[1] = imagePointer2[2] = 255;
}
}
imagePointer1 += 3;
imagePointer2 += 3;
}
imagePointer1 += remain + 6;
imagePointer2 += remain + 6;
}
}
returnMap.UnlockBits(bitmapData2);
bmpimg.UnlockBits(bitmapData1);
bmpimg = (Bitmap)returnMap.Clone();
//return returnMap;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -