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 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 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; } } }
private static string Upload(string img, bool useImgur) { string imgUrl; if (useImgur) { CliOutput.WriteInfo("Using Imgur for image upload"); var imgur = new Imgur(); imgUrl = imgur.Upload(img); } else { CliOutput.WriteInfo("Using ImgOps for image upload (2 hour cache)"); var imgOps = new ImgOps(); imgUrl = imgOps.UploadTempImage(img, out _); } return(imgUrl); }
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));*/ }