public int GetNumBinsWithItems(int count) { int bins = 0; int total = 0; int key = 0; while (total < count) { if (key > 255) { return(-1); } AdvColor color = new AdvColor(Color.FromArgb(255, key, key, key), ColorPlane.eGreen); if (histogram.ContainsKey(color)) { total += histogram[color]; if (total >= count) { return(bins); } bins++; } key++; } return(bins); }
public AdvColor[,] HistogramStretch(AdvColor low, AdvColor high, Histogram histogram, ColorPlane plane) { int height = GetHeight(); int width = GetWidth(); AdvColor[,] new_pixels = new AdvColor[height, width]; int low_color = low.GetColor(plane); int high_color = high.GetColor(plane); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { int val = Convert.ToInt32((pixels[i, j].GetColor(plane) - low_color) * (255.0 / (high_color - low_color))); if (val < 0) { val = 0; } if (val > 255) { val = 255; } new_pixels[i, j] = new AdvColor(val, val, val, plane); } } return(new_pixels); }
public AdvColor[,] ApplyKernel(AdvColor[,] img, double[,] kernel) { int kernel_r = kernel.GetLength(0); int kernel_c = kernel.GetLength(1); int image_r = img.GetLength(0); int image_c = img.GetLength(1); AdvColor[,] new_img = new AdvColor[image_r - (kernel_r) + 1, image_c - (kernel_c) + 1]; for (int i = kernel_r / 2; i < (image_r - kernel_r / 2); i++) { for (int j = kernel_c / 2; j < image_c - kernel_c / 2; j++) { AdvColor[,] neighborhood = GetNeighborhood(img, i, j, kernel_r, kernel_c); double val = 0; for (int ii = 0; ii < kernel_r; ii++) { for (int jj = 0; jj < kernel_c; jj++) { val += neighborhood[ii, jj].GetColor(ColorPlane.eGreen) * kernel[ii, jj]; } } int i_prime = i - (kernel_r / 2); int j_prime = j - (kernel_c / 2); new_img[i_prime, j_prime] = new AdvColor((int)val, (int)val, (int)val, ColorPlane.eGreen); } } return(new_img); }
//new_pixels is the enlarged photo - use for neighborhood, but write to smaller buffer of original size public AdvColor[,] NoiseReductionThreshold(AdvColor[,] new_pixels, int kernel, int threshold) { AdvColor[,] new_image = new AdvColor[pixels.GetLength(0), pixels.GetLength(1)]; int additions = kernel / 2; for (int i = 0 + additions; i < pixels.GetLength(0) + additions; i++) { for (int j = 0 + additions; j < pixels.GetLength(1) + additions; j++) { List <AdvColor> neighborhood = GetNeighborhood(new_pixels, i, j, kernel); int sum = 0; foreach (AdvColor color in neighborhood) { sum += color.GetColor(ColorPlane.eGreen); } sum /= neighborhood.Count; AdvColor original_pixel = new AdvColor(pixels[i - additions, j - additions], ColorPlane.eGreen); if (Math.Abs(original_pixel.GetColor(ColorPlane.eGreen) - sum) > threshold) { original_pixel = new AdvColor(sum, sum, sum, ColorPlane.eGreen); } new_image[i - additions, j - additions] = original_pixel; } } return(new_image); }
public AdvColor(AdvColor color, ColorPlane color_plane) { alpha = color.A; red = color.R; blue = color.B; green = color.G; plane = color_plane; }
public AdvColor[,] GetNeighborhood(AdvColor[,] new_pixels, int i, int j, int kernel_r, int kernel_c) { AdvColor[,] neighborhood = new AdvColor[kernel_r, kernel_c]; for (int rows = -(kernel_r / 2), ii = 0; rows < kernel_r - (kernel_r / 2); rows++, ii++) { for (int columns = -(kernel_c / 2), jj = 0; columns < kernel_c - (kernel_c / 2); columns++, jj++) { neighborhood[ii, jj] = new AdvColor(new_pixels[rows + i, columns + j], ColorPlane.eGreen); } } return(neighborhood); }
public AdvColor[,] HistogramStretch(double low_percentage, double high_percentance, ColorPlane plane) { Histogram histogram = BuildHistogram(); //low bins to 0 out int low_bins = histogram.GetNumBinsWithItems(Convert.ToInt32(GetHeight() * GetWidth() * low_percentage)); AdvColor low_color = histogram.GetBinColor(low_bins); int high_bins = histogram.GetNumBinsWithItems(Convert.ToInt32(GetHeight() * GetWidth() * high_percentance)); AdvColor high_color = histogram.GetBinColor(high_bins); return(HistogramStretch(low_color, high_color, histogram, ColorPlane.eGreen)); }
public int CompareTo(object obj) { if (Object.ReferenceEquals(obj, null)) { return(1); } if (Object.ReferenceEquals(this, obj)) { return(0); } AdvColor color = (AdvColor)obj; int obj_val; int in_val; switch (color.plane) { case ColorPlane.eBlue: obj_val = color.blue; in_val = blue; break; case ColorPlane.eGreen: obj_val = color.green; in_val = green; break; default: obj_val = color.red; in_val = red; break; } if (obj_val > in_val) { return(-1); } if (obj_val == in_val) { return(0); } if (obj_val < in_val) { return(1); } return(0); }
public RGBImage(String image, ColorPlane plane) { //load the pixels directly from the image Bitmap img = new Bitmap(image); pixels = new AdvColor[img.Height, img.Width]; //walk image and load pixels for (int i = 0; i < img.Height; i++) { for (int j = 0; j < img.Width; j++) { AdvColor clr = new AdvColor(img.GetPixel(j, i), plane); pixels[i, j] = clr;// new AdvColor(img.GetPixel(j, i), plane); } } }
//new_pixels is the enlarged photo - use for neighborhood, but write to smaller buffer of original size public AdvColor[,] MedianFilter(AdvColor[,] new_pixels, int kernel) { AdvColor[,] new_image = new AdvColor[pixels.GetLength(0), pixels.GetLength(1)]; int additions = kernel / 2; for (int i = 0 + additions; i < pixels.GetLength(0) + additions; i++) { for (int j = 0 + additions; j < pixels.GetLength(1) + additions; j++) { List <AdvColor> neighborhood = GetNeighborhood(new_pixels, i, j, kernel); neighborhood.Sort(); new_image[i - additions, j - additions] = new AdvColor(neighborhood[neighborhood.Count / 2], ColorPlane.eAll); } } return(new_image); }
public Histogram(AdvColor[,] pixels, ColorPlane plane) { histogram = new SortedDictionary <AdvColor, int>(); for (int i = 0; i < pixels.GetLength(0); i++) { for (int j = 0; j < pixels.GetLength(1); j++) { AdvColor val = new AdvColor(pixels[i, j], plane); if (histogram.ContainsKey(val)) { histogram[val] = histogram[val] + 1; } else { histogram[val] = 1; } } } }
public void CalcSobel(String mag_image, String dir_image) { double[,] kernel1 = new double[, ] { { -1, -2, -1 }, { 0, 0, 0 }, { 1, 2, 1 } }; double[,] kernel2 = new double[, ] { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } }; AdvColor[,] img = MirrorByKernel(3, 3, pixels); AdvColor[,] img1 = ApplyKernel(img, kernel1); AdvColor[,] img2 = ApplyKernel(img, kernel2); AdvColor[,] mag_img = new AdvColor[img1.GetLength(0), img1.GetLength(1)]; AdvColor[,] dir_img = new AdvColor[img2.GetLength(0), img2.GetLength(1)]; for (int i = 0; i < img1.GetLength(0); i++) { for (int j = 0; j < img1.GetLength(1); j++) { double mag = Math.Sqrt((Math.Pow(img1[i, j].GetColor(ColorPlane.eGreen), 2) + Math.Pow(img2[i, j].GetColor(ColorPlane.eGreen), 2))); double dir = Math.Atan2(img1[i, j].GetColor(ColorPlane.eGreen), img2[i, j].GetColor(ColorPlane.eGreen)); double mag_prime = mag; double dir_prime = dir; mag_prime = ((mag * 255) / Math.Sqrt(Math.Pow(1024, 2) + Math.Pow(1024, 2))); dir_prime = ((dir + Math.PI) / (2 * Math.PI)) * 255; mag_prime = ClampValue(mag_prime, 0.0, 255.0); dir_prime = ClampValue(dir_prime, 0.0, 255.0); mag_img[i, j] = new AdvColor((int)mag_prime, (int)mag_prime, (int)mag_prime, ColorPlane.eGreen); dir_img[i, j] = new AdvColor((int)dir_prime, (int)dir_prime, (int)dir_prime, ColorPlane.eGreen); } } SaveToImage(mag_img, mag_image); SaveToImage(dir_img, dir_image); }
public AdvColor[,] Binzarization(double value, ColorPlane plane, AdvColor[,] source) { AdvColor[,] new_pixels = new AdvColor[pixels.GetLength(0), pixels.GetLength(1)]; for (int i = 0; i < source.GetLength(0); i++) { for (int j = 0; j < source.GetLength(1); j++) { int val = source[i, j].GetColor(plane); if (val < value) { val = 0; } else { val = pixels[i, j].GetColor(plane); } new_pixels[i, j] = new AdvColor(val, val, val, plane); } } return(new_pixels); }
//try 1 - cheese since it was just a 3x3 kernel meant 1 pixel corner //try 2 - mirror and then mirror an edge. - not quite right //try 3 - group solution from class - row major to column major for mirroring public AdvColor[,] MirrorByKernel(int kernel_size_r, int kernel_size_c, AdvColor[,] new_img) { int additions_r = (kernel_size_r / 2); int additions_c = (kernel_size_c / 2); //allocate the larger image AdvColor[,] new_pixels = new AdvColor[new_img.GetLength(0) + (additions_r * 2), new_img.GetLength(1) + (additions_c * 2)]; //copy the bulk of the data first for (int i = 0; i < new_img.GetLength(0); i++) { for (int j = 0; j < new_img.GetLength(1); j++) { int i_prime = i + additions_r; int j_prime = j + additions_c; new_pixels[i_prime, j_prime] = new_img[i, j]; } } //right side for (int i = additions_r; i < new_pixels.GetLength(0) - additions_r; i++) { for (int j = 0; j < additions_c; j++) { int j_prime = new_pixels.GetLength(1) - additions_c + j; int j_sub_prime = new_pixels.GetLength(1) - additions_c - j - 1; new_pixels[i, j_prime] = new AdvColor(new_pixels[i, j_sub_prime], ColorPlane.eAll); } } //left side for (int i = 0; i < pixels.GetLength(0); i++) { int i_prime = additions_r + i; for (int j = 0; j < additions_c; j++) { int j_prime = additions_c - j - 1; new_pixels[i_prime, j_prime] = new AdvColor(new_img[i, j], ColorPlane.eAll); } } //top for (int i = 0; i < additions_r; i++) { for (int j = 0; j < new_img.GetLength(1); j++) { new_pixels[additions_r - i - 1, j + additions_c] = new AdvColor(new_img[i, j], ColorPlane.eGreen); } } //bottom for (int i = 0; i < additions_r; i++) { for (int j = 0; j < new_img.GetLength(1); j++) { int i_new = new_pixels.GetLength(0) - additions_r + i; int i_old = new_img.GetLength(0) - i - 1; new_pixels[i_new, j + additions_c] = new AdvColor(new_img[i_old, j], ColorPlane.eGreen); } } int half_width = additions_c; int half_height = additions_r; //top left corner if (additions_r == 1 && additions_c == 1) { new_pixels[0, 0] = new AdvColor(new_img[0, 0], ColorPlane.eAll); } else if (additions_r > 1 && additions_c > 1) { for (int i = 0, oj = half_width - 1; i < additions_r; ++i, --oj) { for (int j = 0, oi = half_height - 1; j < half_width; ++j, --oi) { new_pixels[i, j] = new AdvColor(pixels[oi, oj], ColorPlane.eGreen); } } /*for (int i = 0; i < additions_r; i++) * { * for (int j = 0; j < additions_c; j++) * { * new_pixels[additions_r - i - 1, additions_c - j - 1] = new AdvColor(new_pixels[i + additions_r, additions_c - j - 1], ColorPlane.eGreen); * } * }*/ } //top right corner if (additions_r == 1 && additions_c == 1) { new_pixels[0, new_img.GetLength(1) + (additions_c * 2) - 1] = new AdvColor(new_img[0, pixels.GetLength(1) - 1], ColorPlane.eAll); } else if (additions_r > 1 && additions_c > 1) { //move UP original pixel - apply across new pixels int orig_start_point = pixels.GetLength(1) - additions_c; for (int i = 0, oj = new_pixels.GetLength(1) - additions_c; i < additions_c; ++i, oj++) { for (int j = orig_start_point, oi = 0; j < pixels.GetLength(1); j++, oi++) { new_pixels[oi, oj] = new AdvColor(pixels[i, j], ColorPlane.eGreen); } } /* * for (int i = 0; i < additions_r; i++) * { * for (int j = 0; j < additions_c; j++) * { * int i_prime = additions_r - i - 1; * int j_prime = new_pixels.GetLength(1) - additions_c + j; * int j_sub_prime = new_img.GetLength(1) + additions_c + j; * new_pixels[i_prime, j_prime] = new AdvColor(new_pixels[i + additions_r, j_sub_prime ], ColorPlane.eGreen); * } * }*/ } //bottom left corner if (additions_r == 1 && additions_c == 1) { new_pixels[new_pixels.GetLength(0) - 1, 0] = new AdvColor(new_img[new_img.GetLength(0) - 1, 0], ColorPlane.eAll); } else { //start bottom left pixel from source image, move right to number of added columns then up until achieved added rows //start at #added columns, new_pixels.GetLength(0) - half_height, move down the rows and back across the columns until achieve added columns for (int i = pixels.GetLength(0) - 1, oj = additions_c - 1; i > pixels.GetLength(0) - (additions_r + 1); --i, --oj) { for (int j = 0, oi = new_pixels.GetLength(0) - additions_r; j < additions_c; j++, oi++) { new_pixels[oi, oj] = new AdvColor(pixels[i, j], ColorPlane.eGreen); } } /* * for (int i = 0; i < additions_r; i++) * { * for (int j = 0; j < additions_c; j++) * { * int i_new = new_pixels.GetLength(0) - additions_r + i; * int i_old = new_pixels.GetLength(0) - additions_r - i - 1; * new_pixels[i_new, additions_c - j - 1] = new AdvColor(new_pixels[i_old, additions_c - j - 1], ColorPlane.eGreen); * } * }*/ } //bottom right corner if (additions_r == 1 && additions_c == 1) { new_pixels[new_pixels.GetLength(0) - 1, new_pixels.GetLength(1) - 1] = new AdvColor(new_img[new_img.GetLength(0) - 1, new_img.GetLength(1) - 1], ColorPlane.eAll); } else { //for initial pixels start at pixels.getlengt(0) - additions_r, pixels.getlength(1)-additions_r //for new pixels start at new_pixels.getlength(0) - 1, new_pixels.getlenght(1)-1 //initial pixels move across additions_c...then down until through additions_r //new pixels move UP the rows and then - 1 column for (int i = pixels.GetLength(0) - additions_r, oj = new_pixels.GetLength(1) - 1; i < pixels.GetLength(0); i++, --oj) { for (int j = pixels.GetLength(1) - additions_r, oi = new_pixels.GetLength(0) - 1; j < pixels.GetLength(1); j++, oi--) { new_pixels[oi, oj] = new AdvColor(pixels[i, j], ColorPlane.eGreen); } } /*for (int i = 0; i < additions_r; i++) * { * for (int j = 0; j < additions_c; j++) * { * int i_new = new_pixels.GetLength(0) - additions_r + i; * int i_old = new_pixels.GetLength(0) - additions_r - i - 1; * int j_new = new_pixels.GetLength(1) - additions_c + j; * new_pixels[i_new, j_new] = new AdvColor(new_pixels[i_old, j_new], ColorPlane.eGreen); * } * }*/ } //make sure nothing was missed for (int i = 0; i < new_pixels.GetLength(0); i++) { for (int j = 0; j < new_pixels.GetLength(1); j++) { if (new_pixels[i, j] == null) { int blah = 0; blah++; } } } return(new_pixels); }
public int GetBinContent(AdvColor bin) { return(histogram[bin]); }
public void DrawBresenhamLine(AdvColor[,] pixel_data, int startH, int startW, int endH, int endW, Color color, Color end_color) { int actual_startH = startH; int actual_startW = startW; int dx = Math.Abs(endW - startW); int dy = Math.Abs(endH - startH); int sx, sy; if (startW < endW) { sx = 1; } else { sx = -1; } if (startH < endH) { sy = 1; } else { sy = -1; } int err = dx - dy; while (true) { if (startH < 0 || startW < 0 || startH >= H || startW >= W) { break; } double percent_startH = ((endH - actual_startH) - (startH - actual_startH)) / Convert.ToDouble(endH - actual_startH); double percent_startW = ((endW - actual_startW) - (startW - actual_startW)) / Convert.ToDouble(endW - actual_startW); double percent = 0.0; if ((endH - actual_startH) > (endW - actual_startW)) { percent = percent_startH; } else { percent = percent_startW; } int colorR = 255; int colorG = 255; int colorB = 255; //Color drawn_color = Color.FromArgb(colorA, colorR, colorG, colorB); pixel_data[startH, startW] = new AdvColor(colorR, colorG, colorB, ColorPlane.eGreen); if (startW == endW && startH == endH) { break; } int e2 = 2 * err; if (e2 > -dy) { err = err - dy; startW = startW + sx; } if (e2 < dx) { err = err + dx; startH = startH + sy; } } }
public double CalcOtsuThreshold() { //get histogram - normalize it Histogram histogram = BuildHistogram(); SortedDictionary <AdvColor, int> bins = histogram.GetHistogram(); int threshold, optimal_thresh; // k = the current threshold; kStar = optimal threshold int N1 = 0, N = 0; // N1 = # points with intensity <=k; N = total number of points double BCV, BCVmax; // The current Between Class Variance and maximum BCV double num, denom; // temporary bookeeping int Sk; // The total intensity for all histogram points <=k int S = 0; // The total intensity of the image bool first = true; for (threshold = 0; threshold < 256; threshold++) { AdvColor color = new AdvColor(threshold, threshold, threshold, ColorPlane.eAll); if (bins.ContainsKey(color)) { if (first) { N1 = bins[color]; first = false; } S += threshold * bins[color]; // Total histogram intensity N += bins[color]; // Total number of data points } } Sk = 0; BCVmax = 0; optimal_thresh = 0; // Look at each possible threshold value, // calculate the between-class variance, and decide if it's a max for (threshold = 1; threshold < 255; threshold++) { AdvColor color = new AdvColor(threshold, threshold, threshold, ColorPlane.eAll); if (bins.ContainsKey(color)) { Sk += threshold * bins[color]; N1 += bins[color]; // The float casting here is to avoid compiler warning about loss of precision and // will prevent overflow in the case of large saturated images denom = (double)(N1)*(N - N1); // Maximum value of denom is (N^2)/4 = approx. 3E10 if (denom != 0.0) { // Float here is to avoid loss of precision when dividing num = ((double)N1 / N) * S - Sk; // Maximum value of num = 255*N = approx 8E7 BCV = (num * num) / denom; } else { BCV = 0; } if (BCV >= BCVmax) { // Assign the best threshold found so far BCVmax = BCV; optimal_thresh = threshold; } } } return(optimal_thresh); }