private void ProcessSegmentationMethod(object sender, RoutedEventArgs e) { string strSermenterName = (sender as Control).Tag.ToString(); ISegmentLine segmenter = ComponentCreator.MakeComponent <ISegmentLine>(strSermenterName); if (segmenter == null || currBookLine == null) { return; } // приведем к чернобелому Bytearray image = currBookLine.ImageBytearray; //IBinarize binarizer = new BinarizeByOtsu(); //binarizer.Binarize(image, image); OcrRoutine.binarize_simple(image, image); // сегментация Intarray charseg = new Intarray(); segmenter.Charseg(ref charseg, image); // фон равен 0 SegmRoutine.make_line_segmentation_black(charseg); // удалим маленькие сегменты SegmRoutine.remove_small_components(charseg, 3, 3); ImgLabels.renumber_labels(charseg, 1); currBookLine.CharsegIntarray = charseg; CurrSegmentsCount = NarrayUtil.Max(charseg); // Show segmented image ShowCharsegImage(charseg, (currBookLine.HaveTranscript && CurrSegmentsCount == currBookLine.Transcript.Length) ? currBookLine.Transcript : ""); // to enable save button EnableCharsegCmdButtons(); }
public static void remove_small_components(Intarray segmentation, int w = 5, int h = 4) { if (NarrayUtil.Max(segmentation) > 100000) { throw new Exception("remove_small_components: to many segments"); } Narray <Rect> bboxes = new Narray <Rect>(); ImgLabels.bounding_boxes(ref bboxes, segmentation); for (int i = 1; i < bboxes.Length(); i++) { Rect b = bboxes[i]; if (b.Width() < w && b.Height() < h) { for (int x = b.x0; x < b.x1; x++) { for (int y = b.y0; y < b.y1; y++) { if (segmentation[x, y] == i) { segmentation[x, y] = 0; } } } } } }
public static void threshold_frac(Bytearray thresholded, Floatarray input, float frac) { float minofinput = NarrayUtil.Min(input); float theta = frac * (NarrayUtil.Max(input) - minofinput) + minofinput; binarize_with_threshold(thresholded, input, theta); }
public override void SetSegmentationAndGt(Intarray segmentation, Intarray cseg, ref string text) { // first, set the segmentation as usual SetSegmentation(segmentation); // Maybe fix up the transcript (remove spaces). gttranscript = text; string s = text; fixup_transcript(ref s, false); int max_cseg = NarrayUtil.Max(cseg); bool old_csegs = (s.Length != max_cseg); fixup_transcript(ref gttranscript, old_csegs); // Complain if it doesn't match. if (gttranscript.Length != max_cseg) { Logger.Default.Format("transcript = '{0}'\n", gttranscript); throw new Exception(String.Format("transcript doesn't agree with cseg (transcript {0}, cseg {1})", gttranscript.Length, max_cseg)); } // Now compute the correspondences between the character segmentation // and the raw segmentation. GrouperRoutine.segmentation_correspondences(gtsegments, segmentation, cseg); }
public static void rseg_to_cseg(Intarray cseg, Intarray rseg, Intarray ids) { Intarray map = new Intarray(NarrayUtil.Max(rseg) + 1); map.Fill(0); int color = 0; for (int i = 0; i < ids.Length(); i++) { if (ids[i] == 0) { continue; } color++; int start = ids[i] >> 16; int end = ids[i] & 0xFFFF; if (start > end) { throw new Exception("segmentation encoded in IDs looks seriously broken!"); } if (start >= map.Length() || end >= map.Length()) { throw new Exception("segmentation encoded in IDs doesn't fit!"); } for (int j = start; j <= end; j++) { map[j] = color; } } cseg.MakeLike(rseg); for (int i = 0; i < cseg.Length1d(); i++) { cseg.Put1d(i, map[rseg.At1d(i)]); } }
/// <summary> /// Merge segments from start to end. /// </summary> /// <param name="cseg">Output</param> /// <param name="rseg">Input</param> /// <param name="start">start merge position</param> /// <param name="end">end merge position</param> public static void rseg_to_cseg(Intarray cseg, Intarray rseg, 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!"); } 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++; } } cseg.MakeLike(rseg); for (int i = 0; i < cseg.Length1d(); i++) { cseg.Put1d(i, map[rseg.At1d(i)]); } }
protected void Recompute() { nc = NarrayUtil.Max(classes) + 1; nf = data[0].Dim(0); CHECK_ARG(DataMin(data) >= 0 && DataMax(data) < 256, "min(data) >= 0 && max(data) < 256"); CHECK_ARG(NarrayUtil.Min(classes) >= -1 && NarrayUtil.Max(classes) < 10000, "min(classes)>=-1 && max(classes)<10000"); CHECK_ARG(nc > 0, "nc > 0"); CHECK_ARG(nf > 0, "nf > 0"); }
protected void Recompute() { nc = NarrayUtil.Max(classes) + 1; nf = data.Dim(1); CHECK_ARG(Min(data) > -100 && Max(data) < 100, "min(data) > -100 && max(data) < 100"); CHECK_ARG(NarrayUtil.Min(classes) >= -1 && NarrayUtil.Max(classes) < 10000, "min(classes)>=-1 && max(classes)<10000"); CHECK_ARG(nc > 0, "nc > 0"); CHECK_ARG(nf > 0, "nf > 0"); }
public static void combine_segmentations(ref Intarray dst, Intarray src) { dst.SameDims(src); int n = NarrayUtil.Max(dst) + 1; for (int i = 0; i < dst.Length1d(); i++) { dst.Put1d(i, (dst.At1d(i) + src.At1d(i) * n)); } ImgLabels.renumber_labels(dst, 1); }
/// <summary> /// Изменился текущий BookLine /// </summary> private void BookLine_CurrentChanged(object sender, EventArgs e) { if (listingDataView.View.CurrentItem == null) { return; } // сбросим кэш предыдущего елемента if (currBookLine != null) { currBookLine.Image = null; currBookLine.ImageBytearray = null; currBookLine.CharsegIntarray = null; } // текущий елемент BookLine bline = listingDataView.View.CurrentItem as BookLine; currBookLine = bline; // сбросим некоторые признаки isCurrDeletedSegment = false; // показать Charseg if (bline != null && bline.HaveCharseg) { // загрузим с файла Intarray charseg = bline.CharsegIntarray; // занесем в кэш bline.CharsegIntarray = charseg; // номер максимального сегмента CurrSegmentsCount = NarrayUtil.Max(charseg); // отобразим картинку ShowCharsegImage(charseg, bline.Transcript); // активируем кнопки действий EnableCharsegCmdButtons(); } else { imgCharSeg.Source = null; DisableCharsegCmdButtons(); } // показать Transcript if (bline != null && bline.HaveTranscript) { ShowTranscript(bline.Transcript); } else { ShowTranscript(""); } // сбросим к началу номер начальног осегмента numUpDnStart.Value = 1; numUpDnEnd.Value = 2; }
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 binsmooth(Bytearray binary, Floatarray input, float sigma) { Floatarray smoothed = new Floatarray(); smoothed.Copy(input); smoothed -= NarrayUtil.Min(smoothed); smoothed /= NarrayUtil.Max(smoothed); if (sigma > 0) { Gauss.Gauss2d(smoothed, sigma, sigma); } binarize_with_threshold(binary, smoothed, 0.5f); }
/// <summary> /// Get spacing to the next component. /// </summary> public override int PixelSpace(int i) { int end = NarrayUtil.Max(segments.At1d(i)); if (end >= rboxes.Length() - 1) { return(-1); } int x0 = rboxes.At1d(end).x1; int x1 = rboxes.At1d(end + 1).x0; return(x1 - x0); }
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 override void Add(Floatarray v, int c) { CHECK_ARG(NarrayUtil.Min(v) > -1.2f && NarrayUtil.Max(v) < 1.2f, "float8: value out of range (-1.2..1.2)"); CHECK_ARG(c >= -1, "c>=-1"); if (c >= nc) { nc = c + 1; } if (nf < 0) { nf = v.Length(); } RowPush(data, v); classes.Push(c); }
/// <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); } } }
private void ProcessMergeSegments(object sender, RoutedEventArgs e) { int start = numUpDnStart.Value ?? 1; int end = numUpDnEnd.Value ?? 1; start = Math.Min(start, CurrSegmentsCount); end = Math.Min(end, CurrSegmentsCount); SegmRoutine.rseg_to_cseg(currBookLine.CharsegIntarray, currBookLine.CharsegIntarray, start, end); // пересчитаем число сегментов CurrSegmentsCount = NarrayUtil.Max(currBookLine.CharsegIntarray); // Show segmented image ShowCharsegImage(currBookLine.CharsegIntarray, (currBookLine.HaveTranscript && CurrSegmentsCount == currBookLine.Transcript.Length) ? currBookLine.Transcript : ""); }
public static void line_segmentation_sort_x(Intarray segmentation) { if (NarrayUtil.Max(segmentation) > 100000) { throw new Exception("line_segmentation_merge_small_components: to many segments"); } Narray <Rect> bboxes = new Narray <Rect>(); ImgLabels.bounding_boxes(ref bboxes, segmentation); Floatarray x0s = new Floatarray(); unchecked { x0s.Push((float)-999999); } for (int i = 1; i < bboxes.Length(); i++) { if (bboxes[i].Empty()) { x0s.Push(999999); } else { x0s.Push(bboxes[i].x0); } } // dprint(x0s,1000); printf("\n"); Narray <int> permutation = new Intarray(); Narray <int> rpermutation = new Intarray(); NarrayUtil.Quicksort(permutation, x0s); rpermutation.Resize(permutation.Length()); for (int i = 0; i < permutation.Length(); i++) { rpermutation[permutation[i]] = i; } // dprint(rpermutation,1000); printf("\n"); for (int i = 0; i < segmentation.Length1d(); i++) { if (segmentation.At1d(i) == 0) { continue; } segmentation.Put1d(i, rpermutation[segmentation.At1d(i)]); } }
public override void Info() { bool bak = Logger.Default.verbose; Logger.Default.verbose = true; Logger.Default.WriteLine("MLP"); PPrint(); Logger.Default.WriteLine(String.Format("nInput {0} nHidden {1} nOutput {2}", w1.Dim(1), w1.Dim(0), w2.Dim(0))); if (w1.Length() > 0 && w2.Length() > 0) { Logger.Default.WriteLine(String.Format("w1 [{0},{1}] b1 [{2},{3}]", NarrayUtil.Min(w1), NarrayUtil.Max(w1), NarrayUtil.Min(b1), NarrayUtil.Max(b1))); Logger.Default.WriteLine(String.Format("w2 [{0},{1}] b2 [{2},{3}]", NarrayUtil.Min(w2), NarrayUtil.Max(w2), NarrayUtil.Min(b2), NarrayUtil.Max(b2))); } Logger.Default.verbose = bak; }
public static void weighted_sample(Intarray samples, Floatarray weights, int n) { Floatarray cs = new Floatarray(); cs.Copy(weights); for (int i = 1; i < cs.Length(); i++) { cs[i] += cs[i - 1]; } cs /= NarrayUtil.Max(cs); samples.Clear(); for (int i = 0; i < n; i++) { float value = (float)DRandomizer.Default.drand(); int where = Binsearch(cs, value); samples.Push(where); } }
public Dataset8(Narray <sbyte> data, Intarray classes) : this() { data.Copy(data); classes.Copy(classes); if (classes.Length() > 0) { nc = NarrayUtil.Max(classes) + 1; nf = data.Dim(1); //CHECK_ARG(NarrayUtil.Min(data) > -100 && NarrayUtil.Max(data) < 100, "min(data)>-100 && max(data)<100"); CHECK_ARG(NarrayUtil.Min(classes) >= -1 && NarrayUtil.Max(classes) < 10000, "min(classes)>=-1 && max(classes)<10000"); } else { nc = 0; nf = -1; } }
/// <summary> /// Compute a classmap that maps a set of possibly sparse classes onto a dense /// list of new classes and vice versa /// </summary> public static void ClassMap(Intarray out_class_to_index, Intarray out_index_to_class, Intarray classes) { int nclasses = NarrayUtil.Max(classes) + 1; Intarray hist = new Intarray(nclasses); hist.Fill(0); for (int i = 0; i < classes.Length(); i++) { if (classes[i] == -1) { continue; } hist[classes[i]]++; } int count = 0; for (int i = 0; i < hist.Length(); i++) { if (hist[i] > 0) { count++; } } out_class_to_index.Resize(nclasses); out_class_to_index.Fill(-1); out_index_to_class.Resize(count); out_index_to_class.Fill(-1); int index = 0; for (int i = 0; i < hist.Length(); i++) { if (hist[i] > 0) { out_class_to_index[i] = index; out_index_to_class[index] = i; index++; } } CHECK_ARG(out_class_to_index.Length() == nclasses, "class_to_index.Length() == nclasses"); CHECK_ARG(out_index_to_class.Length() == NarrayUtil.Max(out_class_to_index) + 1, "index_to_class.Length() == Max(class_to_index)+1"); CHECK_ARG(out_index_to_class.Length() <= out_class_to_index.Length(), "index_to_class.Length() <= class_to_index.Length()"); }
public static void binarize_by_range(Bytearray outa, Floatarray ina, float fraction) { float imin = NarrayUtil.Min(ina); float imax = NarrayUtil.Max(ina); float thresh = (int)(imin + (imax - imin) * fraction); outa.MakeLike(ina); for (int i = 0; i < ina.Length1d(); i++) { if (ina.At1d(i) > thresh) { outa.Put1d(i, 255); } else { outa.Put1d(i, 0); } } }
public override void Add(Floatarray v, int c) { CHECK_ARG(NarrayUtil.Min(v) >= 0.0f && NarrayUtil.Max(v) <= 1.0f, "float8: value out of range (0..1)"); CHECK_ARG(c >= -1, "c>=-1"); if (c >= nc) { nc = c + 1; } if (nf < 0) { nf = v.Length(); } Narray <byte> newDataItem = data.Push(new Narray <byte>()); Copy(newDataItem, v); classes.Push(c); CHECK_ARG(nc > 0, "nc>0"); CHECK_ARG(nf > 0, "nf>0"); }
public static void erase_small_components(Floatarray input, float mins = 0.2f, float thresh = 0.25f) { // compute a thresholded image for component labeling float threshold = thresh * NarrayUtil.Max(input); Intarray components = new Intarray(); components.MakeLike(input); components.Fill(0); for (int i = 0; i < components.Length(); i++) { components[i] = (input[i] > threshold ? 1 : 0); } // compute the number of pixels in each component int n = ImgLabels.label_components(ref components); Intarray totals = new Intarray(n + 1); totals.Fill(0); for (int i = 0; i < components.Length(); i++) { totals[components[i]] = totals[components[i]] + 1; } totals[0] = 0; int biggest = NarrayUtil.ArgMax(totals); // erase small components float minsize = mins * totals[biggest]; Bytearray keep = new Bytearray(n + 1); float background = NarrayUtil.Min(input); for (int i = 0; i < keep.Length(); i++) { keep[i] = (byte)(totals[i] > minsize ? 1 : 0); } for (int i = 0; i < input.Length(); i++) { if (keep[components[i]] == 0) { input[i] = background; } } }
public static void segmentation_correspondences(Narray <Intarray> outsegments, Intarray seg, Intarray cseg) { if (NarrayUtil.Max(seg) >= 10000) { throw new Exception("CHECK_ARG: (max(seg)<10000)"); } if (NarrayUtil.Max(cseg) >= 10000) { throw new Exception("CHECK_ARG: (max(cseg)<10000)"); } int nseg = NarrayUtil.Max(seg) + 1; int ncseg = NarrayUtil.Max(cseg) + 1; Intarray overlaps = new Intarray(nseg, ncseg); overlaps.Fill(0); if (seg.Length() != cseg.Length()) { throw new Exception("CHECK_ARG: (seg.Length()==cseg.Length())"); } for (int i = 0; i < seg.Length(); i++) { overlaps[seg.At1d(i), cseg.At1d(i)]++; } outsegments.Clear(); outsegments.Resize(ncseg); for (int i = 0; i < nseg; i++) { int j = NarrayRowUtil.RowArgMax(overlaps, i); if (!(j >= 0 && j < ncseg)) { throw new Exception("ASSERT: (j>=0 && j<ncseg)"); } if (outsegments[j] == null) { outsegments[j] = new Intarray(); } outsegments[j].Push(i); } }
/// <summary> /// Compute the bounding boxes for the pixels in the image. /// </summary> public static void bounding_boxes(ref Narray <Rect> result, Intarray image) { result.Clear(); int n = NarrayUtil.Max(image); if (n < 1) { return; } result.Resize(n + 1); result.Fill(Rect.CreateEmpty()); for (int i = 0; i < image.Dim(0); i++) { for (int j = 0; j < image.Dim(1); j++) { int value = image[i, j]; Rect r = result[value]; r.Include(i, j); result[value] = r; //original: result(value).include(i, j); } } }
private void ProcessDeleteSegment(object sender, RoutedEventArgs e) { int start = numUpDnStart.Value ?? 1; start = Math.Min(start, CurrSegmentsCount); Bytearray outgray = new Bytearray(); SegmRoutine.rseg_to_cseg_remove( currBookLine.CharsegIntarray, currBookLine.CharsegIntarray, outgray, currBookLine.ImageBytearray, start, start); // пересчитаем число сегментов CurrSegmentsCount = NarrayUtil.Max(currBookLine.CharsegIntarray); // Show segmented image ShowCharsegImage(currBookLine.CharsegIntarray, (currBookLine.HaveTranscript && CurrSegmentsCount == currBookLine.Transcript.Length) ? currBookLine.Transcript : ""); currBookLine.ImageBytearray = outgray; currBookLine.Image = ImgRoutine.NarrayToRgbBitmap(outgray); isCurrDeletedSegment = true; }
public override int nClasses() { return(NarrayUtil.Max(_classes) + 1); }
protected void rescale(Floatarray v, Floatarray input) { if (input.Rank() != 2) { throw new Exception("CHECK_ARG: sub.Rank()==2"); } Floatarray sub = new Floatarray(); // find the largest connected component // and crop to its bounding box // (use a binary version of the character // to compute the bounding box) Intarray components = new Intarray(); float threshold = PGetf("threshold") * NarrayUtil.Max(input); Global.Debugf("biggestcc", "threshold {0}", threshold); components.MakeLike(input); components.Fill(0); for (int i = 0; i < components.Length(); i++) { components[i] = (input[i] > threshold ? 1 : 0); } int n = ImgLabels.label_components(ref components); Intarray totals = new Intarray(n + 1); totals.Fill(0); for (int i = 0; i < components.Length(); i++) { totals[components[i]]++; } totals[0] = 0; Narray <Rect> boxes = new Narray <Rect>(); ImgLabels.bounding_boxes(ref boxes, components); int biggest = NarrayUtil.ArgMax(totals); Rect r = boxes[biggest]; int pad = (int)(PGetf("pad") + 0.5f); r.PadBy(pad, pad); Global.Debugf("biggestcc", "({0}) {1}[{2}] :: {3} {4} {5} {6}", n, biggest, totals[biggest], r.x0, r.y0, r.x1, r.y1); // now perform normal feature extraction // (use the original grayscale input) sub = input; ImgMisc.Crop(sub, r); int csize = PGeti("csize"); float s = Math.Max(sub.Dim(0), sub.Dim(1)) / (float)csize; if (PGetf("noupscale") > 0 && s < 1.0f) { s = 1.0f; } float sig = s * PGetf("aa"); float dx = (csize * s - sub.Dim(0)) / 2f; float dy = (csize * s - sub.Dim(1)) / 2f; if (sig > 1e-3f) { Gauss.Gauss2d(sub, sig, sig); } v.Resize(csize, csize); v.Fill(0f); for (int i = 0; i < csize; i++) { for (int j = 0; j < csize; j++) { float x = i * s - dx; float y = j * s - dy; if (x < 0 || x >= sub.Dim(0)) { continue; } if (y < 0 || y >= sub.Dim(1)) { continue; } float value = ImgOps.bilin(sub, x, y); v[i, j] = value; } } /*Global.Debugf("biggestcc", "{0} {1} ({2}) -> {3} {4} ({5})", * sub.Dim(0), sub.Dim(1), NarrayUtil.Max(sub), * v.Dim(0), v.Dim(1), NarrayUtil.Max(v));*/ }