using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
namespace UPImage
{
public class Projections
{
public static int[] GetHorizonProjection(Bitmap orginal)
{
Bitmap bmp;
if (ImageProcessing.IsGrayscale(orginal) == false)
{
bmp = ImageProcessing.ColorToIndexedGrayscale(orginal);
}
else
{
bmp = (Bitmap)orginal.Clone();
}
int[] horizonProjection = new int[bmp.Width];
// init horizonProjection valutes
for (int i = 0; i < bmp.Width; i++)
{
horizonProjection[i] = 0;
}
//
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData =
bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly,
bmp.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
byte[] rgbValues = new byte[bytes];
// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
for (int h = 0; h < bmp.Height; h++)
{
for (int w = 0; w < bmp.Width; w++)
{
byte color = rgbValues[h * bmpData.Stride + w];
horizonProjection[w] += color<128 ? 1:0;
}
}
bmp.UnlockBits(bmpData);
bmp.Dispose();
rgbValues = null;
return horizonProjection;
}
public static int[] GetVerticalProjection(Bitmap orginal)
{
Bitmap bmp;
if (ImageProcessing.IsGrayscale(orginal) == false)
{
bmp = ImageProcessing.ColorToIndexedGrayscale(orginal);
}
else
{
bmp = (Bitmap)orginal.Clone();
}
int[] verticalProjection = new int[bmp.Height];
// init verticalProjection valutes
for (int i = 0; i < bmp.Height; i++)
{
verticalProjection[i] = 0;
}
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData =
bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly,
bmp.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
byte[] rgbValues = new byte[bytes];
// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
for (int h = 0; h < bmp.Height; h++)
{
for (int w = 0; w < bmp.Width; w++)
{
byte color = rgbValues[h * bmpData.Stride + w];
verticalProjection[h] += color < 128 ? 1 : 0;
}
}
bmp.UnlockBits(bmpData);
bmp.Dispose();
rgbValues = null;
return verticalProjection;
}
public static Bitmap DrawHorizonHistogram(Bitmap orginal)
{
Bitmap bmp;
if (ImageProcessing.IsGrayscale(orginal) == false)
{
bmp = ImageProcessing.ColorToIndexedGrayscale(orginal);
}
else
{
bmp = (Bitmap)orginal.Clone();
}
int[] horizonProjection = GetHorizonProjection(bmp);
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData =
bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmp.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
byte[] rgbValues = new byte[bytes];
// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
//fill white color
for (int h = 0; h < bmp.Height; h++)
{
for (int w = 0; w < bmp.Width; w++)
{
byte color = rgbValues[h * bmpData.Stride + w];
if (color != 255)
{
rgbValues[h * bmpData.Stride + w] = 255;
}
}
}
//Draw Horizon Histogram
int height=bmp.Height;
for (int w = 0; w < bmp.Width; w++)
{
for (int i = 0; i < horizonProjection[w]; i++)
{
rgbValues[(height - i - 1) * bmpData.Stride + w] = 0;
}
}
// Copy the RGB values back to the bitmap
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
bmp.UnlockBits(bmpData);
return bmp;
}
public static Bitmap DrawVerticalHistogram(Bitmap orginal)
{
Bitmap bmp;
if (ImageProcessing.IsGrayscale(orginal) == false)
{
bmp = ImageProcessing.ColorToIndexedGrayscale(orginal);
}
else
{
bmp = (Bitmap)orginal.Clone();
}
int[] verticalProjection = GetVerticalProjection(bmp);
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData =
bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
bmp.PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;
// Declare an array to hold the bytes of the bitmap.
int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
byte[] rgbValues = new byte[bytes];
// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
//fill white color
for (int h = 0; h < bmp.Height; h++)
{
for (int w = 0; w < bmp.Width; w++)
{
byte color = rgbValues[h * bmpData.Stride + w];
if (color != 255)
{
rgbValues[h * bmpData.Stride + w] = 255;
}
}
}
//Draw Vertical Histogram
int width = bmp.Width;
for (int h = 0; h < bmp.Height; h++)
{
for (int i = 0; i < verticalProjection[h]; i++)
{
rgbValues[h* bmpData.Stride + i] = 0;
}
}
// Copy the RGB values back to the bitmap
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
bmp.UnlockBits(bmpData);
return bmp;
}
public static double GetMinimumThickofHorizonHistogram(Bitmap orginal,int lengh)
{
double result=-1.0;
int[] horizonProjection = GetHorizonProjection(orginal);
int count=horizonProjection.Count();
if (count > lengh)
{
for (int i = 0; i < count - lengh; i++)
{
double avarage = 0.0;
int index = 0;
for (int j = 0; j < lengh; j++)
{
if (horizonProjection[i + j] > 0)
{
avarage += horizonProjection[i + j];
index++;
}
}
if (avarage > 0)
{
avarage /= index;
if (result == -1)
{
result = avarage;
}
else
{
if (result > avarage)
{
result = avarage;
}
}
}
}
}
return result;
}
}
}