public override void Charseg(ref Intarray outimage, Bytearray inimage) { int swidth = PGeti("swidth"); int sheight = PGeti("sheight"); Bytearray image = new Bytearray(); image.Copy(inimage); OcrRoutine.binarize_simple(image); OcrRoutine.Invert(image); outimage.Copy(image); if (swidth > 0 || sheight > 0) { Morph.binary_close_rect(image, swidth, sheight); } Intarray labels = new Intarray(); labels.Copy(image); ImgLabels.label_components(ref labels); for (int i = 0; i < outimage.Length1d(); i++) { if (outimage.At1d(i) > 0) { outimage.Put1d(i, SegmRoutine.cseg_pixel(labels.At1d(i))); } } SegmRoutine.make_line_segmentation_white(outimage); SegmRoutine.check_line_segmentation(outimage); }
protected void CorrectOutputsNull(int vertex) { if (m_outputs[vertex] == null) { m_outputs[vertex] = new Intarray(); } }
public static void write_image_packed(string path, Intarray image) { Bitmap bitmap = ImgRoutine.NarrayToRgbBitmap(image); bitmap.Save(path); bitmap.Dispose(); }
/// <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 bool a_star_in_composition(Intarray inputs, Intarray vertices1, Intarray vertices2, Intarray outputs, Floatarray costs, OcroFST fst1, OcroFST fst2) { CompositionFst composition = FstFactory.MakeCompositionFst(fst1, fst2); bool result; try { //Floatarray g1 = new Floatarray(); //Floatarray g2 = new Floatarray(); fst1.CalculateHeuristics(); fst2.CalculateHeuristics(); result = a_star2_internal(inputs, vertices1, vertices2, outputs, costs, fst1, fst2, fst1.Heuristics(), fst2.Heuristics(), composition); } catch (Exception ex) { composition.Move1(); composition.Move2(); throw ex; } composition.Move1(); composition.Move2(); return(result); }
public OutputVector() { _len = 0; _keys = new Intarray(); _values = new Floatarray(); _result = null; }
/// <summary> /// Randomly sample an FST, assuming any input. /// </summary> /// <param name="result">The array of output symbols, excluding epsilons.</param> /// <param name="fst">The FST.</param> /// <param name="max">The maximum length of the result.</param> /// <returns>total cost</returns> public static double fst_sample(Intarray result, IGenericFst fst, int max = 1000) { double total_cost = 0; int current = fst.GetStart(); for (int counter = 0; counter < max; counter++) { Intarray inputs = new Intarray(); Intarray outputs = new Intarray(); Intarray targets = new Intarray(); Floatarray costs = new Floatarray(); fst.Arcs(inputs, targets, outputs, costs, current); // now we need to deal with the costs uniformly, so: costs.Push(fst.GetAcceptCost(current)); int choice = sample_by_costs(costs); if (choice == costs.Length() - 1) { break; } result.Push(outputs[choice]); total_cost += costs[choice]; current = targets[choice]; } return(total_cost + fst.GetAcceptCost(current)); }
public void GetLineSegmentation(Intarray image, int page, int line, string variant = null) { string v = "rseg"; if (!String.IsNullOrEmpty(variant)) { v += "."; v += variant; } GetLine(image, page, line, v); SegmRoutine.make_line_segmentation_black(image); }
/// <summary> /// Copy one FST to another. /// </summary> /// <param name="dst">The destination. Will be cleared before copying.</param> /// <param name="src">The FST to copy.</param> public static void fst_copy(IGenericFst dst, IGenericFst src) { dst.Clear(); int n = src.nStates(); for (int i = 0; i < n; i++) { dst.NewState(); } dst.SetStart(src.GetStart()); for (int i = 0; i < n; i++) { dst.SetAccept(i, src.GetAcceptCost(i)); Intarray targets = new Intarray(), outputs = new Intarray(), inputs = new Intarray(); Floatarray costs = new Floatarray(); src.Arcs(inputs, targets, outputs, costs, i); int inlen = inputs.Length(); if (inlen != targets.Length()) { throw new Exception("ASSERT: inputs.length() == targets.length()"); } if (inlen != outputs.Length()) { throw new Exception("ASSERT: inputs.length() == outputs.length()"); } if (inlen != costs.Length()) { throw new Exception("ASSERT: inputs.length() == costs.length()"); } for (int j = 0; j < inputs.Length(); j++) { dst.AddTransition(i, targets.At1d(j), outputs.At1d(j), costs.At1d(j), inputs.At1d(j)); } } }
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 Bitmap read_image_packed(Intarray image, string path) { Bitmap bitmap = LoadBitmapFromFile(path); image.Resize(bitmap.Width, bitmap.Height); ImgRoutine.NarrayFromBitmap(image, bitmap); return bitmap; }
public static void check_approximately_sorted(Intarray labels) { for (int i = 0; i < labels.Length1d(); i++) { if (labels.At1d(i) > 100000) { throw new Exception("labels out of range"); } } Narray <Rect> rboxes = new Narray <Rect>(); ImgLabels.bounding_boxes(ref rboxes, labels); #if false // TODO/tmb disabling check until the overseg issue is fixed --tmb for (int i = 1; i < rboxes.Length(); i++) { if (rboxes[i].Right < rboxes[i - 1].Left) { /*errors_log("bad segmentation", labels); * errors_log.recolor("bad segmentation (recolored)", labels); * throw_fmt("boxes aren't approximately sorted: " * "box %d is to the left from box %d", i, i-1);*/ } } #endif }
public void InitData(IDataset ds, int nhidden, Intarray newc2i = null, Intarray newi2c = null) { CHECK_ARG(nhidden > 1 && nhidden < 1000000, "nhidden > 1 && nhidden < 1000000"); int ninput = ds.nFeatures(); int noutput = ds.nClasses(); w1.Resize(nhidden, ninput); b1.Resize(nhidden); w2.Resize(noutput, nhidden); b2.Resize(noutput); Intarray indexes = new Intarray(); NarrayUtil.RPermutation(indexes, ds.nSamples()); Floatarray v = new Floatarray(); for (int i = 0; i < w1.Dim(0); i++) { int row = indexes[i]; ds.Input1d(v, row); float normv = (float)NarrayUtil.Norm2(v); v /= normv * normv; NarrayRowUtil.RowPut(w1, i, v); } ClassifierUtil.fill_random(b1, -1e-6f, 1e-6f); ClassifierUtil.fill_random(w2, -1.0f / nhidden, 1.0f / nhidden); ClassifierUtil.fill_random(b2, -1e-6f, 1e-6f); if (newc2i != null) { c2i.Copy(newc2i); } if (newi2c != null) { i2c.Copy(newi2c); } }
public static bool Equals(Intarray a, Intarray b) { if (a.Length() != b.Length()) return false; for (int i = 0; i < a.Length(); i++) if (a.UnsafeAt1d(i) != b.UnsafeAt1d(i)) return false; return true; }
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); } }
protected override void Train(IDataset ds) { if (!(ds.nSamples() > 0)) { throw new Exception("nSamples of IDataset must be > 0"); } if (!(ds.nFeatures() > 0)) { throw new Exception("nFeatures of IDataset must be > 0"); } if (c2i.Length() < 1) { Intarray raw_classes = new Intarray(); raw_classes.ReserveTo(ds.nSamples()); for (int i = 0; i < ds.nSamples(); i++) { raw_classes.Push(ds.Cls(i)); } ClassMap(c2i, i2c, raw_classes); /*Intarray classes = new Intarray(); * ctranslate(classes, raw_classes, c2i);*/ //debugf("info","[mapped %d to %d classes]\n",c2i.length(),i2c.length()); } TranslatedDataset mds = new TranslatedDataset(ds, c2i); TrainDense(mds); }
public static bool a_star_in_composition(Intarray inputs, Intarray vertices1, Intarray vertices2, Intarray outputs, Floatarray costs, OcroFST fst1, OcroFST fst2) { CompositionFst composition = FstFactory.MakeCompositionFst(fst1, fst2); bool result; try { //Floatarray g1 = new Floatarray(); //Floatarray g2 = new Floatarray(); fst1.CalculateHeuristics(); fst2.CalculateHeuristics(); result = a_star2_internal(inputs, vertices1, vertices2, outputs, costs, fst1, fst2, fst1.Heuristics(), fst2.Heuristics(), composition); } catch (Exception ex) { composition.Move1(); composition.Move2(); throw ex; } composition.Move1(); composition.Move2(); return result; }
public void Image(string description, Intarray a, float zoom = 100f) { if (verbose) { writer.WriteLine(String.Format("image {0} w:{1}, h:{2}", description, a.Dim(0), a.Dim(1))); } }
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); }
Floatarray costs; // the cost of the node on the heap /// <summary> /// Constructor. /// Create a heap storing node indices from 0 to n - 1. /// </summary> public Heap(int n) { heap = new Intarray(); heapback = new Intarray(n); heapback.Fill(-1); costs = new Floatarray(); }
/// <summary> /// Return the segmentation-derived mask for the character. /// This may optionally be grown by some pixels. /// </summary> public override void GetMask(out Rect r, ref Bytearray outmask, int index, int grow) { r = boxes.At1d(index).Grow(grow); r.Intersect(new Rect(0, 0, labels.Dim(0), labels.Dim(1))); if (fullheight) { r.y0 = 0; r.y1 = labels.Dim(1); } int x = r.x0, y = r.y0, w = r.Width(), h = r.Height(); Intarray segs = segments.At1d(index); outmask.Resize(w, h); outmask.Fill(0); for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { int label = labels[x + i, y + j]; if (NarrayUtil.first_index_of(segs, label) >= 0) { outmask[i, j] = (byte)255; } } } if (grow > 0) { Morph.binary_dilate_circle(outmask, grow); } }
/// <summary> /// Train on a text line. /// <remarks>Usage is: call addTrainingLine with training data, then call finishTraining /// The state of the object is undefined between calling addTrainingLine and finishTraining, and it is /// an error to call recognizeLine before finishTraining completes. This allows both batch /// and incemental training. /// NB: you might train on length 1 strings for single character training /// and might train on words if line alignment is not working /// (well, for some training data)</remarks> /// </summary> public void AddTrainingLine(Intarray cseg, string tr) { Bytearray gimage = new Bytearray(); ClassifierUtil.segmentation_as_bitmap(gimage, cseg); AddTrainingLine(cseg, gimage, tr); }
public static bool a_star_in_composition(Intarray inputs, Intarray vertices1, Intarray vertices2, Intarray outputs, Floatarray costs, OcroFST fst1, Floatarray g1, OcroFST fst2, Floatarray g2) { CompositionFst composition = FstFactory.MakeCompositionFst(fst1, fst2); bool result; try { result = a_star2_internal(inputs, vertices1, vertices2, outputs, costs, fst1, fst2, g1, g2, composition); } catch (Exception ex) { composition.Move1(); composition.Move2(); throw ex; } composition.Move1(); composition.Move2(); return(result); }
public void Get(Intarray r_vertices1, Intarray r_vertices2, Intarray r_inputs, Intarray r_outputs, Floatarray r_costs, int id) { Intarray t_v1 = new Intarray(); // vertices Intarray t_v2 = new Intarray(); // vertices Intarray t_i = new Intarray(); // inputs Intarray t_o = new Intarray(); // outputs Floatarray t_c = new Floatarray(); // costs int current = id; while (current != -1) { t_v1.Push(v1[current]); t_v2.Push(v2[current]); t_i.Push(inputs[current]); t_o.Push(outputs[current]); t_c.Push(costs[current]); current = parents[current]; } NarrayUtil.Reverse(r_vertices1, t_v1); NarrayUtil.Reverse(r_vertices2, t_v2); NarrayUtil.Reverse(r_inputs, t_i); NarrayUtil.Reverse(r_outputs, t_o); NarrayUtil.Reverse(r_costs, t_c); }
public override void Charseg(ref Intarray result_segmentation, Bytearray orig_image) { Logger.Default.Image("segmenting", orig_image); int PADDING = 3; OcrRoutine.optional_check_background_is_lighter(orig_image); Bytearray image = new Bytearray(); Narray <byte> bimage = image; image.Copy(orig_image); OcrRoutine.binarize_simple(image); OcrRoutine.Invert(image); ImgOps.pad_by(ref bimage, PADDING, PADDING); // pass image to segmenter segmenter.SetImage(image); // find all cuts in the image segmenter.FindAllCuts(); // choose the best of all cuts segmenter.FindBestCuts(); Intarray segmentation = new Intarray(); segmentation.Resize(image.Dim(0), image.Dim(1)); for (int i = 0; i < image.Dim(0); i++) { for (int j = 0; j < image.Dim(1); j++) { segmentation[i, j] = image[i, j] > 0 ? 1 : 0; } } for (int r = 0; r < segmenter.bestcuts.Length(); r++) { int c = segmenter.bestcuts[r]; Narray <Point> cut = segmenter.cuts[c]; for (int y = 0; y < image.Dim(1); y++) { for (int x = cut[y].X; x < image.Dim(0); x++) { if (segmentation[x, y] > 0) { segmentation[x, y]++; } } } } ImgOps.extract_subimage(result_segmentation, segmentation, PADDING, PADDING, segmentation.Dim(0) - PADDING, segmentation.Dim(1) - PADDING); if (small_merge_threshold > 0) { SegmRoutine.line_segmentation_merge_small_components(ref result_segmentation, small_merge_threshold); SegmRoutine.line_segmentation_sort_x(result_segmentation); } SegmRoutine.make_line_segmentation_white(result_segmentation); // set_line_number(segmentation, 1); Logger.Default.Image("resulting segmentation", result_segmentation); }
protected virtual void GetLinesOfPage(Intarray lines, int ipage) { lines.Clear(); string dirName = String.Format("{0}{1}{2:0000}", prefix, Path.DirectorySeparatorChar, ipage); DirPattern dpattern = new DirPattern(dirName, @"([0-9][0-9][0-9][0-9])\.png"); if (dpattern.Length > 0) { lines.ReserveTo(dpattern.Length); } List <int> llist = new List <int>(dpattern.Length); for (int i = 0; i < dpattern.Length; i++) { int k = int.Parse(dpattern[i]); llist.Add(k); //lines.Push(k); } IEnumerable <int> query = llist.OrderBy(i => i); foreach (int iline in query) { lines.Push(iline); } }
/// <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)]); } }
public IBatchDense() { c2i = new Intarray(); i2c = new Intarray(); Persist(c2i, "c2i"); Persist(i2c, "i2c"); }
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)]); } }
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; } } } } } }
/// <summary> /// A valid line segmentation may contain 0 or 0xffffff as the /// background, and otherwise numbers components starting at 1. /// The segmentation consists of segmented background pixels /// (0x80xxxx) and segmented foreground pixels (0x00xxxx). The /// segmented foreground pixels should constitute a usable /// binarization of the original image. /// </summary> public static void check_line_segmentation(Intarray cseg) { if (cseg.Length1d() == 0) { return; } if (cseg.Rank() != 2) { throw new Exception("check_line_segmentation: rank must be 2"); } for (int i = 0; i < cseg.Length1d(); i++) { int value = cseg.At1d(i); if (value == 0) { continue; } if (value == 0xffffff) { continue; } if ((value & 0x800000) > 0) { if ((value & ~0x800000) > 100000) { throw new Exception("check_line_segmentation: (value & ~0x800000) > 100000"); } } else if (value > 100000) { throw new Exception("check_line_segmentation: value > 100000"); } } }
public void BestPath(Intarray v1, Intarray v2, Intarray inputs, Intarray outputs, Floatarray costs) { stree.Clear(); beam.Resize(1); beamcost.Resize(1); beam[0] = stree.Add(-1, fst1.GetStart(), fst2.GetStart(), 0, 0, 0); beamcost[0] = 0; best_so_far = 0; best_cost_so_far = fst1.GetAcceptCost(fst1.GetStart()) + fst2.GetAcceptCost(fst1.GetStart()); while (beam.Length() > 0) { Radiate(); } stree.Get(v1, v2, inputs, outputs, costs, best_so_far); costs.Push(fst1.GetAcceptCost(stree.v1[best_so_far]) + fst2.GetAcceptCost(stree.v2[best_so_far])); //logger("costs", costs); }
public override void Arcs(Intarray out_inputs, Intarray out_targets, Intarray out_outputs, Floatarray out_costs, int from) { out_inputs.Copy(m_inputs[from]); out_targets.Copy(m_targets[from]); out_outputs.Copy(m_outputs[from]); out_costs.Copy(m_costs[from]); }
internal static bool a_star2_internal(Intarray inputs, Intarray vertices1, Intarray vertices2, Intarray outputs, Floatarray costs, IGenericFst fst1, IGenericFst fst2, Floatarray g1, Floatarray g2, CompositionFst composition) { Intarray vertices = new Intarray(); AStarCompositionSearch a = new AStarCompositionSearch(g1, g2, composition); if (!a.Loop()) { return(false); } if (!a.reconstruct_vertices(vertices)) { return(false); } a.reconstruct_edges(inputs, outputs, costs, vertices); composition.SplitIndices(vertices1, vertices2, vertices); return(true); }
Intarray heapback; // heap[heapback[node]] == node; -1 if not in the heap #endregion Fields #region Constructors /// <summary> /// Constructor. /// Create a heap storing node indices from 0 to n - 1. /// </summary> public Heap(int n) { heap = new Intarray(); heapback = new Intarray(n); heapback.Fill(-1); costs = new Floatarray(); }
protected void CorrectTargetsNull(int vertex) { if (m_targets[vertex] == null) { m_targets[vertex] = new Intarray(); } }
public Linerec(string classifier1 = "latin"/*none*/, string extractor1 = "scaledfe", string segmenter1 = "DpSegmenter", int use_reject = 1) { transcript = ""; //line = new Bytearray(); segmentation = new Intarray(); binarized = new Bytearray(); // component choices PDef("classifier", classifier1, "character classifier"); PDef("extractor", extractor1, "feature extractor"); PDef("segmenter", segmenter1, "line segmenter"); PDef("grouper", "SimpleGrouper", "line grouper"); // retraining PDef("cpreload", "none", "classifier to be loaded prior to training"); // debugging PDef("verbose", 0, "verbose output from glinerec"); // outputs PDef("use_priors", 0, "correct the classifier output by priors"); PDef("use_reject", use_reject, "use a reject class (use posteriors only and train on junk chars)"); PDef("maxcost", 20.0, "maximum cost of a character to be added to the output"); PDef("minclass", 32, "minimum output class to be added (default=unicode space)"); PDef("minprob", 1e-9, "minimum probability for a character to appear in the output at all"); PDef("invert", 1, "invert the input line prior to char extraction"); // segmentation PDef("maxrange", 5, "maximum number of components that are grouped together"); // sanity limits on input PDef("minheight", 9, "minimum height of input line"); PDef("maxheight", 300, "maximum height of input line"); PDef("maxaspect", 2.0, "maximum height/width ratio of input line"); // space estimation (FIXME factor this out eventually) PDef("space_fractile", 0.5, "fractile for space estimation"); PDef("space_multiplier", 2.0, "multipler for space estimation"); PDef("space_min", 0.2, "minimum space threshold (in xheight)"); PDef("space_max", 1.1, "maximum space threshold (in xheight)"); PDef("space_yes", 1.0, "cost of inserting a space"); PDef("space_no", 5.0, "cost of not inserting a space"); // back compability PDef("minsize_factor", 0.0, ""); counts = new Intarray(); segmenter = new ComponentContainerISegmentLine(ComponentCreator.MakeComponent<ISegmentLine>(PGet("segmenter"))); grouper = new ComponentContainerIGrouper(ComponentCreator.MakeComponent<IGrouper>(PGet("grouper"))); classifier = new ComponentContainerIModel(IModel.MakeModel(PGet("classifier"))); TryAttachClassifierEvent(classifier.Object); Persist(classifier, "classifier"); Persist(counts, "counts"); Persist(segmenter, "segmenter"); Persist(grouper, "grouper"); if (!classifier.IsEmpty) { classifier.Object.Set("junk", PGeti("use_reject")); classifier.Object.SetExtractor(PGet("extractor")); } ntrained = 0; counts_warned = false; }
public void TestSimple() { Global.SetEnv("debug", Global.GetEnv("debug") + ""); // image file name to recognize string imgFileName = "line.png"; string imgCsegFileName = "line.cseg.png"; string imgTranscriptFileName = "line.txt"; // line recognizer Linerec lrec = (Linerec)Linerec.LoadLinerec("default.model"); //Linerec lrec = (Linerec)Linerec.LoadLinerec("2m2-reject.cmodel"); //Linerec lrec = (Linerec)Linerec.LoadLinerec("multi3.cmodel"); //Linerec lrec = (Linerec)Linerec.LoadLinerec("latin-ascii.model"); lrec.Info(); // language model OcroFST default_lmodel = OcroFST.MakeOcroFst(); default_lmodel.Load("default.fst"); OcroFST lmodel = default_lmodel; // read image Bytearray image = new Bytearray(1, 1); ImgIo.read_image_gray(image, imgFileName); // recognize! OcroFST fst = OcroFST.MakeOcroFst(); Intarray rseg = new Intarray(); lrec.RecognizeLine(rseg, fst, image); // show result 1 string resStr; fst.BestPath(out resStr); Console.WriteLine("Fst BestPath: {0}", resStr); // find result 2 Intarray v1 = new Intarray(); Intarray v2 = new Intarray(); Intarray inp = new Intarray(); Intarray outp = new Intarray(); Floatarray c = new Floatarray(); BeamSearch.beam_search(v1, v2, inp, outp, c, fst, lmodel, 100); FstUtil.remove_epsilons(out resStr, outp); Console.WriteLine("Fst BeamSearch: {0}", resStr); Intarray cseg = new Intarray(); SegmRoutine.rseg_to_cseg(cseg, rseg, inp); SegmRoutine.make_line_segmentation_white(cseg); ImgLabels.simple_recolor(cseg); // for human readable ImgIo.write_image_packed(imgCsegFileName, cseg); File.WriteAllText(imgTranscriptFileName, resStr.Replace(" ", "")); }
/// <summary> /// Return an array of arcs leading from the given node. /// WARN_DEPRECATED /// </summary> public virtual void Arcs(Intarray ids, Intarray targets, Intarray outputs, Floatarray costs, int from) { throw new NotImplementedException("IGenericFst:Arcs: unimplemented"); }
public RowDataset8() { DatatypeSize = sizeof(byte); // one byte data = new ObjList<Narray<byte>>(); classes = new Intarray(); nc = -1; nf = -1; }
public Dataset8() { DatatypeSize = sizeof(sbyte); // one byte data = new Narray<sbyte>(); classes = new Intarray(); nc = -1; nf = -1; }
public void GetPageSegmentation(Intarray image, int page, string variant = null) { string v = "pseg"; if (!String.IsNullOrEmpty(variant)) { v += "."; v += variant; } GetPage(image, page, v); //SegmRoutine.check_page_segmentation(image); // dublicate! SegmRoutine.make_page_segmentation_black(image); }
public List<List<float>> SpaceCosts(List<Candidate> candidates, Bytearray image) { /* Given a list of character recognition candidates and their classifications, and an image of the corresponding text line, compute a list of pairs of costs for putting/not putting a space after each of the candidate characters. The basic idea behind this simple algorithm is to try larger and larger horizontal closing operations until most of the components start having a "wide" aspect ratio; that's when characters have merged into words. The remaining whitespace should be spaces. This is just a simple stopgap measure; it will be replaced with trainable space modeling. */ int w = image.Dim(0); int h = image.Dim(1); Bytearray closed = new Bytearray(); int r; for (r = 0; r < maxrange; r++) { if (r > 0) { closed.Copy(image); Morph.binary_close_circle(closed, r); } else closed.Copy(image); Intarray labeled = new Intarray(); labeled.Copy(closed); ImgLabels.label_components(ref labeled); Narray<Rect> rects = new Narray<Rect>(); ImgLabels.bounding_boxes(ref rects, labeled); Floatarray aspects = new Floatarray(); for (int i = 0; i < rects.Length(); i++) { Rect rect = rects[i]; float aspect = rect.Aspect(); aspects.Push(aspect); } float maspect = NarrayUtil.Median(aspects); if (maspect >= this.aspect_threshold) break; } // close with a little bit of extra space closed.Copy(image); Morph.binary_close_circle(closed, r+1); // compute the remaining aps //Morph.binary_dilate_circle(); // every character box that ends near a cap gets a space appended return null; }
public Intarray v2; // vertices from FST 2 #endregion Fields #region Constructors public SearchTree() { parents = new Intarray(); inputs = new Intarray(); outputs = new Intarray(); v1 = new Intarray(); v2 = new Intarray(); costs = new Floatarray(); }
public RowDataset8(Narray<byte> ds, Intarray cs) : this() { for (int i = 0; i < ds.Dim(0); i++) { RowGet(data.Push(new Narray<byte>()), ds, i); classes.Push(cs[i]); } Recompute(); }
public RowDataset8(int nsamples) { DatatypeSize = sizeof(byte); // one byte data = new ObjList<Narray<byte>>(); data.ReserveTo(nsamples); classes = new Intarray(); classes.ReserveTo(nsamples); nc = -1; nf = -1; }
public TestDataset() { classes = new int[sClasses.Length]; aclasses = new Intarray(sClasses.Length); for (int i = 0; i < sClasses.Length; i++) { classes[i] = (int)sClasses[i]; aclasses.Put1d(i, classes[i]); } }
/// <summary> /// constructor for a NBest data structure of size n /// </summary> public PriorityQueue(int n) { this.n = n; ids = new Intarray(); tags = new Intarray(); values = new Floatarray(); ids.Resize(n + 1); tags.Resize(n + 1); values.Resize(n + 1); Clear(); }
public static double a_star(out string result, OcroFST fst) { result = ""; Intarray inputs = new Intarray(); Intarray vertices = new Intarray(); Intarray outputs = new Intarray(); Floatarray costs = new Floatarray(); if (!a_star(inputs, vertices, outputs, costs, fst)) return 1e38; FstUtil.remove_epsilons(out result, outputs); return NarrayUtil.Sum(costs); }
public CurvedCutSegmenterImpl() { wimage = new Intarray(); costs = new Intarray(); sources = new Intarray(); bestcuts = new Intarray(); dimage = new Intarray(); cuts = new Narray<Narray<Point>>(); cutcosts = new Floatarray(); //params_for_chars(); params_for_lines(); //params_from_hwrec_c(); }
public static double a_star(out string result, OcroFST fst1, OcroFST fst2) { result = ""; Intarray inputs = new Intarray(); Intarray v1 = new Intarray(); Intarray v2 = new Intarray(); Intarray outputs = new Intarray(); Floatarray costs = new Floatarray(); if (!a_star_in_composition(inputs, v1, v2, outputs, costs, fst1, fst2)) return 1e38; FstUtil.remove_epsilons(out result, outputs); return NarrayUtil.Sum(costs); }
public override int AddLineId(int ipage, int iline) { if (lines.Length() <= ipage) { lines.Resize(ipage + 1); for (int i = 0; i < lines.Length(); i++) { if (lines[i] == null) lines[i] = new Intarray(); } } lines[ipage].Push(iline); return lines[ipage].Length() - 1; }
public static double beam_search(out string result, OcroFST fst1, OcroFST fst2, int beam_width) { Intarray v1 = new Intarray(); Intarray v2 = new Intarray(); Intarray i = new Intarray(); Intarray o = new Intarray(); Floatarray c = new Floatarray(); //fprintf(stderr,"starting beam search\n"); beam_search(v1, v2, i, o, c, fst1, fst2, beam_width); //fprintf(stderr,"finished beam search\n"); FstUtil.remove_epsilons(out result, o); return NarrayUtil.Sum(c); }
public override void Charseg(ref Intarray result_segmentation, Bytearray orig_image) { Logger.Default.Image("segmenting", orig_image); int PADDING = 3; OcrRoutine.optional_check_background_is_lighter(orig_image); Bytearray image = new Bytearray(); Narray<byte> bimage = image; image.Copy(orig_image); OcrRoutine.binarize_simple(image); OcrRoutine.Invert(image); ImgOps.pad_by(ref bimage, PADDING, PADDING); // pass image to segmenter segmenter.SetImage(image); // find all cuts in the image segmenter.FindAllCuts(); // choose the best of all cuts segmenter.FindBestCuts(); Intarray segmentation = new Intarray(); segmentation.Resize(image.Dim(0), image.Dim(1)); for (int i = 0; i < image.Dim(0); i++) for (int j = 0; j < image.Dim(1); j++) segmentation[i, j] = image[i, j] > 0 ? 1 : 0; for (int r = 0; r < segmenter.bestcuts.Length(); r++) { int c = segmenter.bestcuts[r]; Narray<Point> cut = segmenter.cuts[c]; for (int y = 0; y < image.Dim(1); y++) { for (int x = cut[y].X; x < image.Dim(0); x++) { if (segmentation[x, y] > 0) segmentation[x, y]++; } } } ImgOps.extract_subimage(result_segmentation, segmentation, PADDING, PADDING, segmentation.Dim(0) - PADDING, segmentation.Dim(1) - PADDING); if (small_merge_threshold > 0) { SegmRoutine.line_segmentation_merge_small_components(ref result_segmentation, small_merge_threshold); SegmRoutine.line_segmentation_sort_x(result_segmentation); } SegmRoutine.make_line_segmentation_white(result_segmentation); // set_line_number(segmentation, 1); Logger.Default.Image("resulting segmentation", result_segmentation); }
protected override void GetLinesOfPage(Intarray lines, int ipage) { lines.Clear(); string dirName = String.Format("{0}{1}{2:0000}", prefix, Path.DirectorySeparatorChar, ipage); //DirPattern dpattern = new DirPattern(dirName, @"([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])\.png"); DirPattern dpattern = new DirPattern(dirName, @"([0-9][0-9][0-9][0-9][0-9][0-9])\.png"); if (dpattern.Length > 0) lines.ReserveTo(dpattern.Length); for (int i = 0; i < dpattern.Length; i++) { int k = int.Parse(dpattern[i]); lines.Push(k); } }
public static bool a_star(Intarray inputs, Intarray vertices, Intarray outputs, Floatarray costs, OcroFST fst) { AStarSearch a = new AStarSearch(fst); if (!a.Loop()) return false; if (!a.reconstruct_vertices(vertices)) return false; a.reconstruct_edges(inputs, outputs, costs, vertices); return true; }