public static void binary_autoinvert(Bytearray image) { check_binary(image); int count = 0; for (int i = 0; i < image.Length1d(); i++) if (image.At1d(i) > 0) count++; if (count > image.Length1d() / 2) binary_invert(image); }
public static void make_binary(Bytearray image) { for (int i = 0; i < image.Length1d(); i++) { image.Put1d(i, (byte)(image.At1d(i) > 0 ? 255 : 0)); } }
public static int binarize_simple(Bytearray result, Bytearray image) { int threshold = (NarrayUtil.Max(image)/* + NarrayUtil.Min(image)*/) / 2; result.MakeLike(image); for (int i = 0; i < image.Length1d(); i++) result.Put1d(i, image.At1d(i) < threshold ? (byte)0 : (byte)255); return threshold; }
public static void binary_autoinvert(Bytearray image) { check_binary(image); int count = 0; for (int i = 0; i < image.Length1d(); i++) { if (image.At1d(i) > 0) { count++; } } if (count > image.Length1d() / 2) { binary_invert(image); } }
public static void binary_invert(Bytearray image) { check_binary(image); for (int i = 0; i < image.Length1d(); i++) { image.Put1d(i, (byte)(255 - image.At1d(i))); } }
public static void binarize_with_threshold(Bytearray result, Bytearray image, int threshold) { result.MakeLike(image); for (int i = 0; i < image.Length1d(); i++) { result.Put1d(i, image.At1d(i) < threshold ? (byte)0 : (byte)255); } }
public static void Invert(Bytearray a) { int n = a.Length1d(); for (int i = 0; i < n; i++) { a.Put1d(i, (byte)(255 - a.At1d(i))); } }
public static void Thin(ref Bytearray uci) { int w = uci.Dim(0) - 1; int h = uci.Dim(1) - 1; for (int i = 0, n = uci.Length1d(); i < n; i++) { if (uci.At1d(i) > 0) uci.Put1d(i, ON); else uci.Put1d(i, OFF); } bool flag; do { flag = false; for (int j = 0; j < 8; j += 2) { for (int x = 1; x < w; x++) for (int y = 1; y < h; y++) { if (uci[x, y] != ON) continue; if (uci[x + nx[j], y + ny[j]] != OFF) continue; int b = 0; for (int i = 7; i >= 0; i--) { b <<= 1; b |= (uci[x + nx[i], y + ny[i]] != OFF ? 1 : 0); } if (ttable[b] > 0) uci[x, y] = SKEL; else { uci[x, y] = DEL; flag = true; } } if (!flag) continue; for (int x = 1; x < w; x++) for (int y = 1; y < h; y++) if (uci[x, y] == DEL) uci[x, y] = OFF; } } while (flag); for (int i = 0, n = uci.Length1d(); i < n; i++) { if (uci.At1d(i) == SKEL) uci.Put1d(i, 255); else uci.Put1d(i, 0); } }
public static Bitmap read_image_binary(Bytearray image, string path) { Bitmap bitmap = LoadBitmapFromFile(path); image.Resize(bitmap.Width, bitmap.Height); ImgRoutine.NarrayFromBitmap(image, bitmap); double threshold = (NarrayUtil.Min(image) + NarrayUtil.Max(image)) / 2.0; for (int i = 0; i < image.Length1d(); i++) image.Put1d(i, (byte)((image.At1d(i) < threshold) ? 0 : 255)); return bitmap; }
public static int binarize_simple(Bytearray result, Bytearray image) { int threshold = (NarrayUtil.Max(image) /* + NarrayUtil.Min(image)*/) / 2; result.MakeLike(image); for (int i = 0; i < image.Length1d(); i++) { result.Put1d(i, image.At1d(i) < threshold ? (byte)0 : (byte)255); } return(threshold); }
public static void check_binary(Bytearray image) { for (int i = 0; i < image.Length1d(); i++) { int value = image.At1d(i); if (!(value == 0 || value == 255)) { throw new Exception("check_binary: value must be 0 or 255"); } } }
public static void segmentation_as_bitmap(Bytearray image, Intarray cseg) { image.MakeLike(cseg); for (int i = 0; i < image.Length1d(); i++) { int value = cseg.At1d(i); if (value == 0 || value == 0xffffff) { image.Put1d(i, 255); } //if (value == 0xffffff) image.Put1d(i, 255); } }
public static Bitmap read_image_binary(Bytearray image, string path) { Bitmap bitmap = LoadBitmapFromFile(path); image.Resize(bitmap.Width, bitmap.Height); ImgRoutine.NarrayFromBitmap(image, bitmap); double threshold = (NarrayUtil.Min(image) + NarrayUtil.Max(image)) / 2.0; for (int i = 0; i < image.Length1d(); i++) { image.Put1d(i, (byte)((image.At1d(i) < threshold) ? 0 : 255)); } return(bitmap); }
/// <summary> /// Remove segments from start to end. /// </summary> /// <param name="cseg">Output</param> /// <param name="rseg">Input</param> /// <param name="start">start remove position</param> /// <param name="end">end remove position</param> public static void rseg_to_cseg_remove(Intarray cseg, Intarray rseg, Bytearray outimg, Bytearray img, int start, int end) { int maxSegNum = NarrayUtil.Max(rseg); if (start > end) { throw new Exception("segmentation encoded in IDs looks seriously broken!"); } if (start > maxSegNum || end > maxSegNum) { throw new Exception("segmentation encoded in IDs doesn't fit!"); } if (rseg.Length1d() != img.Length1d()) { throw new Exception("rseg and img must have same a dimension!"); } Intarray map = new Intarray(maxSegNum + 1); map.Fill(0); int color = 1; for (int i = 1; i <= maxSegNum; i++) { map[i] = color; if (i < start || i > end) { color++; } else { map[i] = 0; } } cseg.MakeLike(rseg); outimg.Copy(img); for (int i = 0; i < cseg.Length1d(); i++) { int val = rseg.At1d(i); cseg.Put1d(i, map[val]); if (val > 0 && map[val] == 0) { outimg.Put1d(i, 255); } } }
public override void Binarize(Bytearray bin_image, Bytearray gray_image) { w = PGeti("w"); k = (float)PGetf("k"); whalf = w >> 1; // fprintf(stderr,"[sauvola %g %d]\n",k,w); if (k < 0.001 || k > 0.999) { throw new Exception("Binarize: CHECK_ARG(k>=0.001 && k<=0.999)"); } if (w == 0 || k >= 1000) { throw new Exception("Binarize: CHECK_ARG(w>0 && k<1000)"); } if (bin_image.Length1d() != gray_image.Length1d()) { bin_image.MakeLike(gray_image); } if (NarrayUtil.contains_only(gray_image, (byte)0, (byte)255)) { bin_image.Copy(gray_image); return; } int image_width = gray_image.Dim(0); int image_height = gray_image.Dim(1); whalf = w >> 1; // Calculate the integral image, and integral of the squared image Narray <long> integral_image = new Narray <long>(), rowsum_image = new Narray <long>(); Narray <long> integral_sqimg = new Narray <long>(), rowsum_sqimg = new Narray <long>(); integral_image.MakeLike(gray_image); rowsum_image.MakeLike(gray_image); integral_sqimg.MakeLike(gray_image); rowsum_sqimg.MakeLike(gray_image); int xmin, ymin, xmax, ymax; double diagsum, idiagsum, diff, sqdiagsum, sqidiagsum, sqdiff, area; double mean, std, threshold; for (int j = 0; j < image_height; j++) { rowsum_image[0, j] = gray_image[0, j]; rowsum_sqimg[0, j] = gray_image[0, j] * gray_image[0, j]; } for (int i = 1; i < image_width; i++) { for (int j = 0; j < image_height; j++) { rowsum_image[i, j] = rowsum_image[i - 1, j] + gray_image[i, j]; rowsum_sqimg[i, j] = rowsum_sqimg[i - 1, j] + gray_image[i, j] * gray_image[i, j]; } } for (int i = 0; i < image_width; i++) { integral_image[i, 0] = rowsum_image[i, 0]; integral_sqimg[i, 0] = rowsum_sqimg[i, 0]; } for (int i = 0; i < image_width; i++) { for (int j = 1; j < image_height; j++) { integral_image[i, j] = integral_image[i, j - 1] + rowsum_image[i, j]; integral_sqimg[i, j] = integral_sqimg[i, j - 1] + rowsum_sqimg[i, j]; } } //Calculate the mean and standard deviation using the integral image for (int i = 0; i < image_width; i++) { for (int j = 0; j < image_height; j++) { xmin = Math.Max(0, i - whalf); ymin = Math.Max(0, j - whalf); xmax = Math.Min(image_width - 1, i + whalf); ymax = Math.Min(image_height - 1, j + whalf); area = (xmax - xmin + 1) * (ymax - ymin + 1); // area can't be 0 here // proof (assuming whalf >= 0): // we'll prove that (xmax-xmin+1) > 0, // (ymax-ymin+1) is analogous // It's the same as to prove: xmax >= xmin // image_width - 1 >= 0 since image_width > i >= 0 // i + whalf >= 0 since i >= 0, whalf >= 0 // i + whalf >= i - whalf since whalf >= 0 // image_width - 1 >= i - whalf since image_width > i // --IM if (area <= 0) { throw new Exception("Binarize: area can't be 0 here"); } if (xmin == 0 && ymin == 0) { // Point at origin diff = integral_image[xmax, ymax]; sqdiff = integral_sqimg[xmax, ymax]; } else if (xmin == 0 && ymin > 0) { // first column diff = integral_image[xmax, ymax] - integral_image[xmax, ymin - 1]; sqdiff = integral_sqimg[xmax, ymax] - integral_sqimg[xmax, ymin - 1]; } else if (xmin > 0 && ymin == 0) { // first row diff = integral_image[xmax, ymax] - integral_image[xmin - 1, ymax]; sqdiff = integral_sqimg[xmax, ymax] - integral_sqimg[xmin - 1, ymax]; } else { // rest of the image diagsum = integral_image[xmax, ymax] + integral_image[xmin - 1, ymin - 1]; idiagsum = integral_image[xmax, ymin - 1] + integral_image[xmin - 1, ymax]; diff = diagsum - idiagsum; sqdiagsum = integral_sqimg[xmax, ymax] + integral_sqimg[xmin - 1, ymin - 1]; sqidiagsum = integral_sqimg[xmax, ymin - 1] + integral_sqimg[xmin - 1, ymax]; sqdiff = sqdiagsum - sqidiagsum; } mean = diff / area; std = Math.Sqrt((sqdiff - diff * diff / area) / (area - 1)); threshold = mean * (1 + k * ((std / 128) - 1)); if (gray_image[i, j] < threshold) { bin_image[i, j] = 0; } else { bin_image[i, j] = (byte)(MAXVAL - 1); } } } if (PGeti("debug_binarize") > 0) { ImgIo.write_image_gray("debug_binarize.png", bin_image); } }
public override void Binarize(Bytearray bin_image, Bytearray gray_image) { if (bin_image.Length1d() != gray_image.Length1d()) { bin_image.MakeLike(gray_image); } if (NarrayUtil.contains_only(gray_image, (byte)0, (byte)255)) { bin_image.Copy(gray_image); return; } int image_width = gray_image.Dim(0); int image_height = gray_image.Dim(1); int[] hist = new int[MAXVAL]; double[] pdf = new double[MAXVAL]; //probability distribution double[] cdf = new double[MAXVAL]; //cumulative probability distribution double[] myu = new double[MAXVAL]; // mean value for separation double max_sigma; double[] sigma = new double[MAXVAL]; // inter-class variance /* Histogram generation */ for (int i = 0; i < MAXVAL; i++) { hist[i] = 0; } for (int x = 0; x < image_width; x++) { for (int y = 0; y < image_height; y++) { hist[gray_image[x, y]]++; } } /* calculation of probability density */ for (int i = 0; i < MAXVAL; i++) { pdf[i] = (double)hist[i] / (image_width * image_height); } /* cdf & myu generation */ cdf[0] = pdf[0]; myu[0] = 0.0; /* 0.0 times prob[0] equals zero */ for (int i = 1; i < MAXVAL; i++) { cdf[i] = cdf[i - 1] + pdf[i]; myu[i] = myu[i - 1] + i * pdf[i]; } /* sigma maximization * sigma stands for inter-class variance * and determines optimal threshold value */ int threshold = 0; max_sigma = 0.0; for (int i = 0; i < MAXVAL - 1; i++) { if (cdf[i] != 0.0 && cdf[i] != 1.0) { double p1p2 = cdf[i] * (1.0 - cdf[i]); double mu1mu2diff = myu[MAXVAL - 1] * cdf[i] - myu[i]; sigma[i] = mu1mu2diff * mu1mu2diff / p1p2; } else { sigma[i] = 0.0; } if (sigma[i] > max_sigma) { max_sigma = sigma[i]; threshold = i; } } for (int x = 0; x < image_width; x++) { for (int y = 0; y < image_height; y++) { if (gray_image[x, y] > threshold) { bin_image[x, y] = (byte)(MAXVAL - 1); } else { bin_image[x, y] = 0; } } } if (PGeti("debug_otsu") > 0) { Logger.Default.Format("Otsu threshold value = {0}\n", threshold); //ImgIo.write_image_gray("debug_otsu.png", bin_image); } }
public static void make_binary(Bytearray image) { for (int i = 0; i < image.Length1d(); i++) image.Put1d(i, (byte)(image.At1d(i) > 0 ? 255 : 0)); }
public static void check_binary(Bytearray image) { for (int i = 0; i < image.Length1d(); i++) { int value = image.At1d(i); if (!(value == 0 || value == 255)) throw new Exception("check_binary: value must be 0 or 255"); } }
public static void binary_invert(Bytearray image) { check_binary(image); for (int i = 0; i < image.Length1d(); i++) image.Put1d(i, (byte)(255 - image.At1d(i))); }
public static void Thin(ref Bytearray uci) { int w = uci.Dim(0) - 1; int h = uci.Dim(1) - 1; for (int i = 0, n = uci.Length1d(); i < n; i++) { if (uci.At1d(i) > 0) { uci.Put1d(i, ON); } else { uci.Put1d(i, OFF); } } bool flag; do { flag = false; for (int j = 0; j < 8; j += 2) { for (int x = 1; x < w; x++) { for (int y = 1; y < h; y++) { if (uci[x, y] != ON) { continue; } if (uci[x + nx[j], y + ny[j]] != OFF) { continue; } int b = 0; for (int i = 7; i >= 0; i--) { b <<= 1; b |= (uci[x + nx[i], y + ny[i]] != OFF ? 1 : 0); } if (ttable[b] > 0) { uci[x, y] = SKEL; } else { uci[x, y] = DEL; flag = true; } } } if (!flag) { continue; } for (int x = 1; x < w; x++) { for (int y = 1; y < h; y++) { if (uci[x, y] == DEL) { uci[x, y] = OFF; } } } } } while (flag); for (int i = 0, n = uci.Length1d(); i < n; i++) { if (uci.At1d(i) == SKEL) { uci.Put1d(i, 255); } else { uci.Put1d(i, 0); } } }
public override void Binarize(Bytearray bin_image, Bytearray gray_image) { w = PGeti("w"); k = (float)PGetf("k"); whalf = w >> 1; // fprintf(stderr,"[sauvola %g %d]\n",k,w); if(k<0.001 || k>0.999) throw new Exception("Binarize: CHECK_ARG(k>=0.001 && k<=0.999)"); if(w==0 || k>=1000) throw new Exception("Binarize: CHECK_ARG(w>0 && k<1000)"); if(bin_image.Length1d() != gray_image.Length1d()) bin_image.MakeLike(gray_image); if(NarrayUtil.contains_only(gray_image, (byte)0, (byte)255)) { bin_image.Copy(gray_image); return; } int image_width = gray_image.Dim(0); int image_height = gray_image.Dim(1); whalf = w >> 1; // Calculate the integral image, and integral of the squared image Narray<long> integral_image = new Narray<long>(), rowsum_image = new Narray<long>(); Narray<long> integral_sqimg = new Narray<long>(), rowsum_sqimg = new Narray<long>(); integral_image.MakeLike(gray_image); rowsum_image.MakeLike(gray_image); integral_sqimg.MakeLike(gray_image); rowsum_sqimg.MakeLike(gray_image); int xmin,ymin,xmax,ymax; double diagsum,idiagsum,diff,sqdiagsum,sqidiagsum,sqdiff,area; double mean,std,threshold; for (int j = 0; j < image_height; j++) { rowsum_image[0, j] = gray_image[0, j]; rowsum_sqimg[0, j] = gray_image[0, j] * gray_image[0, j]; } for (int i = 1; i < image_width; i++) { for (int j = 0; j < image_height; j++) { rowsum_image[i, j] = rowsum_image[i - 1, j] + gray_image[i, j]; rowsum_sqimg[i, j] = rowsum_sqimg[i - 1, j] + gray_image[i, j] * gray_image[i, j]; } } for (int i = 0; i < image_width; i++) { integral_image[i, 0] = rowsum_image[i, 0]; integral_sqimg[i, 0] = rowsum_sqimg[i, 0]; } for (int i = 0; i < image_width; i++) { for (int j = 1; j < image_height; j++) { integral_image[i, j] = integral_image[i, j - 1] + rowsum_image[i, j]; integral_sqimg[i, j] = integral_sqimg[i, j - 1] + rowsum_sqimg[i, j]; } } //Calculate the mean and standard deviation using the integral image for(int i=0; i<image_width; i++){ for(int j=0; j<image_height; j++){ xmin = Math.Max(0,i-whalf); ymin = Math.Max(0, j - whalf); xmax = Math.Min(image_width - 1, i + whalf); ymax = Math.Min(image_height - 1, j + whalf); area = (xmax-xmin+1)*(ymax-ymin+1); // area can't be 0 here // proof (assuming whalf >= 0): // we'll prove that (xmax-xmin+1) > 0, // (ymax-ymin+1) is analogous // It's the same as to prove: xmax >= xmin // image_width - 1 >= 0 since image_width > i >= 0 // i + whalf >= 0 since i >= 0, whalf >= 0 // i + whalf >= i - whalf since whalf >= 0 // image_width - 1 >= i - whalf since image_width > i // --IM if (area <= 0) throw new Exception("Binarize: area can't be 0 here"); if (xmin == 0 && ymin == 0) { // Point at origin diff = integral_image[xmax, ymax]; sqdiff = integral_sqimg[xmax, ymax]; } else if (xmin == 0 && ymin > 0) { // first column diff = integral_image[xmax, ymax] - integral_image[xmax, ymin - 1]; sqdiff = integral_sqimg[xmax, ymax] - integral_sqimg[xmax, ymin - 1]; } else if (xmin > 0 && ymin == 0) { // first row diff = integral_image[xmax, ymax] - integral_image[xmin - 1, ymax]; sqdiff = integral_sqimg[xmax, ymax] - integral_sqimg[xmin - 1, ymax]; } else { // rest of the image diagsum = integral_image[xmax, ymax] + integral_image[xmin - 1, ymin - 1]; idiagsum = integral_image[xmax, ymin - 1] + integral_image[xmin - 1, ymax]; diff = diagsum - idiagsum; sqdiagsum = integral_sqimg[xmax, ymax] + integral_sqimg[xmin - 1, ymin - 1]; sqidiagsum = integral_sqimg[xmax, ymin - 1] + integral_sqimg[xmin - 1, ymax]; sqdiff = sqdiagsum - sqidiagsum; } mean = diff/area; std = Math.Sqrt((sqdiff - diff*diff/area)/(area-1)); threshold = mean*(1+k*((std/128)-1)); if(gray_image[i,j] < threshold) bin_image[i,j] = 0; else bin_image[i,j] = (byte)(MAXVAL-1); } } if(PGeti("debug_binarize") > 0) { ImgIo.write_image_gray("debug_binarize.png", bin_image); } }
public static void binarize_with_threshold(Bytearray result, Bytearray image, int threshold) { result.MakeLike(image); for (int i = 0; i < image.Length1d(); i++) result.Put1d(i, image.At1d(i) < threshold ? (byte)0 : (byte)255); }
public override void Binarize(Bytearray bin_image, Bytearray gray_image) { if(bin_image.Length1d() != gray_image.Length1d()) bin_image.MakeLike(gray_image); if(NarrayUtil.contains_only(gray_image, (byte)0, (byte)255)) { bin_image.Copy(gray_image); return; } int image_width = gray_image.Dim(0); int image_height = gray_image.Dim(1); int[] hist = new int[MAXVAL]; double[] pdf = new double[MAXVAL]; //probability distribution double[] cdf = new double[MAXVAL]; //cumulative probability distribution double[] myu = new double[MAXVAL]; // mean value for separation double max_sigma; double[] sigma = new double[MAXVAL]; // inter-class variance /* Histogram generation */ for(int i=0; i<MAXVAL; i++){ hist[i] = 0; } for(int x=0; x<image_width; x++){ for(int y=0; y<image_height; y++){ hist[gray_image[x,y]]++; } } /* calculation of probability density */ for(int i=0; i<MAXVAL; i++){ pdf[i] = (double)hist[i] / (image_width * image_height); } /* cdf & myu generation */ cdf[0] = pdf[0]; myu[0] = 0.0; /* 0.0 times prob[0] equals zero */ for(int i=1; i<MAXVAL; i++){ cdf[i] = cdf[i-1] + pdf[i]; myu[i] = myu[i-1] + i*pdf[i]; } /* sigma maximization sigma stands for inter-class variance and determines optimal threshold value */ int threshold = 0; max_sigma = 0.0; for(int i=0; i<MAXVAL-1; i++){ if(cdf[i] != 0.0 && cdf[i] != 1.0){ double p1p2 = cdf[i]*(1.0 - cdf[i]); double mu1mu2diff = myu[MAXVAL-1]*cdf[i]-myu[i]; sigma[i] = mu1mu2diff * mu1mu2diff / p1p2; } else sigma[i] = 0.0; if(sigma[i] > max_sigma){ max_sigma = sigma[i]; threshold = i; } } for(int x=0; x<image_width; x++){ for(int y=0; y<image_height; y++){ if (gray_image[x,y] > threshold) bin_image[x,y] = (byte)(MAXVAL-1); else bin_image[x,y] = 0; } } if(PGeti("debug_otsu") > 0) { Logger.Default.Format("Otsu threshold value = {0}\n", threshold); //ImgIo.write_image_gray("debug_otsu.png", bin_image); } }