using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace ImageProcessing { public partial class FormImageProcessing : Form { // string ImageFile = @"1.png"; string ImageFile = @"strip.png"; Bitmap Bmp; float[] Original; float[] Normalized; float[] HorizontalThresholdF; float[] LocalMeanF; float[] Diff; float[] MaskedInfo; float[] MaskedInfoWithMedian; ColorHSL[] OriginalHSL; ColorRGB[] OriginalRGB; public FormImageProcessing() { InitializeComponent(); } private void ComputeRGBFilter(string p) { Bmp = (Bitmap)Bitmap.FromFile(p); OriginalRGB = BitmapFilter.ColorRGBBitmap(Bmp); float[] threasholdImg = new float[OriginalRGB.Length]; // chroma histogram 10 steps // find the 2 max //if the 2 max> 1 the threashold = min (2 max) + (max2 - max1)/2 //Horizontal line for (int y = 0; y < Bmp.Height; y++) { int lenght = Bmp.Width; for (int x = 0; x < lenght; x++) { ColorRGB pix = OriginalRGB[x + y * Bmp.Width]; threasholdImg[x + y * Bmp.Width] = 0.50f; //no relevant histogram if ((pix.R > 125) && (pix.G < 125) && (pix.B < 125)) threasholdImg[x + y * Bmp.Width] = 0.00f; //no relevant histogram if ((pix.R < 125) && (pix.G > 125) && (pix.B < 125)) threasholdImg[x + y * Bmp.Width] = 1.00f; //no relevant histogram } } // pictureBox1.Image = BitmapFilter.GenerateBitmapFromHSL(OriginalHSL, Bmp.Width, Bmp.Height); pictureBox1.Image = BitmapFilter.GenerateBitmap(threasholdImg, Bmp.Width, Bmp.Height); } private void ComputeColorFilter(string p) { Bmp = (Bitmap)Bitmap.FromFile(p); OriginalHSL = BitmapFilter.ColorLSHBitmap(Bmp); float[] threasholdImg = new float[OriginalHSL.Length]; // chroma histogram 10 steps // find the 2 max //if the 2 max> 1 the threashold = min (2 max) + (max2 - max1)/2 //Horizontal line for (int y = 0; y < Bmp.Height; y++) { //Find min max mean median int steps = 10; int[] chromaHisto = new int[steps + 1]; int lenght = Bmp.Width; for (int x = 0; x < lenght; x++) { ColorHSL pix = OriginalHSL[x + y * Bmp.Width]; int histIndexChroma = (int)(pix.H * steps); chromaHisto[histIndexChroma]++; } //Find the two max int max1 = -1; int chroma1 = -1; int max2 = -1; int chroma2 = -1; //Find max1 for (int i = 0; i < chromaHisto.Length; i++) { if ((chromaHisto[i] > max1) && (chromaHisto[i] != 0)) { max1 = chromaHisto[i]; chroma1 = i; } } //find max2 for (int i = 0; i < chromaHisto.Length; i++) { //circular distance // int dist = Math.Abs(i - chroma1); // if (Math.Min(dist, Math.Abs(dist - steps)) > (steps / 3)) //At least delta chroma > steps / 3 if (CircularDistance(i, chroma1, steps) > (steps / 3)) if ((chromaHisto[i] > max2) && (chromaHisto[i] != 0)) { max2 = chromaHisto[i]; chroma2 = i; } } int peak = chroma1; if ((max1 != -1) && (max2 != -1) && (chromaHisto[chroma2] > chromaHisto[chroma1])) peak = chroma2; double delta = 3; Console.WriteLine(chroma1 + " " + chroma2); //binaries for (int x = 0; x < Bmp.Width; x++) { if ((max1 != -1) && (max2 != -1)) //found a max1 and max 2 ? { ColorHSL pix = OriginalHSL[x + y * Bmp.Width]; int histIndexChroma = (int)(pix.H * steps); if (CircularDistance(histIndexChroma, peak, steps) < delta) threasholdImg[x + y * Bmp.Width] = 1; //Black else threasholdImg[x + y * Bmp.Width] = 0; //White } else threasholdImg[x + y * Bmp.Width] = 0.50f; //no relevant histogram } } // pictureBox1.Image = BitmapFilter.GenerateBitmapFromHSL(OriginalHSL, Bmp.Width, Bmp.Height); pictureBox1.Image = BitmapFilter.GenerateBitmap(threasholdImg, Bmp.Width, Bmp.Height); } int CircularDistance(int index1, int index2, int steps) { //circular distance int dist = Math.Abs(index1 - index2); return Math.Min(dist, Math.Abs(dist - steps)); } private void ComputeFilter(string p) { Bmp = (Bitmap)Bitmap.FromFile(p); Original = BitmapFilter.GrayScaleFloat(Bmp); float min = 0, max = 0, mean = 0; Normalized = BitmapFilter.Normalize(Original, out min, out max, out mean); Diff = new float[Original.Length]; float[] imput = Original; //Horizontal line normalization for (int y = 0; y < Bmp.Height; y++) { //Find min max mean median float minL = float.MaxValue, maxL = 0, meanL = 0, median = 0; List line = new List(); int lenght = Bmp.Width; for (int x = 0; x < lenght; x++) { float pix = imput[x + y * Bmp.Width]; if (pix < minL) minL = pix; if (pix > maxL) maxL = pix; line.Add(pix); meanL += pix; } line.Sort(); median = line[line.Count / 2]; meanL /= (float)lenght; //Scale and binaries for (int x = 0; x < Bmp.Width; x++) { float pix = imput[x + y * Bmp.Width]; Diff[x + y * Bmp.Width] = Original[x + y * Bmp.Width] - minL + meanL; if (Diff[x + y * Bmp.Width] > 1) Diff[x + y * Bmp.Width] = 1; if (Diff[x + y * Bmp.Width] < 0) Diff[x + y * Bmp.Width] = 0; } } //Vertical line normalization imput = Diff; for (int x = 0; x < Bmp.Width; x++) { //Find min max mean median float minL = float.MaxValue, maxL = 0, meanL = 0, median = 0; List line = new List(); int lenght = Bmp.Height; for (int y = 0; y < lenght; y++) { float pix = imput[x + y * Bmp.Width]; if (pix < minL) minL = pix; if (pix > maxL) maxL = pix; line.Add(pix); meanL += pix; } line.Sort(); median = line[line.Count / 2]; meanL /= (float)lenght; //Scale and binaries for (int y = 0; y < lenght; y++) { float pix = imput[x + y * Bmp.Width]; Diff[x + y * Bmp.Width] = Diff[x + y * Bmp.Width] - minL + meanL; if (Diff[x + y * Bmp.Width] > 1) Diff[x + y * Bmp.Width] = 1; if (Diff[x + y * Bmp.Width] < 0) Diff[x + y * Bmp.Width] = 0; } } /* for (int x = 0; x < Bmp.Width; x++) { float minL = float.MaxValue, maxL = 0, meanL = 0, median = 0; List line = new List(); int lenght = Bmp.Height; for (int y = 0; y < Bmp.Height; y++) { float pix = Diff[x + y * Bmp.Width]; if (pix < minL) minL = pix; if (pix > maxL) maxL = pix; line.Add(pix); meanL += pix; } line.Sort(); median = line[line.Count / 2]; meanL /= (float)lenght; //Scale and binaries for (int y = 0; y < lenght; y++) { Diff[x + y * Bmp.Width] = BitmapFilter.GenericScaleF(Diff[x + y * Bmp.Width], minL, 0, maxL, 1); } } */ /* //Compute the mean and min of each horizontal line for (int y = 0; y < Bmp.Height; y++) { float minL = float.MaxValue, meanL = 0; for (int x = 0; x < Bmp.Width; x++) { float pix = Original[x+y*Bmp.Width]; if (pix < minL) minL = pix; meanL += pix; } meanL /= (float)Bmp.Width; for (int x = 0; x < Bmp.Width; x++) { Diff[x + y * Bmp.Width] = Original[x + y * Bmp.Width] - minL + meanL; if (Diff[x + y * Bmp.Width] < 0) Diff[x + y * Bmp.Width] = 0; if (Diff[x + y * Bmp.Width] > 1) Diff[x + y * Bmp.Width] = 1; } } //Compute the mean and min of each horizontal line for (int x = 0; x < Bmp.Width; x++) { float minL = float.MaxValue, meanL = 0, median = 0; List lst = new List(); for (int y = 0; y < Bmp.Height; y++) { float pix = Diff[x + y * Bmp.Width]; if (pix < minL) minL = pix; lst.Add(pix); meanL += pix; } meanL /= (float)Bmp.Height; lst.Sort(); median = lst[lst.Count / 2]; for (int y = 0; y < Bmp.Height; y++) { Diff[x + y * Bmp.Width] = Diff[x + y * Bmp.Width] - minL + meanL; if (Diff[x + y * Bmp.Width] < 0) Diff[x + y * Bmp.Width] = 0; if (Diff[x + y * Bmp.Width] > 1) Diff[x + y * Bmp.Width] = 1; } } Diff = BitmapFilter.Normalize(Diff, out min, out max, out mean); */ // HorizontalThresholdF = BitmapFilter.HorizontalThreshold(Normalized, Bmp.Width, Bmp.Height); // LocalMeanF = BitmapFilter.ComputeLocalMean(Normalized, Bmp.Width, Bmp.Height); /* Diff = new float[Original.Length]; for (int i = 0; i < Original.Length; i++) { Diff[i] = Normalized[i] - LocalMeanF[i]; if (Diff[i] < 0) Diff[i] = 0; else Diff[i] = 1; }*/ //Compute the median Threshold only on the mask (HorizontalThresholdF) /* MaskedInfo = new float[Original.Length]; List lst = new List(); for (int i = 0; i < Original.Length; i++) { if (HorizontalThresholdF[i] == 0) { MaskedInfo[i] = Normalized[i]; lst.Add(Normalized[i]); } else MaskedInfo[i] = 1; } lst.Sort(); float median = lst[lst.Count / 2]; SUperCompute(median); */ } private void SUperCompute(float median) { toolStripStatusLabel1.Text = median.ToString("0.000"); MaskedInfoWithMedian = new float[Original.Length]; for (int i = 0; i < Original.Length; i++) { if (MaskedInfo[i] > median) MaskedInfoWithMedian[i] = 1.0f; else MaskedInfoWithMedian[i] = 0.0f; } } private void Form1_Load(object sender, EventArgs e) { ComputeFilter(ImageFile); pictureBox1.Image = BitmapFilter.GenerateBitmap(Diff, Bmp.Width, Bmp.Height); pictureBox1.Invalidate(); } private void orinigalToolStripMenuItem_Click(object sender, EventArgs e) { pictureBox1.Image = BitmapFilter.GenerateBitmap(Original, Bmp.Width, Bmp.Height); pictureBox1.Invalidate(); } private void normalizedToolStripMenuItem_Click(object sender, EventArgs e) { pictureBox1.Image = BitmapFilter.GenerateBitmap(Normalized, Bmp.Width, Bmp.Height); pictureBox1.Invalidate(); } private void horizontalThresholdToolStripMenuItem_Click(object sender, EventArgs e) { pictureBox1.Image = BitmapFilter.GenerateBitmap(HorizontalThresholdF, Bmp.Width, Bmp.Height); pictureBox1.Invalidate(); } private void localMeanToolStripMenuItem_Click(object sender, EventArgs e) { pictureBox1.Image = BitmapFilter.GenerateBitmap(LocalMeanF, Bmp.Width, Bmp.Height); pictureBox1.Invalidate(); } private void diffToolStripMenuItem_Click(object sender, EventArgs e) { pictureBox1.Image = BitmapFilter.GenerateBitmap(Diff, Bmp.Width, Bmp.Height); pictureBox1.Invalidate(); } private void medianOnMaskToolStripMenuItem_Click(object sender, EventArgs e) { pictureBox1.Image = BitmapFilter.GenerateBitmap(MaskedInfo, Bmp.Width, Bmp.Height); pictureBox1.Invalidate(); } private void openFileToolStripMenuItem_Click(object sender, EventArgs e) { } private void trackBar1_Scroll(object sender, EventArgs e) { float median = (float)trackBar1.Value / (float)trackBar1.Maximum; SUperCompute(median); } private void maskedInfoWithMedianToolStripMenuItem_Click(object sender, EventArgs e) { pictureBox1.Image = BitmapFilter.GenerateBitmap(MaskedInfoWithMedian, Bmp.Width, Bmp.Height); pictureBox1.Invalidate(); } private void lodColorToolStripMenuItem_Click(object sender, EventArgs e) { if (openFileDialog1.ShowDialog() == DialogResult.OK) { //ComputeColorFilter(openFileDialog1.FileName); ComputeRGBFilter(openFileDialog1.FileName); } } } }