// morphapp.c (901, 1) // pixaExtendByMorph(pixas, type, niters, sel, include) as Pixa // pixaExtendByMorph(PIXA *, l_int32, l_int32, SEL *, l_int32) as PIXA * /// <summary> /// (1) This dilates or erodes every pix in %pixas, iteratively, /// using the input Sel (or, if null, a 2x2 Sel by default), /// and puts the results in %pixad.<para/> /// /// (2) If %niters smaller or equal 0, this is a no-op it returns a clone of pixas.<para/> /// /// (3) If %include == 1, the output %pixad contains all the pix /// in %pixas. Otherwise, it doesn't, but pixaJoin() can be /// used later to join pixas with pixad. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixaExtendByMorph/*"/> /// <param name="pixas">[in] - </param> /// <param name="type">[in] - L_MORPH_DILATE, L_MORPH_ERODE</param> /// <param name="niters">[in] - </param> /// <param name="sel">[in] - used for dilation, erosion uses 2x2 if null</param> /// <param name="include">[in] - 1 to include a copy of the input pixas in pixad 0 to omit</param> /// <returns>pixad with derived pix, using all iterations, or NULL on error</returns> public static Pixa pixaExtendByMorph( Pixa pixas, int type, int niters, Sel sel, int include) { if (pixas == null) { throw new ArgumentNullException("pixas cannot be Nothing"); } if (sel == null) { throw new ArgumentNullException("sel cannot be Nothing"); } IntPtr _Result = Natives.pixaExtendByMorph(pixas.Pointer, type, niters, sel.Pointer, include); if (_Result == IntPtr.Zero) { return(null); } return(new Pixa(_Result)); }
// morphapp.c (973, 1) // pixaExtendByScaling(pixas, nasc, type, include) as Pixa // pixaExtendByScaling(PIXA *, NUMA *, l_int32, l_int32) as PIXA * /// <summary> /// (1) This scales every pix in %pixas by each factor in %nasc. /// and puts the results in %pixad.<para/> /// /// (2) If %include == 1, the output %pixad contains all the pix /// in %pixas. Otherwise, it doesn't, but pixaJoin() can be /// used later to join pixas with pixad. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixaExtendByScaling/*"/> /// <param name="pixas">[in] - </param> /// <param name="nasc">[in] - numa of scaling factors</param> /// <param name="type">[in] - L_HORIZ, L_VERT, L_BOTH_DIRECTIONS</param> /// <param name="include">[in] - 1 to include a copy of the input pixas in pixad 0 to omit</param> /// <returns>pixad with derived pix, using all scalings, or NULL on error</returns> public static Pixa pixaExtendByScaling( Pixa pixas, Numa nasc, int type, int include) { if (pixas == null) { throw new ArgumentNullException("pixas cannot be Nothing"); } if (nasc == null) { throw new ArgumentNullException("nasc cannot be Nothing"); } IntPtr _Result = Natives.pixaExtendByScaling(pixas.Pointer, nasc.Pointer, type, include); if (_Result == IntPtr.Zero) { return(null); } return(new Pixa(_Result)); }
// boxfunc3.c (716, 1) // pixaDisplayBoxaa(pixas, baa, colorflag, width) as Pixa // pixaDisplayBoxaa(PIXA *, BOXAA *, l_int32, l_int32) as PIXA * /// <summary> /// (1) All pix in %pixas that are not rgb are converted to rgb.<para/> /// /// (2) Each boxa in %baa contains boxes that will be drawn on /// the corresponding pix in %pixas.<para/> /// /// (3) The color of the boxes drawn on each pix are selected with /// %colorflag: /// For red, green or blue: use L_DRAW_RED, etc. /// For sequential r, g, b: use L_DRAW_RGB /// For random colors: use L_DRAW_RANDOM /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixaDisplayBoxaa/*"/> /// <param name="pixas">[in] - any depth, can be cmapped</param> /// <param name="baa">[in] - boxes to draw on input pixa</param> /// <param name="colorflag">[in] - (L_DRAW_RED, L_DRAW_GREEN, etc)</param> /// <param name="width">[in] - thickness of lines</param> /// <returns>pixa with box outlines drawn on each pix, or NULL on error</returns> public static Pixa pixaDisplayBoxaa( Pixa pixas, Boxaa baa, int colorflag, int width) { if (pixas == null) { throw new ArgumentNullException("pixas cannot be Nothing"); } if (baa == null) { throw new ArgumentNullException("baa cannot be Nothing"); } IntPtr _Result = Natives.pixaDisplayBoxaa(pixas.Pointer, baa.Pointer, colorflag, width); if (_Result == IntPtr.Zero) { return(null); } return(new Pixa(_Result)); }
// morphapp.c (265, 1) // pixaMorphSequenceByComponent(pixas, sequence, minw, minh) as Pixa // pixaMorphSequenceByComponent(PIXA *, const char *, l_int32, l_int32) as PIXA * /// <summary> /// (1) See pixMorphSequence() for composing operation sequences.<para/> /// /// (2) This operates separately on each c.c. in the input pixa.<para/> /// /// (3) You can specify that the width and/or height must equal /// or exceed a minimum size for the operation to take place.<para/> /// /// (4) The input pixa should have a boxa giving the locations /// of the pix components. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixaMorphSequenceByComponent/*"/> /// <param name="pixas">[in] - of 1 bpp pix</param> /// <param name="sequence">[in] - string specifying sequence</param> /// <param name="minw">[in] - minimum width to consider use 0 or 1 for any width</param> /// <param name="minh">[in] - minimum height to consider use 0 or 1 for any height</param> /// <returns>pixad, or NULL on error</returns> public static Pixa pixaMorphSequenceByComponent( Pixa pixas, String sequence, int minw, int minh) { if (pixas == null) { throw new ArgumentNullException("pixas cannot be Nothing"); } if (sequence == null) { throw new ArgumentNullException("sequence cannot be Nothing"); } IntPtr _Result = Natives.pixaMorphSequenceByComponent(pixas.Pointer, sequence, minw, minh); if (_Result == IntPtr.Zero) { return(null); } return(new Pixa(_Result)); }
// textops.c (641, 1) // pixaAddTextNumber(pixas, bmf, na, val, location) as Pixa // pixaAddTextNumber(PIXA *, L_BMF *, NUMA *, l_uint32, l_int32) as PIXA * /// <summary> /// (1) Typical usage is for labelling each pix in a pixa with a number.<para/> /// /// (2) This function paints numbers external to each pix, in a position /// given by %location. In all cases, the pix is expanded on /// on side and the number is painted over white in the added region.<para/> /// /// (3) %val is the pixel value to be painted through the font mask. /// It should be chosen to agree with the depth of pixs. /// If it is out of bounds, an intermediate value is chosen. /// For RGB, use hex notation: 0xRRGGBB00, where RR is the /// hex representation of the red intensity, etc.<para/> /// /// (4) If na == NULL, number each pix sequentially, starting with 1.<para/> /// /// (5) If there is a colormap, this does the best it can to use /// the requested color, or something similar to it. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixaAddTextNumber/*"/> /// <param name="pixas">[in] - input pixa colormap ok</param> /// <param name="bmf">[in] - bitmap font data</param> /// <param name="na">[in][optional] - number array use 1 ... n if null</param> /// <param name="val">[in] - color to set the text</param> /// <param name="location">[in] - L_ADD_ABOVE, L_ADD_BELOW, L_ADD_LEFT, L_ADD_RIGHT</param> /// <returns>pixad new pixa with rendered numbers, or NULL on error</returns> public static Pixa pixaAddTextNumber( Pixa pixas, L_Bmf bmf, Numa na, uint val, int location) { if (pixas == null) { throw new ArgumentNullException("pixas cannot be Nothing"); } if (bmf == null) { throw new ArgumentNullException("bmf cannot be Nothing"); } IntPtr naPtr = IntPtr.Zero; if (na != null) { naPtr = na.Pointer; } IntPtr _Result = Natives.pixaAddTextNumber(pixas.Pointer, bmf.Pointer, naPtr, val, location); if (_Result == IntPtr.Zero) { return(null); } return(new Pixa(_Result)); }
// textops.c (780, 1) // pixaAddPixWithText(pixa, pixs, reduction, bmf, textstr, val, location) as int // pixaAddPixWithText(PIXA *, PIX *, l_int32, L_BMF *, const char *, l_uint32, l_int32) as l_ok /// <summary> /// (1) This function generates a new pix with added text, and adds /// it by insertion into the pixa.<para/> /// /// (2) If the input pixs is not cmapped and not 32 bpp, it is /// converted to 32 bpp rgb. %val is a standard 32 bpp pixel, /// expressed as 0xrrggbb00. If there is a colormap, this does /// the best it can to use the requested color, or something close.<para/> /// /// (3) if %bmf == NULL, generate an 8 pt font this takes about 5 msec.<para/> /// /// (4) If %textstr == NULL, use the text field in the pix.<para/> /// /// (5) In general, the text string can be written in multiple lines /// use newlines as the separators.<para/> /// /// (6) Typical usage is for debugging, where the pixa of labeled images /// is used to generate a pdf. Suggest using 1.0 for scalefactor. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixaAddPixWithText/*"/> /// <param name="pixa">[in] - </param> /// <param name="pixs">[in] - any depth, colormap ok</param> /// <param name="reduction">[in] - integer subsampling factor</param> /// <param name="bmf">[in][optional] - bitmap font data</param> /// <param name="textstr">[in][optional] - text string to be added</param> /// <param name="val">[in] - color to set the text</param> /// <param name="location">[in] - L_ADD_ABOVE, L_ADD_BELOW, L_ADD_LEFT, L_ADD_RIGHT</param> /// <returns>0 if OK, 1 on error.</returns> public static int pixaAddPixWithText( Pixa pixa, Pix pixs, int reduction, L_Bmf bmf, String textstr, uint val, int location) { if (pixa == null) { throw new ArgumentNullException("pixa cannot be Nothing"); } if (pixs == null) { throw new ArgumentNullException("pixs cannot be Nothing"); } if (reduction < 2 || reduction > 16) { throw new ArgumentException("integer subsampling factor"); } IntPtr bmfPtr = IntPtr.Zero; if (bmf != null) { bmfPtr = bmf.Pointer; } int _Result = Natives.pixaAddPixWithText(pixa.Pointer, pixs.Pointer, reduction, bmfPtr, textstr, val, location); return(_Result); }
// pageseg.c (464, 1) // pixGenTextblockMask(pixs, pixvws, pixadb) as Pix // pixGenTextblockMask(PIX *, PIX *, PIXA *) as PIX * /// <summary> /// (1) Both the input masks (textline and vertical white space) and /// the returned textblock mask are at the same resolution.<para/> /// /// (2) This is not intended to work on small thumbnails. The /// dimensions of pixs must be at least MinWidth x MinHeight.<para/> /// /// (3) The result is somewhat noisy, in that small "blocks" of /// text may be included. These can be removed by post-processing, /// using, e.g., /// pixSelectBySize(pix, 60, 60, 4, L_SELECT_IF_EITHER, /// L_SELECT_IF_GTE, NULL) /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixGenTextblockMask/*"/> /// <param name="pixs">[in] - 1 bpp, textline mask, assumed to be 150 to 200 ppi</param> /// <param name="pixvws">[in] - vertical white space mask</param> /// <param name="pixadb">[in] - input for collecting debug pix use NULL to skip</param> /// <returns>pixd textblock mask, or NULL on error</returns> public static Pix pixGenTextblockMask( Pix pixs, Pix pixvws, Pixa pixadb) { if (pixs == null) { throw new ArgumentNullException("pixs cannot be Nothing"); } if (pixvws == null) { throw new ArgumentNullException("pixvws cannot be Nothing"); } if (pixadb == null) { throw new ArgumentNullException("pixadb cannot be Nothing"); } IntPtr _Result = Natives.pixGenTextblockMask(pixs.Pointer, pixvws.Pointer, pixadb.Pointer); if (_Result == IntPtr.Zero) { return(null); } return(new Pix(_Result)); }
// jbclass.c (1030, 1) // jbClassifyCorrelation(classer, boxa, pixas) as int // jbClassifyCorrelation(JBCLASSER *, BOXA *, PIXA *) as l_ok /// <summary> /// jbClassifyCorrelation() /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/jbClassifyCorrelation/*"/> /// <param name="boxa">[in] - new components for classification</param> /// <param name="pixas">[in] - new components for classification</param> /// <returns>0 if OK 1 on error</returns> public static int jbClassifyCorrelation( JbClasser classer, Boxa boxa, Pixa pixas) { if (classer == null) { throw new ArgumentNullException("classer cannot be Nothing"); } if (boxa == null) { throw new ArgumentNullException("boxa cannot be Nothing"); } if (pixas == null) { throw new ArgumentNullException("pixas cannot be Nothing"); } IntPtr classerPtr = IntPtr.Zero; if (classer != null) { classerPtr = classer.Pointer; } int _Result = Natives.jbClassifyCorrelation(classer.Pointer, boxa.Pointer, pixas.Pointer); return(_Result); }
// recogtrain.c (1488, 1) // recogTrainFromBoot(recogboot, pixas, minscore, threshold, debug) as Pixa // recogTrainFromBoot(L_RECOG *, PIXA *, l_float32, l_int32, l_int32) as PIXA * /// <summary> /// (1) This takes %pixas of unscaled single characters and %recboot, /// a bootstrep recognizer (BSR) that has been set up with parameters /// scaleh: scale all templates to this height /// linew: width of normalized strokes, or 0 if using /// the input image /// It modifies the pix in %pixas accordingly and correlates /// with the templates in the BSR. It returns those input /// images in %pixas whose best correlation with the BSR is at /// or above %minscore. The returned pix have added text labels /// for the text string of the class to which the best /// correlated template belongs.<para/> /// /// (2) Identification occurs in scaled mode (typically with h = 40), /// optionally using a width-normalized line images derived /// from those in %pixas. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/recogTrainFromBoot/*"/> /// <param name="recogboot">[in] - labeled boot recognizer</param> /// <param name="pixas">[in] - set of unlabeled input characters</param> /// <param name="minscore">[in] - min score for accepting the example e.g., 0.75</param> /// <param name="threshold">[in] - for binarization, if needed</param> /// <param name="debug">[in] - 1 for debug output saved to recogboot 0 otherwise</param> /// <returns>pixad labeled version of input pixas, trained on a BSR, or NULL on error</returns> public static Pixa recogTrainFromBoot( L_Recog recogboot, Pixa pixas, Single minscore, int threshold, Enumerations.DebugOnOff debug = DebugOnOff.DebugOn) { if (recogboot == null) { throw new ArgumentNullException("recogboot cannot be Nothing"); } if (pixas == null) { throw new ArgumentNullException("pixas cannot be Nothing"); } IntPtr _Result = Natives.recogTrainFromBoot(recogboot.Pointer, pixas.Pointer, minscore, threshold, (int)debug); if (_Result == IntPtr.Zero) { return(null); } return(new Pixa(_Result)); }
// pageseg.c (372, 1) // pixGenTextlineMask(pixs, ppixvws, ptlfound, pixadb) as Pix // pixGenTextlineMask(PIX *, PIX **, l_int32 *, PIXA *) as PIX * /// <summary> /// (1) The input pixs should be deskewed.<para/> /// /// (2) pixs should have no halftone pixels.<para/> /// /// (3) This is not intended to work on small thumbnails. The /// dimensions of pixs must be at least MinWidth x MinHeight.<para/> /// /// (4) Both the input image and the returned textline mask /// are at the same resolution. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixGenTextlineMask/*"/> /// <param name="pixs">[in] - 1 bpp, assumed to be 150 to 200 ppi</param> /// <param name="ppixvws">[out] - vertical whitespace mask</param> /// <param name="ptlfound">[out][optional] - 1 if the mask is not empty</param> /// <param name="pixadb">[in] - input for collecting debug pix use NULL to skip</param> /// <returns>pixd textline mask, or NULL on error</returns> public static Pix pixGenTextlineMask( Pix pixs, out Pix ppixvws, out int ptlfound, Pixa pixadb) { if (pixs == null) { throw new ArgumentNullException("pixs cannot be Nothing"); } if (pixadb == null) { throw new ArgumentNullException("pixadb cannot be Nothing"); } IntPtr ppixvwsPtr = IntPtr.Zero; IntPtr _Result = Natives.pixGenTextlineMask(pixs.Pointer, out ppixvwsPtr, out ptlfound, pixadb.Pointer); if (ppixvwsPtr == IntPtr.Zero) { ppixvws = null; } else { ppixvws = new Pix(ppixvwsPtr); }; if (_Result == IntPtr.Zero) { return(null); } return(new Pix(_Result)); }
// recogtrain.c (970, 1) // recogFilterPixaBySize(pixas, setsize, maxkeep, max_ht_ratio, pna) as Pixa // recogFilterPixaBySize(PIXA *, l_int32, l_int32, l_float32, NUMA **) as PIXA * /// <summary> /// (1) The basic assumption is that the most common and larger /// templates in each class are more likely to represent the /// characters we are interested in. For example, larger digits /// are more likely to represent page numbers, and smaller digits /// could be data in tables. Therefore, we bias the first /// stage of filtering toward the larger characters by removing /// very small ones, and select based on proximity of the /// remaining characters to median height.<para/> /// /// (2) For each of the %setsize classes, order the templates /// increasingly by height. Take the rank 0.9 height. Eliminate /// all templates that are shorter by more than %max_ht_ratio. /// Of the remaining ones, select up to %maxkeep that are closest /// in rank order height to the median template. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/recogFilterPixaBySize/*"/> /// <param name="pixas">[in] - labeled templates</param> /// <param name="setsize">[in] - size of character set (number of classes)</param> /// <param name="maxkeep">[in] - max number of templates to keep in a class</param> /// <param name="max_ht_ratio">[in] - max allowed height ratio (see below)</param> /// <param name="pna">[out][optional] - debug output, giving the number in each class after filtering use NULL to skip</param> /// <returns>pixa filtered templates, or NULL on error</returns> public static Pixa recogFilterPixaBySize( Pixa pixas, int setsize, int maxkeep, Single max_ht_ratio, out Numa pna) { if (pixas == null) { throw new ArgumentNullException("pixas cannot be Nothing"); } IntPtr pnaPtr = IntPtr.Zero; IntPtr _Result = Natives.recogFilterPixaBySize(pixas.Pointer, setsize, maxkeep, max_ht_ratio, out pnaPtr); if (pnaPtr == IntPtr.Zero) { pna = null; } else { pna = new Numa(pnaPtr); }; if (_Result == IntPtr.Zero) { return(null); } return(new Pixa(_Result)); }
// recogtrain.c (664, 1) // pixaAccumulateSamples(pixa, pta, ppixd, px, py) as int // pixaAccumulateSamples(PIXA *, PTA *, PIX **, l_float32 *, l_float32 *) as l_int32 /// <summary> /// (1) This generates an aligned (by centroid) sum of the input pix.<para/> /// /// (2) We use only the first 256 samples that's plenty.<para/> /// /// (3) If pta is not input, we generate two tables, and discard /// after use. If this is called many times, it is better /// to precompute the pta. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixaAccumulateSamples/*"/> /// <param name="pixa">[in] - of samples from the same class, 1 bpp</param> /// <param name="pta">[in][optional] - of centroids of the samples</param> /// <param name="ppixd">[out] - accumulated samples, 8 bpp</param> /// <param name="px">[out][optional] - average x coordinate of centroids</param> /// <param name="py">[out][optional] - average y coordinate of centroids</param> /// <returns>0 on success, 1 on failure</returns> public static int pixaAccumulateSamples( Pixa pixa, Pta pta, out Pix ppixd, out Single px, out Single py) { if (pixa == null) { throw new ArgumentNullException("pixa cannot be Nothing"); } IntPtr ptaPtr = IntPtr.Zero; if (pta != null) { ptaPtr = pta.Pointer; } IntPtr ppixdPtr = IntPtr.Zero; int _Result = Natives.pixaAccumulateSamples(pixa.Pointer, ptaPtr, out ppixdPtr, out px, out py); if (ppixdPtr == IntPtr.Zero) { ppixd = null; } else { ppixd = new Pix(ppixdPtr); }; return(_Result); }
// watershed.c (1034, 1) // wshedBasins(wshed, ppixa, pnalevels) as int // wshedBasins(L_WSHED *, PIXA **, NUMA **) as l_ok /// <summary> /// wshedBasins() /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/wshedBasins/*"/> /// <param name="wshed">[in] - </param> /// <param name="ppixa">[out][optional] - mask of watershed basins</param> /// <param name="pnalevels">[out][optional] - watershed levels</param> /// <returns>0 if OK, 1 on error</returns> public static int wshedBasins( L_WShed wshed, out Pixa ppixa, out Numa pnalevels) { if (wshed == null) { throw new ArgumentNullException("wshed cannot be Nothing"); } IntPtr ppixaPtr = IntPtr.Zero; IntPtr pnalevelsPtr = IntPtr.Zero; int _Result = Natives.wshedBasins(wshed.Pointer, out ppixaPtr, out pnalevelsPtr); if (ppixaPtr == IntPtr.Zero) { ppixa = null; } else { ppixa = new Pixa(ppixaPtr); }; if (pnalevelsPtr == IntPtr.Zero) { pnalevels = null; } else { pnalevels = new Numa(pnalevelsPtr); }; return(_Result); }
// baseline.c (113, 1) // pixFindBaselines(pixs, ppta, pixadb) as Numa // pixFindBaselines(PIX *, PTA **, PIXA *) as NUMA * /// <summary> /// (1) Input binary image must have text lines already aligned /// horizontally. This can be done by either rotating the /// image with pixDeskew(), or, if a projective transform /// is required, by doing pixDeskewLocal() first.<para/> /// /// (2) Input null for [and]pta if you don't want this returned. /// The pta will come in pairs of points (left and right end /// of each baseline).<para/> /// /// (3) Caution: this will not work properly on text with multiple /// columns, where the lines are not aligned between columns. /// If there are multiple columns, they should be extracted /// separately before finding the baselines.<para/> /// /// (4) This function constructs different types of output /// for baselines namely, a set of raster line values and /// a set of end points of each baseline.<para/> /// /// (5) This function was designed to handle short and long text lines /// without using dangerous thresholds on the peak heights. It does /// this by combining the differential signal with a morphological /// analysis of the locations of the text lines. One can also /// combine this data to normalize the peak heights, by weighting /// the differential signal in the region of each baseline /// by the inverse of the width of the text line found there. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixFindBaselines/*"/> /// <param name="pixs">[in] - 1 bpp, 300 ppi</param> /// <param name="ppta">[out][optional] - pairs of pts corresponding to approx. ends of each text line</param> /// <param name="pixadb">[in] - for debug output use NULL to skip</param> /// <returns>na of baseline y values, or NULL on error</returns> public static Numa pixFindBaselines( Pix pixs, out Pta ppta, Pixa pixadb) { if (pixs == null) { throw new ArgumentNullException("pixs cannot be Nothing"); } if (pixadb == null) { throw new ArgumentNullException("pixadb cannot be Nothing"); } IntPtr pptaPtr = IntPtr.Zero; IntPtr _Result = Natives.pixFindBaselines(pixs.Pointer, out pptaPtr, pixadb.Pointer); if (pptaPtr == IntPtr.Zero) { ppta = null; } else { ppta = new Pta(pptaPtr); }; if (_Result == IntPtr.Zero) { return(null); } return(new Numa(_Result)); }
// writefile.c (1128, 1) // pixSaveTiledOutline(pixs, pixa, scalefactor, newrow, space, linewidth, dp) as int // pixSaveTiledOutline(PIX *, PIXA *, l_float32, l_int32, l_int32, l_int32, l_int32) as l_ok /// <summary> /// (1) Before calling this function for the first time, use /// pixaCreate() to make the %pixa that will accumulate the pix. /// This is passed in each time pixSaveTiled() is called.<para/> /// /// (2) %scalefactor scales the input image. After scaling and /// possible depth conversion, the image is saved in the input /// pixa, along with a box that specifies the location to /// place it when tiled later. Disable saving the pix by /// setting %scalefactor == 0.0.<para/> /// /// (3) %newrow and %space specify the location of the new pix /// with respect to the last one(s) that were entered.<para/> /// /// (4) %dp specifies the depth at which all pix are saved. It can /// be only 8 or 32 bpp. Any colormap is removed. This is only /// used at the first invocation.<para/> /// /// (5) This function uses two variables from call to call. /// If they were static, the function would not be .so or thread /// safe, and furthermore, there would be interference with two or /// more pixa accumulating images at a time. Consequently, /// we use the first pix in the pixa to store and obtain both /// the depth and the current position of the bottom (one pixel /// below the lowest image raster line when laid out using /// the boxa). The bottom variable is stored in the input format /// field, which is the only field available for storing an int. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixSaveTiledOutline/*"/> /// <param name="pixs">[in] - 1, 2, 4, 8, 32 bpp</param> /// <param name="pixa">[in] - the pix are accumulated here</param> /// <param name="scalefactor">[in] - 0.0 to disable otherwise this is a scale factor</param> /// <param name="newrow">[in] - 0 if placed on the same row as previous 1 otherwise</param> /// <param name="space">[in] - horizontal and vertical spacing, in pixels</param> /// <param name="linewidth">[in] - width of added outline for image 0 for no outline</param> /// <param name="dp">[in] - depth of pixa 8 or 32 bpp only used on first call</param> /// <returns>0 if OK, 1 on error.</returns> public static int pixSaveTiledOutline( Pix pixs, Pixa pixa, Single scalefactor, int newrow, int space, int linewidth, int dp) { if (pixs == null) { throw new ArgumentNullException("pixs cannot be Nothing"); } if (pixa == null) { throw new ArgumentNullException("pixa cannot be Nothing"); } if ((new List <int> { 1, 2, 4, 8, 32 }).Contains((int)pixs.d) == false) { throw new ArgumentException("1, 2, 4, 8, 32 bpp"); } int _Result = Natives.pixSaveTiledOutline(pixs.Pointer, pixa.Pointer, scalefactor, newrow, space, linewidth, dp); return(_Result); }
// jbclass.c (531, 1) // jbAddPageComponents(classer, pixs, boxas, pixas) as int // jbAddPageComponents(JBCLASSER *, PIX *, BOXA *, PIXA *) as l_ok /// <summary> /// (1) If there are no components on the page, we don't require input /// of empty boxas or pixas, although that's the typical situation. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/jbAddPageComponents/*"/> /// <param name="pixs">[in] - input page</param> /// <param name="boxas">[in] - b.b. of components for this page</param> /// <param name="pixas">[in] - components for this page</param> /// <returns>0 if OK 1 on error</returns> public static int jbAddPageComponents( JbClasser classer, Pix pixs, Boxa boxas, Pixa pixas) { if (classer == null) { throw new ArgumentNullException("classer cannot be Nothing"); } if (pixs == null) { throw new ArgumentNullException("pixs cannot be Nothing"); } if (boxas == null) { throw new ArgumentNullException("boxas cannot be Nothing"); } if (pixas == null) { throw new ArgumentNullException("pixas cannot be Nothing"); } IntPtr classerPtr = IntPtr.Zero; if (classer != null) { classerPtr = classer.Pointer; } int _Result = Natives.jbAddPageComponents(classer.Pointer, pixs.Pointer, boxas.Pointer, pixas.Pointer); return(_Result); }
// readbarcode.c (254, 1) // pixReadBarcodes(pixa, format, method, psaw, debugflag) as Sarray // pixReadBarcodes(PIXA *, l_int32, l_int32, SARRAY **, l_int32) as SARRAY * /// <summary> /// pixReadBarcodes() /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixReadBarcodes/*"/> /// <param name="pixa">[in] - of 8 bpp deskewed and cropped barcodes</param> /// <param name="format">[in] - L_BF_ANY, L_BF_CODEI2OF5, L_BF_CODE93, ...</param> /// <param name="method">[in] - L_USE_WIDTHS, L_USE_WINDOWS</param> /// <param name="psaw">[out][optional] - sarray of bar widths</param> /// <param name="debugflag">[in] - use 1 to generate debug output</param> /// <returns>sa sarray of widths, one string for each barcode found, or NULL on error</returns> public static Sarray pixReadBarcodes( Pixa pixa, Enumerations.IFF format, int method, out Sarray psaw, int debugflag) { if (pixa == null) { throw new ArgumentNullException("pixa cannot be Nothing"); } IntPtr psawPtr = IntPtr.Zero; IntPtr _Result = Natives.pixReadBarcodes(pixa.Pointer, (int)format, method, out psawPtr, debugflag); if (psawPtr == IntPtr.Zero) { psaw = null; } else { psaw = new Sarray(psawPtr); }; if (_Result == IntPtr.Zero) { return(null); } return(new Sarray(_Result)); }
// jbclass.c (1454, 1) // pixWordMaskByDilation(pixs, ppixm, psize, pixadb) as int // pixWordMaskByDilation(PIX *, PIX **, l_int32 *, PIXA *) as l_ok /// <summary> /// (1) This gives an estimate of the word masks. See /// pixWordBoxesByDilation() for further filtering of the word boxes.<para/> /// /// (2) The resolution should be between 75 and 150 ppi, and the optimal /// dilation will be between 3 and 10.<para/> /// /// (3) A good size for dilating to get word masks is optionally returned.<para/> /// /// (4) Typically, the number of c.c. reduced with each successive /// dilation (stored in nadiff) decreases quickly to a minimum /// (where the characters in a word are joined), and then /// increases again as the smaller number of words are joined. /// For the typical case, you can then look for this minimum /// and dilate to get the word mask. However, there are many /// cases where the function is not so simple. For example, if the /// pix has been upscaled 2x, the nadiff function oscillates, with /// every other value being zero! And for some images it tails /// off without a clear minimum to indicate where to break. /// So a more simple and robust method is to find the dilation /// where the initial number of c.c. has been reduced by some /// fraction (we use a 70% reduction). /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixWordMaskByDilation/*"/> /// <param name="pixs">[in] - 1 bpp typ. at 75 to 150 ppi</param> /// <param name="psize">[out][optional] - size of good horizontal dilation</param> /// <param name="pixadb">[out][optional] - debug: pixa of intermediate steps</param> /// <returns>0 if OK, 1 on error</returns> public static int pixWordMaskByDilation( Pix pixs, Pix ppixm, out int psize, out Pixa pixadb) { if (pixs == null) { throw new ArgumentNullException("pixs cannot be Nothing"); } if (ppixm == null) { throw new ArgumentNullException("ppixm cannot be Nothing"); } IntPtr ppixmPtr = IntPtr.Zero; if (ppixm != null) { ppixmPtr = ppixm.Pointer; } IntPtr pixadbPtr = IntPtr.Zero; int _Result = Natives.pixWordMaskByDilation(pixs.Pointer, ppixmPtr, out psize, out pixadbPtr); if (pixadbPtr == IntPtr.Zero) { pixadb = null; } else { pixadb = new Pixa(pixadbPtr); }; return(_Result); }
// pageseg.c (1076, 1) // pixExtractRawTextlines(pixs, maxw, maxh, adjw, adjh, pixadb) as Pixa // pixExtractRawTextlines(PIX *, l_int32, l_int32, l_int32, l_int32, PIXA *) as PIXA * /// <summary> /// (1) This function assumes that textlines have sufficient /// vertical separation and small enough skew so that a /// horizontal dilation sufficient to join words will not join /// textlines. It aggressively joins textlines across multiple /// columns, so if that is not desired, you must either (a) make /// sure that %pixs is a single column of text or (b) use instead /// pixExtractTextlines(), which is more conservative /// about joining text fragments that have vertical overlap.<para/> /// /// (2) This first removes components from pixs that are either /// very wide ( is greater %maxw) or very tall ( is greater %maxh).<para/> /// /// (3) For reasonable accuracy, the resolution of pixs should be /// at least 100 ppi. For reasonable efficiency, the resolution /// should not exceed 600 ppi.<para/> /// /// (4) This can be used to determine if some region of a scanned /// image is horizontal text.<para/> /// /// (5) As an example, for a pix with resolution 300 ppi, a reasonable /// set of parameters is: /// pixExtractRawTextlines(pix, 150, 150, 0, 0, NULL)<para/> /// /// (6) The output pixa is composed of subimages, one for each textline, /// and the boxa in the pixa tells where in %pixs each textline goes. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixExtractRawTextlines/*"/> /// <param name="pixs">[in] - any depth, assumed to have nearly horizontal text</param> /// <param name="maxw">[in] - initial filtering: remove any components in pixs with components larger than maxw or maxh use 0 for default values.</param> /// <param name="maxh">[in] - initial filtering: remove any components in pixs with components larger than maxw or maxh use 0 for default values.</param> /// <param name="adjw">[in] - final adjustment of boxes representing each text line. If is greater 0, these increase the box size at each edge by this amount.</param> /// <param name="adjh">[in] - final adjustment of boxes representing each text line. If is greater 0, these increase the box size at each edge by this amount.</param> /// <param name="pixadb">[in] - pixa for saving intermediate steps NULL to omit</param> /// <returns>pixa of textline images, including bounding boxes, or NULL on error</returns> public static Pixa pixExtractRawTextlines( Pix pixs, int maxw, int maxh, int adjw, int adjh, Pixa pixadb) { if (pixs == null) { throw new ArgumentNullException("pixs cannot be Nothing"); } if (pixadb == null) { throw new ArgumentNullException("pixadb cannot be Nothing"); } IntPtr _Result = Natives.pixExtractRawTextlines(pixs.Pointer, maxw, maxh, adjw, adjh, pixadb.Pointer); if (_Result == IntPtr.Zero) { return(null); } return(new Pixa(_Result)); }
// textops.c (710, 1) // pixaAddTextlines(pixas, bmf, sa, val, location) as Pixa // pixaAddTextlines(PIXA *, L_BMF *, SARRAY *, l_uint32, l_int32) as PIXA * /// <summary> /// (1) This function adds one or more lines of text externally to /// each pix, in a position given by %location. In all cases, /// the pix is expanded as necessary to accommodate the text.<para/> /// /// (2) %val is the pixel value to be painted through the font mask. /// It should be chosen to agree with the depth of pixs. /// If it is out of bounds, an intermediate value is chosen. /// For RGB, use hex notation: 0xRRGGBB00, where RR is the /// hex representation of the red intensity, etc.<para/> /// /// (3) If sa == NULL, use the text embedded in each pix. In all /// cases, newlines in the text string are used to separate the /// lines of text that are added to the pix.<para/> /// /// (4) If sa has a smaller count than pixa, issue a warning /// and do not use any embedded text.<para/> /// /// (5) If there is a colormap, this does the best it can to use /// the requested color, or something similar to it. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixaAddTextlines/*"/> /// <param name="pixas">[in] - input pixa colormap ok</param> /// <param name="bmf">[in] - bitmap font data</param> /// <param name="sa">[in][optional] - sarray use text embedded in each pix if null</param> /// <param name="val">[in] - color to set the text</param> /// <param name="location">[in] - L_ADD_ABOVE, L_ADD_BELOW, L_ADD_LEFT, L_ADD_RIGHT</param> /// <returns>pixad new pixa with rendered text, or NULL on error</returns> public static Pixa pixaAddTextlines( Pixa pixas, L_Bmf bmf, Sarray sa, uint val, int location) { if (pixas == null) { throw new ArgumentNullException("pixas cannot be Nothing"); } if (bmf == null) { throw new ArgumentNullException("bmf cannot be Nothing"); } IntPtr saPtr = IntPtr.Zero; if (sa != null) { saPtr = sa.Pointer; } IntPtr _Result = Natives.pixaAddTextlines(pixas.Pointer, bmf.Pointer, saPtr, val, location); if (_Result == IntPtr.Zero) { return(null); } return(new Pixa(_Result)); }
// pageseg.c (1204, 1) // pixCountTextColumns(pixs, deltafract, peakfract, clipfract, pncols, pixadb) as int // pixCountTextColumns(PIX *, l_float32, l_float32, l_float32, l_int32 *, PIXA *) as l_ok /// <summary> /// (1) It is assumed that pixs has the correct resolution set. /// If the resolution is 0, we set to 300 and issue a warning.<para/> /// /// (2) If necessary, the image is scaled to between 37 and 75 ppi /// most of the processing is done at this resolution.<para/> /// /// (3) If no text is found (essentially a blank page), /// this returns ncols = 0.<para/> /// /// (4) For debug output, input a pre-allocated pixa. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixCountTextColumns/*"/> /// <param name="pixs">[in] - 1 bpp</param> /// <param name="deltafract">[in] - fraction of (max - min) to be used in the delta for extrema finding typ 0.3</param> /// <param name="peakfract">[in] - fraction of (max - min) to be used to threshold the peak value typ. 0.5</param> /// <param name="clipfract">[in] - fraction of image dimension removed on each side typ. 0.1, which leaves w and h reduced by 0.8</param> /// <param name="pncols">[out] - number of columns -1 if not determined</param> /// <param name="pixadb">[in][optional] - pre-allocated, for showing intermediate computation use null to skip</param> /// <returns>0 if OK, 1 on error</returns> public static int pixCountTextColumns( Pix pixs, Single deltafract, Single peakfract, Single clipfract, out int pncols, Pixa pixadb = null) { if (pixs == null) { throw new ArgumentNullException("pixs cannot be Nothing"); } if ((new List <int> { 1 }).Contains((int)pixs.d) == false) { throw new ArgumentException("1 bpp"); } IntPtr pixadbPtr = IntPtr.Zero; if (pixadb != null) { pixadbPtr = pixadb.Pointer; } int _Result = Natives.pixCountTextColumns(pixs.Pointer, deltafract, peakfract, clipfract, out pncols, pixadbPtr); return(_Result); }
// conncomp.c (190, 1) // pixConnCompPixa(pixs, ppixa, connectivity) as Boxa // pixConnCompPixa(PIX *, PIXA **, l_int32) as BOXA * /// <summary> /// (1) This finds bounding boxes of 4- or 8-connected components /// in a binary image, and saves images of each c.c /// in a pixa array.<para/> /// /// (2) It sets up 2 temporary pix, and for each c.c. that is /// located in raster order, it erases the c.c. from one pix, /// then uses the b.b. to extract the c.c. from the two pix using /// an XOR, and finally erases the c.c. from the second pix.<para/> /// /// (3) A clone of the returned boxa (where all boxes in the array /// are clones) is inserted into the pixa.<para/> /// /// (4) If the input is valid, this always returns a boxa and a pixa. /// If pixs is empty, the boxa and pixa will be empty. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixConnCompPixa/*"/> /// <param name="pixs">[in] - 1 bpp</param> /// <param name="ppixa">[out] - pixa of each c.c.</param> /// <param name="connectivity">[in] - 4 or 8</param> /// <returns>boxa, or NULL on error</returns> public static Boxa pixConnCompPixa( Pix pixs, out Pixa ppixa, int connectivity) { if (pixs == null) { throw new ArgumentNullException("pixs cannot be Nothing"); } if ((new List <int> { 1 }).Contains((int)pixs.d) == false) { throw new ArgumentException("1 bpp"); } IntPtr ppixaPtr = IntPtr.Zero; IntPtr _Result = Natives.pixConnCompPixa(pixs.Pointer, out ppixaPtr, connectivity); if (ppixaPtr == IntPtr.Zero) { ppixa = null; } else { ppixa = new Pixa(ppixaPtr); }; if (_Result == IntPtr.Zero) { return(null); } return(new Boxa(_Result)); }
// recogident.c (878, 1) // recogIdentifyPixa(recog, pixa, ppixdb) as int // recogIdentifyPixa(L_RECOG *, PIXA *, PIX **) as l_ok /// <summary> /// (1) This should be called by recogIdentifyMuliple(), which /// binarizes and splits characters before sending %pixa here.<para/> /// /// (2) This calls recogIdentifyPix(), which does the same operation /// on each pix in %pixa, and optionally returns the arrays /// of results (scores, class index and character string) /// for the best correlation match. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/recogIdentifyPixa/*"/> /// <param name="recog">[in] - </param> /// <param name="pixa">[in] - of 1 bpp images to match</param> /// <param name="ppixdb">[out][optional] - pix showing inputs and best fits</param> /// <returns>0 if OK, 1 on error</returns> public static int recogIdentifyPixa( L_Recog recog, Pixa pixa, out Pix ppixdb) { if (recog == null) { throw new ArgumentNullException("recog cannot be Nothing"); } if (pixa == null) { throw new ArgumentNullException("pixa cannot be Nothing"); } IntPtr ppixdbPtr = IntPtr.Zero; int _Result = Natives.recogIdentifyPixa(recog.Pointer, pixa.Pointer, out ppixdbPtr); if (ppixdbPtr == IntPtr.Zero) { ppixdb = null; } else { ppixdb = new Pix(ppixdbPtr); }; return(_Result); }
private void WriteAllPixaImages(ref Pixa pixa, string prefix) { var n = pixaGetCount(pixa); for (int i = 0; i < n; i++) { var pix1 = pixaGetPix(pixa, i, Enumerations.L_access_storage.L_CLONE); var fn = $"{prefix}-{i.ToString().PadLeft(2, '0')}.png"; pix1.save_format(fn, Enumerations.IFF.IFF_PNG); pixDestroy(ref pix1); } }
// recogident.c (158, 1) // recogIdentifyMultiple(recog, pixs, minh, skipsplit, pboxa, ppixa, ppixdb, debugsplit) as int // recogIdentifyMultiple(L_RECOG *, PIX *, l_int32, l_int32, BOXA **, PIXA **, PIX **, l_int32) as l_ok /// <summary> /// (1) This filters the input pixa and calls recogIdentifyPixa()<para/> /// /// (2) Splitting is relatively slow, because it tries to match all /// character templates to all locations. This step can be skipped.<para/> /// /// (3) An attempt is made to order the (optionally) returned images /// and boxes in 2-dimensional sorted order. These can then /// be used to aggregate identified characters into numbers or words. /// One typically wants the pixa, which contains a boxa of the /// extracted subimages. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/recogIdentifyMultiple/*"/> /// <param name="recog">[in] - with training finished</param> /// <param name="pixs">[in] - containing typically a small number of characters</param> /// <param name="minh">[in] - remove shorter components use 0 for default</param> /// <param name="skipsplit">[in] - 1 to skip the splitting step</param> /// <param name="pboxa">[out][optional] - locations of identified components</param> /// <param name="ppixa">[out][optional] - images of identified components</param> /// <param name="ppixdb">[out][optional] - debug pix: inputs and best fits</param> /// <param name="debugsplit">[in] - 1 returns pix split debugging images</param> /// <returns>0 if OK 1 if nothing is found 2 for other errors.</returns> public static int recogIdentifyMultiple( L_Recog recog, Pix pixs, int minh, int skipsplit, out Boxa pboxa, out Pixa ppixa, out Pix ppixdb, int debugsplit) { if (recog == null) { throw new ArgumentNullException("recog cannot be Nothing"); } if (pixs == null) { throw new ArgumentNullException("pixs cannot be Nothing"); } IntPtr pboxaPtr = IntPtr.Zero; IntPtr ppixaPtr = IntPtr.Zero; IntPtr ppixdbPtr = IntPtr.Zero; int _Result = Natives.recogIdentifyMultiple(recog.Pointer, pixs.Pointer, minh, skipsplit, out pboxaPtr, out ppixaPtr, out ppixdbPtr, debugsplit); if (pboxaPtr == IntPtr.Zero) { pboxa = null; } else { pboxa = new Boxa(pboxaPtr); }; if (ppixaPtr == IntPtr.Zero) { ppixa = null; } else { ppixa = new Pixa(ppixaPtr); }; if (ppixdbPtr == IntPtr.Zero) { ppixdb = null; } else { ppixdb = new Pix(ppixdbPtr); }; return(_Result); }
// pageseg.c (102, 1) // pixGetRegionsBinary(pixs, ppixhm, ppixtm, ppixtb, pixadb) as int // pixGetRegionsBinary(PIX *, PIX **, PIX **, PIX **, PIXA *) as l_ok /// <summary> /// (1) It is best to deskew the image before segmenting.<para/> /// /// (2) Passing in %pixadb enables debug output. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixGetRegionsBinary/*"/> /// <param name="pixs">[in] - 1 bpp, assumed to be 300 to 400 ppi</param> /// <param name="ppixhm">[out][optional] - halftone mask</param> /// <param name="ppixtm">[out][optional] - textline mask</param> /// <param name="ppixtb">[out][optional] - textblock mask</param> /// <param name="pixadb">[in] - input for collecting debug pix use NULL to skip</param> /// <returns>0 if OK, 1 on error</returns> public static int pixGetRegionsBinary( Pix pixs, out Pix ppixhm, out Pix ppixtm, out Pix ppixtb, Pixa pixadb) { if (pixs == null) { throw new ArgumentNullException("pixs cannot be Nothing"); } if (pixadb == null) { throw new ArgumentNullException("pixadb cannot be Nothing"); } IntPtr ppixhmPtr = IntPtr.Zero; IntPtr ppixtmPtr = IntPtr.Zero; IntPtr ppixtbPtr = IntPtr.Zero; int _Result = Natives.pixGetRegionsBinary(pixs.Pointer, out ppixhmPtr, out ppixtmPtr, out ppixtbPtr, pixadb.Pointer); if (ppixhmPtr == IntPtr.Zero) { ppixhm = null; } else { ppixhm = new Pix(ppixhmPtr); }; if (ppixtmPtr == IntPtr.Zero) { ppixtm = null; } else { ppixtm = new Pix(ppixtmPtr); }; if (ppixtbPtr == IntPtr.Zero) { ppixtb = null; } else { ppixtb = new Pix(ppixtbPtr); }; return(_Result); }
// classapp.c (378, 1) // pixGetWordsInTextlines(pixs, minwidth, minheight, maxwidth, maxheight, pboxad, ppixad, pnai) as int // pixGetWordsInTextlines(PIX *, l_int32, l_int32, l_int32, l_int32, BOXA **, PIXA **, NUMA **) as l_ok /// <summary> /// (1) The input should be at a resolution of between 75 and 150 ppi.<para/> /// /// (2) The four size constraints on saved components are all /// scaled by %reduction.<para/> /// /// (3) The result are word images (and their b.b.), extracted in /// textline order, at either full res or 2x reduction, /// and with a numa giving the textline index for each word.<para/> /// /// (4) The pixa and boxa interfaces should make this type of /// application simple to put together. The steps are: /// ~ generate first estimate of word masks /// ~ get b.b. of these, and remove the small and big ones /// ~ extract pixa of the word images, using the b.b. /// ~ sort actual word images in textline order (2d) /// ~ flatten them to a pixa (1d), saving the textline index /// for each pix<para/> /// /// (5) In an actual application, it may be desirable to pre-filter /// the input image to remove large components, to extract /// single columns of text, and to deskew them. For example, /// to remove both large components and small noisy components /// that can interfere with the statistics used to estimate /// parameters for segmenting by words, but still retain text lines, /// the following image preprocessing can be done: /// Pix pixt = pixMorphSequence(pixs, "c40.1", 0) /// Pix pixf = pixSelectBySize(pixt, 0, 60, 8, /// L_SELECT_HEIGHT, L_SELECT_IF_LT, NULL) /// pixAnd(pixf, pixf, pixs) // the filtered image /// The closing turns text lines into long blobs, but does not /// significantly increase their height. But if there are many /// small connected components in a dense texture, this is likely /// to generate tall components that will be eliminated in pixf. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixGetWordsInTextlines/*"/> /// <param name="pixs">[in] - 1 bpp, typ. 75 - 150 ppi</param> /// <param name="minwidth">[in] - of saved components smaller are discarded</param> /// <param name="minheight">[in] - of saved components smaller are discarded</param> /// <param name="maxwidth">[in] - of saved components larger are discarded</param> /// <param name="maxheight">[in] - of saved components larger are discarded</param> /// <param name="pboxad">[out] - word boxes sorted in textline line order</param> /// <param name="ppixad">[out] - word images sorted in textline line order</param> /// <param name="pnai">[out] - index of textline for each word</param> /// <returns>0 if OK, 1 on error</returns> public static int pixGetWordsInTextlines( Pix pixs, int minwidth, int minheight, int maxwidth, int maxheight, out Boxa pboxad, out Pixa ppixad, out Numa pnai) { if (pixs == null) { throw new ArgumentNullException("pixs cannot be Nothing"); } IntPtr pboxadPtr = IntPtr.Zero; IntPtr ppixadPtr = IntPtr.Zero; IntPtr pnaiPtr = IntPtr.Zero; int _Result = Natives.pixGetWordsInTextlines(pixs.Pointer, minwidth, minheight, maxwidth, maxheight, out pboxadPtr, out ppixadPtr, out pnaiPtr); if (pboxadPtr == IntPtr.Zero) { pboxad = null; } else { pboxad = new Boxa(pboxadPtr); }; if (ppixadPtr == IntPtr.Zero) { ppixad = null; } else { ppixad = new Pixa(ppixadPtr); }; if (pnaiPtr == IntPtr.Zero) { pnai = null; } else { pnai = new Numa(pnaiPtr); }; return(_Result); }
// morphapp.c (1475, 1) // pixaCentroids(pixa) as Pta // pixaCentroids(PIXA *) as PTA * /// <summary> /// (1) An error message is returned if any pix has something other /// than 1 bpp or 8 bpp depth, and the centroid from that pix /// is saved as (0, 0). /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixaCentroids/*"/> /// <param name="pixa">[in] - of components 1 or 8 bpp</param> /// <returns>pta of centroids relative to the UL corner of each pix, or NULL on error</returns> public static Pta pixaCentroids( Pixa pixa) { if (pixa == null) { throw new ArgumentNullException("pixa cannot be Nothing"); } IntPtr _Result = Natives.pixaCentroids(pixa.Pointer); if (_Result == IntPtr.Zero) { return(null); } return(new Pta(_Result)); }
// pageseg.c (679, 1) // pixSplitIntoCharacters(pixs, minw, minh, pboxa, ppixa, ppixdebug) as int // pixSplitIntoCharacters(PIX *, l_int32, l_int32, BOXA **, PIXA **, PIX **) as l_ok /// <summary> /// (1) This is a simple function that attempts to find split points /// based on vertical pixel profiles.<para/> /// /// (2) It should be given an image that has an arbitrary number /// of text characters.<para/> /// /// (3) The returned pixa includes the boxes from which the /// (possibly split) components are extracted. /// </summary> /// <remarks> /// </remarks> /// <include file="..\CHM_Help\IncludeComments.xml" path="Comments/pixSplitIntoCharacters/*"/> /// <param name="pixs">[in] - 1 bpp, contains only deskewed text</param> /// <param name="minw">[in] - min component width for initial filtering typ. 4</param> /// <param name="minh">[in] - min component height for initial filtering typ. 4</param> /// <param name="pboxa">[out][optional] - character bounding boxes</param> /// <param name="ppixa">[out][optional] - character images</param> /// <param name="ppixdebug">[out][optional] - showing splittings</param> /// <returns>0 if OK, 1 on error</returns> public static int pixSplitIntoCharacters( Pix pixs, int minw, int minh, out Boxa pboxa, out Pixa ppixa, out Pix ppixdebug) { if (pixs == null) { throw new ArgumentNullException("pixs cannot be Nothing"); } IntPtr pboxaPtr = IntPtr.Zero; IntPtr ppixaPtr = IntPtr.Zero; IntPtr ppixdebugPtr = IntPtr.Zero; int _Result = Natives.pixSplitIntoCharacters(pixs.Pointer, minw, minh, out pboxaPtr, out ppixaPtr, out ppixdebugPtr); if (pboxaPtr == IntPtr.Zero) { pboxa = null; } else { pboxa = new Boxa(pboxaPtr); }; if (ppixaPtr == IntPtr.Zero) { ppixa = null; } else { ppixa = new Pixa(ppixaPtr); }; if (ppixdebugPtr == IntPtr.Zero) { ppixdebug = null; } else { ppixdebug = new Pix(ppixdebugPtr); }; return(_Result); }
private static void testIsTable() { int pscore; Leptonica.Native.DllImports.LeptonicaDirectory = @"..\..\..\leptonica.net\lib"; Pix pix1 = Pix.Read(file); Pixa pixadb = PixaBasic.pixaCreate(0); PageSeg.pixDecideIfTable(pix1, null, Leptonica.Definitions.Pix.ImageOrientationFlags.L_PORTRAIT_MODE, out pscore, pixadb); var istable = (pscore >= 2) ? 1.0F : 0.0F; Console.WriteLine("Is this a table result: {0}", istable); pix1.pixDestroy(); pixadb.pixaDestroy(); Console.WriteLine("Done..."); Console.ReadKey(); }