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 override bool GetCosts(Floatarray costs, int page, int line, string variant = null) { costs.Clear(); costs.Resize(10000); costs.Fill(1e38f); if (!File.Exists(PathFile(page, line, variant, "costs"))) return false; FileStream fs = null; try { fs = Open(FileMode.Open, page, line, variant, "costs"); StreamReader reader = new StreamReader(fs); int index; float cost; while (!reader.EndOfStream) { string sline = reader.ReadLine(); string[] parts = sline.Split(new char[] { ' ' }, 2); if (parts.Length == 2 && int.TryParse(parts[0], out index) && float.TryParse(parts[1], out cost)) costs[index] = cost; } reader.Close(); fs.Close(); } catch (FileNotFoundException e) { return false; } catch (Exception e) { if (fs != null) fs.Close(); return false; } return true; }
public static void local_min(ref Floatarray result, Floatarray data, int r) { int n = data.Length(); result.Resize(n); for (int i = 0; i < n; i++) { float lmin = data[i]; for (int j = -r; j <= r; j++) { int k = i + j; unchecked { if ((uint)(k) >= (uint)(n)) { continue; } } if (data[k] >= lmin) { continue; } lmin = data[k]; } result[i] = lmin; } }
protected void rescale(Floatarray outv, Floatarray sub) { if (sub.Rank() != 2) throw new Exception("CHECK_ARG: sub.Rank()==2"); int csize = PGeti("csize"); int indent = PGeti("indent"); float s = Math.Max(sub.Dim(0), sub.Dim(1)) / (float)(csize - indent - indent); if (PGeti("noupscale") > 0 && s < 1.0f) s = 1.0f; float sig = s * PGetf("aa"); float dx = (csize * s - sub.Dim(0)) / 2; float dy = (csize * s - sub.Dim(1)) / 2; if (sig > 1e-3f) Gauss.Gauss2d(sub, sig, sig); outv.Resize(csize, csize); outv.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); outv[i, j] = value; } } /*Global.Debugf("fe", "{0} {1} ({2}) -> {3} {4} ({5})\n", sub.Dim(0), sub.Dim(1), NarrayUtil.Max(sub), outv.Dim(0), outv.Dim(1), NarrayUtil.Max(outv));*/ }
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 Input(Floatarray v, int i) { v.Resize(data.Dim(1)); for (int j = 0; j < v.Dim(0); j++) { v.UnsafePut1d(j, data[i, j]); } }
public static void getd1(Floatarray image, Floatarray slice, int index) { slice.Resize(image.Dim(0)); for (int i = 0; i < image.Dim(0); i++) { slice.UnsafePut(i, image.UnsafeAt(i, index)); } }
public override void ClearLattice() { class_costs.Dealloc(); class_costs.Resize(boxes.Length()); class_outputs.Dealloc(); class_outputs.Resize(boxes.Length()); spaces.Resize(boxes.Length(), 2); spaces.Fill(float.PositiveInfinity); }
public void SetImage(Bytearray image_) { Bytearray image = new Bytearray(); //image = image_; image.Copy(image_); dimage.Copy(image); if (PGeti("fill_holes") > 0) { Bytearray holes = new Bytearray(); SegmRoutine.extract_holes(ref holes, image); for (int i = 0; i < image.Length(); i++) { if (holes.At1d(i) > 0) { image.Put1d(i, 255); } } } int w = image.Dim(0), h = image.Dim(1); wimage.Resize(w, h); wimage.Fill(0); float s1 = 0.0f, sy = 0.0f; for (int i = 1; i < w; i++) { for (int j = 0; j < h; j++) { if (image[i, j] > 0) { s1++; sy += j; } if (image[i, j] > 0) { wimage[i, j] = inside_weight; } else { wimage[i, j] = outside_weight; } } } if (s1 == 0) { where = image.Dim(1) / 2; } else { where = (int)(sy / s1); } for (int i = 0; i < dimage.Dim(0); i++) { dimage[i, where] = 0x008000; } }
public void Init(int n = 0) { _keys.Resize(n); for (int i = 0; i < n; i++) { _keys.Put1d(i, i); } _values.Resize(n); _values.Fill <float>(0.0f); }
/// <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 Floatarray AsArray() { Floatarray result = new Floatarray(); result.Resize(Length()); result.Fill(0f); for (int i = 0; i < _keys.Length(); i++) { result.UnsafePut1d(_keys.UnsafeAt1d(i), _values.UnsafeAt1d(i)); } return(result); }
/// <summary> /// SGI compiler bug: can't make this a template function with /// an unused last argument for the template parameter /// </summary> public static void Go(Metric m, ref Floatarray distance, ref Narray<Point> source, float maxdist) { const float BIG = 1e38f; int w = distance.Dim(0); int h = distance.Dim(1); distance.Resize(w,h); source.Resize(w,h); Queue<Point> queue = new Queue<Point>(w*h); int i, j; for(i = 0; i < w; i++) for(j = 0; j < h; j++) { if(distance.At(i, j) > 0) { queue.Enqueue(new Point(i, j)); distance[i, j] = 0; source[i, j] = new Point(i, j); } else { distance[i, j] = BIG; source[i, j] = new Point(-1, -1); } } while(queue.Count != 0) { Point q = queue.Dequeue(); float d = m.metric(new Point(q.X - 1, q.Y), source.At(q.X, q.Y)); if(d <= maxdist && q.X > 0 && d < distance.At(q.X - 1, q.Y)) { queue.Enqueue(new Point(q.X - 1, q.Y)); source[q.X - 1, q.Y] = source.At(q.X, q.Y); distance[q.X - 1, q.Y] = d; } d = m.metric(new Point(q.X, q.Y - 1), source.At(q.X, q.Y)); if(d <= maxdist && q.Y > 0 && d < distance.At(q.X, q.Y - 1)) { queue.Enqueue(new Point(q.X, q.Y - 1)); source[q.X, q.Y - 1] = source.At(q.X, q.Y); distance[q.X, q.Y - 1] = d; } d = m.metric(new Point(q.X + 1, q.Y), source.At(q.X, q.Y)); if(d <= maxdist && q.X < w - 1 && d < distance.At(q.X + 1, q.Y)) { queue.Enqueue(new Point(q.X + 1, q.Y)); source[q.X + 1, q.Y] = source.At(q.X, q.Y); distance[q.X + 1, q.Y] = d; } d = m.metric(new Point(q.X, q.Y + 1), source.At(q.X, q.Y)); if(d <= maxdist && q.Y < h - 1 && d < distance.At(q.X, q.Y + 1)) { queue.Enqueue(new Point(q.X, q.Y + 1)); source[q.X, q.Y + 1] = source.At(q.X, q.Y); distance[q.X, q.Y + 1] = d; } } }
protected void rescale(Floatarray outv, Floatarray sub) { if (sub.Rank() != 2) { throw new Exception("CHECK_ARG: sub.Rank()==2"); } int csize = PGeti("csize"); int indent = PGeti("indent"); float s = Math.Max(sub.Dim(0), sub.Dim(1)) / (float)(csize - indent - indent); if (PGeti("noupscale") > 0 && s < 1.0f) { s = 1.0f; } float sig = s * PGetf("aa"); float dx = (csize * s - sub.Dim(0)) / 2; float dy = (csize * s - sub.Dim(1)) / 2; if (sig > 1e-3f) { Gauss.Gauss2d(sub, sig, sig); } outv.Resize(csize, csize); outv.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); outv[i, j] = value; } } /*Global.Debugf("fe", "{0} {1} ({2}) -> {3} {4} ({5})\n", * sub.Dim(0), sub.Dim(1), NarrayUtil.Max(sub), * outv.Dim(0), outv.Dim(1), NarrayUtil.Max(outv));*/ }
public static void Gauss1d(Floatarray outa, Floatarray ina, float sigma) { outa.Resize(ina.Dim(0)); // make a normalized mask int range = 1 + (int)(3.0 * sigma); Floatarray mask = new Floatarray(2 * range + 1); for (int i = 0; i <= range; i++) { float y = (float)Math.Exp(-i * i / 2.0 / sigma / sigma); mask[range + i] = mask[range - i] = y; } float total = 0.0f; for (int i = 0; i < mask.Dim(0); i++) { total += mask[i]; } for (int i = 0; i < mask.Dim(0); i++) { mask[i] /= total; } // apply it int n = ina.Length(); for (int i = 0; i < n; i++) { total = 0.0f; for (int j = 0; j < mask.Dim(0); j++) { int index = i + j - range; if (index < 0) { index = 0; } if (index >= n) { index = n - 1; } total += ina[index] * mask[j]; // it's symmetric } outa[i] = total; } }
public static void scale_to(Floatarray v, Floatarray sub, int csize, float noupscale = 1.0f, float aa = 1.0f) { // compute the scale factor float s = Math.Max(sub.Dim(0), sub.Dim(1)) / (float)csize; // don't upscale if that's prohibited if (s < noupscale) { s = 1.0f; } // compute the offset to keep the input centered in the output float dx = (csize * s - sub.Dim(0)) / 2; float dy = (csize * s - sub.Dim(1)) / 2; // antialiasing via Gaussian convolution float sig = s * aa; if (sig > 1e-3f) { Gauss.Gauss2d(sub, sig, sig); } // now compute the output image via bilinear interpolation 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; } } }
public void reconstruct_edges(Intarray inputs, Intarray outputs, Floatarray costs, Intarray vertices) { int n = vertices.Length(); inputs.Resize(n); outputs.Resize(n); costs.Resize(n); for (int i = 0; i < n - 1; i++) { int source = vertices[i]; int target = vertices[i + 1]; Intarray out_ins = new Intarray(); Intarray out_targets = new Intarray(); Intarray out_outs = new Intarray(); Floatarray out_costs = new Floatarray(); fst.Arcs(out_ins, out_targets, out_outs, out_costs, source); costs[i] = 1e38f; // find the best arc for (int j = 0; j < out_targets.Length(); j++) { if (out_targets[j] != target) { continue; } if (out_costs[j] < costs[i]) { inputs[i] = out_ins[j]; outputs[i] = out_outs[j]; costs[i] = out_costs[j]; } } } inputs[n - 1] = 0; outputs[n - 1] = 0; costs[n - 1] = fst.GetAcceptCost(vertices[n - 1]); }
public override bool GetCosts(Floatarray costs, int page, int line, string variant = null) { costs.Clear(); costs.Resize(10000); costs.Fill(1e38f); if (!File.Exists(PathFile(page, line, variant, "costs"))) { return(false); } FileStream fs = null; try { fs = Open(FileMode.Open, page, line, variant, "costs"); StreamReader reader = new StreamReader(fs); int index; float cost; while (!reader.EndOfStream) { string sline = reader.ReadLine(); string[] parts = sline.Split(new char[] { ' ' }, 2); if (parts.Length == 2 && int.TryParse(parts[0], out index) && float.TryParse(parts[1], out cost)) { costs[index] = cost; } } reader.Close(); fs.Close(); } catch (FileNotFoundException e) { return(false); } catch (Exception e) { if (fs != null) { fs.Close(); } return(false); } return(true); }
protected static void vmmul0(Floatarray result, Floatarray v, Floatarray a) { int n = a.Dim(0); int m = a.Dim(1); CHECK_ARG(n == v.Length(), "n == v.Length()"); result.Resize(m); result.Fill(0f); for (int i = 0; i < n; i++) { float value = v.UnsafeAt(i);//v[i]; if (value == 0f) { continue; } for (int j = 0; j < m; j++) { result.UnsafePut(j, result.UnsafeAt(j) + (a.UnsafeAt(i, j) * value)); } } }
public void EstimateSpaceSize() { Intarray labels = new Intarray(); labels.Copy(segmentation); ImgLabels.label_components(ref labels); Narray <Rect> boxes = new Narray <Rect>(); ImgLabels.bounding_boxes(ref boxes, labels); Floatarray distances = new Floatarray(); distances.Resize(boxes.Length()); distances.Fill(99999f); for (int i = 1; i < boxes.Length(); i++) { Rect b = boxes[i]; for (int j = 1; j < boxes.Length(); j++) { Rect n = boxes[j]; int delta = n.x0 - b.x1; if (delta < 0) { continue; } if (delta >= distances[i]) { continue; } distances[i] = delta; } } float interchar = NarrayUtil.Fractile(distances, PGetf("space_fractile")); space_threshold = interchar * PGetf("space_multiplier"); // impose some reasonable upper and lower bounds float xheight = 10.0f; // FIXME space_threshold = Math.Max(space_threshold, PGetf("space_min") * xheight); space_threshold = Math.Min(space_threshold, PGetf("space_max") * xheight); }
public static void remove_dontcares(ref Intarray image) { Floatarray dist = new Floatarray(); Narray <Point> source = new Narray <Point>(); dist.Resize(image.Dim(0), image.Dim(1)); for (int i = 0; i < dist.Length1d(); i++) { if (!dontcare(image.At1d(i))) { dist.Put1d(i, (image.At1d(i) > 0 ? 1 : 0)); } } BrushFire.brushfire_2(ref dist, ref source, 1000000); for (int i = 0; i < dist.Length1d(); i++) { Point p = source.At1d(i); if (dontcare(image.At1d(i))) { image.Put1d(i, image[p.X, p.Y]); } } }
public void reconstruct_edges(Intarray inputs, Intarray outputs, Floatarray costs, Intarray vertices) { int n = vertices.Length(); inputs.Resize(n); outputs.Resize(n); costs.Resize(n); for (int i = 0; i < n - 1; i++) { int source = vertices[i]; int target = vertices[i + 1]; Intarray out_ins = new Intarray(); Intarray out_targets = new Intarray(); Intarray out_outs = new Intarray(); Floatarray out_costs = new Floatarray(); fst.Arcs(out_ins, out_targets, out_outs, out_costs, source); costs[i] = 1e38f; // find the best arc for (int j = 0; j < out_targets.Length(); j++) { if (out_targets[j] != target) continue; if (out_costs[j] < costs[i]) { inputs[i] = out_ins[j]; outputs[i] = out_outs[j]; costs[i] = out_costs[j]; } } } inputs[n - 1] = 0; outputs[n - 1] = 0; costs[n - 1] = fst.GetAcceptCost(vertices[n - 1]); }
public override void Input(Floatarray v, int i) { v.Resize(data.Dim(1)); for (int j = 0; j < v.Dim(0); j++) v.UnsafePut1d(j, data[i, j]); }
public override void Extract(Narray<Floatarray> outarrays, Floatarray inarray) { outarrays.Clear(); Floatarray input = new Floatarray(); input.Copy(inarray); int w = input.Dim(0), h = input.Dim(1); Floatarray a = new Floatarray(); // working array int csize = PGeti("csize"); // get rid of small components SegmRoutine.erase_small_components(input, PGetf("minsize"), PGetf("threshold")); // compute a thresholded version for morphological operations Bytearray thresholded = new Bytearray(); OcrRoutine.threshold_frac(thresholded, input, PGetf("threshold")); // compute a smoothed version of the input for gradient computations float sigma = PGetf("gradsigma"); Floatarray smoothed = new Floatarray(); smoothed.Copy(input); Gauss.Gauss2d(smoothed, sigma, sigma); // x gradient a.Resize(w, h); for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { float delta; if (i == 0) delta = 0f; else delta = smoothed[i, j] - smoothed[i - 1, j]; a[i, j] = delta; } } Floatarray xgrad = outarrays.Push(new Floatarray()); OcrRoutine.scale_to(xgrad, a, csize, PGetf("noupscale"), PGetf("aa")); for (int j = 0; j < csize; j++) { for (int i = 0; i < csize; i++) { if (j % 2 == 0) xgrad[i, j] = Math.Max(xgrad[i, j], 0f); else xgrad[i, j] = Math.Min(xgrad[i, j], 0f); } } // y gradient a.Resize(w, h); for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { float delta; if (j == 0) delta = 0f; else delta = smoothed[i, j] - smoothed[i, j - 1]; a[i, j] = delta; } } Floatarray ygrad = outarrays.Push(new Floatarray()); OcrRoutine.scale_to(ygrad, a, csize, PGetf("noupscale"), PGetf("aa")); for (int i = 0; i < csize; i++) { for (int j = 0; j < csize; j++) { if (i % 2 == 0) ygrad[i, j] = Math.Max(ygrad[i, j], 0f); else ygrad[i, j] = Math.Min(ygrad[i, j], 0f); } } // junctions, endpoints, and holes Floatarray junctions = new Floatarray(); Floatarray endpoints = new Floatarray(); Floatarray holes = new Floatarray(); Bytearray junctions1 = new Bytearray(); Bytearray endpoints1 = new Bytearray(); Bytearray holes1 = new Bytearray(); Bytearray dilated = new Bytearray(); Bytearray binary = new Bytearray(); junctions.MakeLike(input, 0f); endpoints.MakeLike(input, 0f); holes.MakeLike(input, 0f); int n = PGeti("n"); float step = PGetf("step"); int bs = PGeti("binsmooth"); for(int i=0; i<n; i++) { sigma = step * i; if(bs > 0) OcrRoutine.binsmooth(binary, input, sigma); else { binary.Copy(thresholded); Morph.binary_dilate_circle(binary, (int)(sigma)); } OcrRoutine.skeletal_features(endpoints1, junctions1, binary, 0.0f, 0.0f); NarrayUtil.Greater(junctions1, (byte)0, (byte)0, (byte)1); junctions.Copy(junctions1); NarrayUtil.Greater(endpoints1, (byte)0, (byte)0, (byte)1); endpoints.Copy(endpoints1); SegmRoutine.extract_holes(ref holes1, binary); NarrayUtil.Greater(holes1, (byte)0, (byte)0, (byte)1); holes.Copy(holes1); } junctions *= 1.0f / (float)n; endpoints *= 1.0f / (float)n; holes *= 1.0f / (float)n; OcrRoutine.scale_to(outarrays.Push(new Floatarray()), junctions, csize, PGetf("noupscale"), PGetf("aa")); OcrRoutine.scale_to(outarrays.Push(new Floatarray()), endpoints, csize, PGetf("noupscale"), PGetf("aa")); OcrRoutine.scale_to(outarrays.Push(new Floatarray()), holes, csize, PGetf("noupscale"), PGetf("aa")); }
public override void FindAllCuts() { int w = wimage.Dim(0), h = wimage.Dim(1); // initialize dimensions of cuts, costs etc cuts.Resize(w); cutcosts.Resize(w); costs.Resize(w, h); sources.Resize(w, h); costs.Fill(1000000000); for (int i = 0; i < w; i++) { costs[i, 0] = 0; } sources.Fill(-1); limit = where; direction = 1; Step(0, w, 0); for (int x = 0; x < w; x++) { cutcosts[x] = costs[x, where]; cuts[x] = new Narray <Point>(); cuts[x].Clear(); // bottom should probably be initialized with 2*where instead of // h, because where cannot be assumed to be h/2. In the most extreme // case, the cut could go through 2 pixels in each row Narray <Point> bottom = new Narray <Point>(); int i = x, j = where; while (j >= 0) { bottom.Push(new Point(i, j)); i = sources[i, j]; j--; } //cuts(x).resize(h); for (i = bottom.Length() - 1; i >= 0; i--) { cuts[x].Push(bottom[i]); } } costs.Fill(1000000000); for (int i = 0; i < w; i++) { costs[i, h - 1] = 0; } sources.Fill(-1); limit = where; direction = -1; Step(0, w, h - 1); for (int x = 0; x < w; x++) { cutcosts[x] += costs[x, where]; // top should probably be initialized with 2*(h-where) instead of // h, because where cannot be assumed to be h/2. In the most extreme // case, the cut could go through 2 pixels in each row Narray <Point> top = new Narray <Point>(); int i = x, j = where; while (j < h) { if (j > where) { top.Push(new Point(i, j)); } i = sources[i, j]; j++; } for (i = 0; i < top.Length(); i++) { cuts[x].Push(top[i]); } } // add costs for line "where" for (int x = 0; x < w; x++) { cutcosts[x] += wimage[x, where]; } }
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));*/ }
public static void remove_dontcares(ref Intarray image) { Floatarray dist = new Floatarray(); Narray<Point> source = new Narray<Point>(); dist.Resize(image.Dim(0), image.Dim(1)); for (int i = 0; i < dist.Length1d(); i++) if (!dontcare(image.At1d(i))) dist.Put1d(i, (image.At1d(i) > 0 ? 1 : 0)); BrushFire.brushfire_2(ref dist, ref source, 1000000); for (int i = 0; i < dist.Length1d(); i++) { Point p = source.At1d(i); if (dontcare(image.At1d(i))) image.Put1d(i, image[p.X, p.Y]); } }
public Floatarray ToFloatarray() { Floatarray fa = new Floatarray(); fa.Resize(Width, Height); int yput; for (int y = 0; y < Height; y++) { yput = Height - y - 1; for (int x = 0; x < Width; x++) fa.Put(x, yput, Convert.ToSingle(Get(y, x) / 255.0f)); } return fa; }
/// <summary> /// SGI compiler bug: can't make this a template function with /// an unused last argument for the template parameter /// </summary> public static void Go(Metric m, ref Floatarray distance, ref Narray <Point> source, float maxdist) { const float BIG = 1e38f; int w = distance.Dim(0); int h = distance.Dim(1); distance.Resize(w, h); source.Resize(w, h); Queue <Point> queue = new Queue <Point>(w * h); int i, j; for (i = 0; i < w; i++) { for (j = 0; j < h; j++) { if (distance.At(i, j) > 0) { queue.Enqueue(new Point(i, j)); distance[i, j] = 0; source[i, j] = new Point(i, j); } else { distance[i, j] = BIG; source[i, j] = new Point(-1, -1); } } } while (queue.Count != 0) { Point q = queue.Dequeue(); float d = m.metric(new Point(q.X - 1, q.Y), source.At(q.X, q.Y)); if (d <= maxdist && q.X > 0 && d < distance.At(q.X - 1, q.Y)) { queue.Enqueue(new Point(q.X - 1, q.Y)); source[q.X - 1, q.Y] = source.At(q.X, q.Y); distance[q.X - 1, q.Y] = d; } d = m.metric(new Point(q.X, q.Y - 1), source.At(q.X, q.Y)); if (d <= maxdist && q.Y > 0 && d < distance.At(q.X, q.Y - 1)) { queue.Enqueue(new Point(q.X, q.Y - 1)); source[q.X, q.Y - 1] = source.At(q.X, q.Y); distance[q.X, q.Y - 1] = d; } d = m.metric(new Point(q.X + 1, q.Y), source.At(q.X, q.Y)); if (d <= maxdist && q.X < w - 1 && d < distance.At(q.X + 1, q.Y)) { queue.Enqueue(new Point(q.X + 1, q.Y)); source[q.X + 1, q.Y] = source.At(q.X, q.Y); distance[q.X + 1, q.Y] = d; } d = m.metric(new Point(q.X, q.Y + 1), source.At(q.X, q.Y)); if (d <= maxdist && q.Y < h - 1 && d < distance.At(q.X, q.Y + 1)) { queue.Enqueue(new Point(q.X, q.Y + 1)); source[q.X, q.Y + 1] = source.At(q.X, q.Y); distance[q.X, q.Y + 1] = d; } } }
public void EstimateSpaceSize() { Intarray labels = new Intarray(); labels.Copy(segmentation); ImgLabels.label_components(ref labels); Narray<Rect> boxes = new Narray<Rect>(); ImgLabels.bounding_boxes(ref boxes, labels); Floatarray distances = new Floatarray(); distances.Resize(boxes.Length()); distances.Fill(99999f); for (int i = 1; i < boxes.Length(); i++) { Rect b = boxes[i]; for (int j = 1; j < boxes.Length(); j++) { Rect n = boxes[j]; int delta = n.x0 - b.x1; if (delta < 0) continue; if (delta >= distances[i]) continue; distances[i] = delta; } } float interchar = NarrayUtil.Fractile(distances, PGetf("space_fractile")); space_threshold = interchar * PGetf("space_multiplier"); // impose some reasonable upper and lower bounds float xheight = 10.0f; // FIXME space_threshold = Math.Max(space_threshold, PGetf("space_min") * xheight); space_threshold = Math.Min(space_threshold, PGetf("space_max") * xheight); }
public Floatarray AsArray() { Floatarray result = new Floatarray(); result.Resize(Length()); result.Fill(0f); for (int i = 0; i < _keys.Length(); i++) result.UnsafePut1d(_keys.UnsafeAt1d(i), _values.UnsafeAt1d(i)); return result; }
public static void scale_to(Floatarray v, Floatarray sub, int csize, float noupscale=1.0f, float aa=1.0f) { // compute the scale factor float s = Math.Max(sub.Dim(0), sub.Dim(1))/(float)csize; // don't upscale if that's prohibited if(s < noupscale) s = 1.0f; // compute the offset to keep the input centered in the output float dx = (csize*s-sub.Dim(0))/2; float dy = (csize*s-sub.Dim(1))/2; // antialiasing via Gaussian convolution float sig = s * aa; if(sig > 1e-3f) Gauss.Gauss2d(sub, sig, sig); // now compute the output image via bilinear interpolation 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; } } }
public virtual void Output(Floatarray outv, int i) { outv.Resize(nClasses()); outv.Fill(limit); outv.Put1d(Cls(i), 1 - limit); }
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));*/ }
protected static void vmmul0(Floatarray result, Floatarray v, Floatarray a) { int n = a.Dim(0); int m = a.Dim(1); CHECK_ARG(n == v.Length(), "n == v.Length()"); result.Resize(m); result.Fill(0f); for (int i = 0; i < n; i++) { float value = v.UnsafeAt(i);//v[i]; if (value == 0f) continue; for (int j = 0; j < m; j++) result.UnsafePut(j, result.UnsafeAt(j) + (a.UnsafeAt(i, j) * value)); } }
public override void Extract(Narray <Floatarray> outarrays, Floatarray inarray) { outarrays.Clear(); Floatarray input = new Floatarray(); input.Copy(inarray); int w = input.Dim(0), h = input.Dim(1); Floatarray a = new Floatarray(); // working array int csize = PGeti("csize"); // get rid of small components SegmRoutine.erase_small_components(input, PGetf("minsize"), PGetf("threshold")); // compute a thresholded version for morphological operations Bytearray thresholded = new Bytearray(); OcrRoutine.threshold_frac(thresholded, input, PGetf("threshold")); // compute a smoothed version of the input for gradient computations float sigma = PGetf("gradsigma"); Floatarray smoothed = new Floatarray(); smoothed.Copy(input); Gauss.Gauss2d(smoothed, sigma, sigma); // x gradient a.Resize(w, h); for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { float delta; if (i == 0) { delta = 0f; } else { delta = smoothed[i, j] - smoothed[i - 1, j]; } a[i, j] = delta; } } Floatarray xgrad = outarrays.Push(new Floatarray()); OcrRoutine.scale_to(xgrad, a, csize, PGetf("noupscale"), PGetf("aa")); for (int j = 0; j < csize; j++) { for (int i = 0; i < csize; i++) { if (j % 2 == 0) { xgrad[i, j] = Math.Max(xgrad[i, j], 0f); } else { xgrad[i, j] = Math.Min(xgrad[i, j], 0f); } } } // y gradient a.Resize(w, h); for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { float delta; if (j == 0) { delta = 0f; } else { delta = smoothed[i, j] - smoothed[i, j - 1]; } a[i, j] = delta; } } Floatarray ygrad = outarrays.Push(new Floatarray()); OcrRoutine.scale_to(ygrad, a, csize, PGetf("noupscale"), PGetf("aa")); for (int i = 0; i < csize; i++) { for (int j = 0; j < csize; j++) { if (i % 2 == 0) { ygrad[i, j] = Math.Max(ygrad[i, j], 0f); } else { ygrad[i, j] = Math.Min(ygrad[i, j], 0f); } } } // junctions, endpoints, and holes Floatarray junctions = new Floatarray(); Floatarray endpoints = new Floatarray(); Floatarray holes = new Floatarray(); Bytearray junctions1 = new Bytearray(); Bytearray endpoints1 = new Bytearray(); Bytearray holes1 = new Bytearray(); Bytearray dilated = new Bytearray(); Bytearray binary = new Bytearray(); junctions.MakeLike(input, 0f); endpoints.MakeLike(input, 0f); holes.MakeLike(input, 0f); int n = PGeti("n"); float step = PGetf("step"); int bs = PGeti("binsmooth"); for (int i = 0; i < n; i++) { sigma = step * i; if (bs > 0) { OcrRoutine.binsmooth(binary, input, sigma); } else { binary.Copy(thresholded); Morph.binary_dilate_circle(binary, (int)(sigma)); } OcrRoutine.skeletal_features(endpoints1, junctions1, binary, 0.0f, 0.0f); NarrayUtil.Greater(junctions1, (byte)0, (byte)0, (byte)1); junctions.Copy(junctions1); NarrayUtil.Greater(endpoints1, (byte)0, (byte)0, (byte)1); endpoints.Copy(endpoints1); SegmRoutine.extract_holes(ref holes1, binary); NarrayUtil.Greater(holes1, (byte)0, (byte)0, (byte)1); holes.Copy(holes1); } junctions *= 1.0f / (float)n; endpoints *= 1.0f / (float)n; holes *= 1.0f / (float)n; OcrRoutine.scale_to(outarrays.Push(new Floatarray()), junctions, csize, PGetf("noupscale"), PGetf("aa")); OcrRoutine.scale_to(outarrays.Push(new Floatarray()), endpoints, csize, PGetf("noupscale"), PGetf("aa")); OcrRoutine.scale_to(outarrays.Push(new Floatarray()), holes, csize, PGetf("noupscale"), PGetf("aa")); }