// Primitive feature structure typedef struct _PRIMFEATURE { int pixel; // Area of the primitive region int length; // Perimeter of the primitive region double cx; // Centroid x double cy; // Centroid y // featureex added on July 25, 2001 // Always NULL as of July 25, 2001. The content of the structure is also undetermined (no problem with compilation) PRIMFEATUREEX* featureex; // Extended features (intended for future expansion, such as circularity, line width, second moment features, etc.) } PRIMFEATURE; typedef struct _PRIMITIVE { unsigned char layer; // Layer number of the primitive unsigned char undo; // Original layer of the primitive unsigned char unused; // 1 when not in use unsigned char flag; // General control flag int xmin; // Upper-left coordinate of the primitive region (if the positive direction of the Y-axis is down) int ymin; int xmax; // Bottom-right coordinate of the primitive region (if the positive direction of the Y-axis is down) int ymax; PRIMFEATURE* feature; } PRIMITIVE;
typedef struct _CLUSTER { int num; // number of elements in the prim array int validnum; // number of valid elements in the prim array int max; // size of the prim array PRIMITIVE** pprim; unsigned char flag; // 0...normal cluster (to be fused) // 1...isolated cluster (not to be fused) unsigned char loc; // 0...far from the frame: unrelated to the adjacent segment clusters // 1...near the top frame: to be fused with the top segment cluster // 2...near the bottom frame: to be fused with the bottom segment cluster // 4...near the left frame: to be fused with the left segment cluster // 8...near the right frame: to be fused with the right segment cluster unsigned char unused; // 0...used // 1...not used unsigned char reserved2; short line; // line in case of a table short column; // column in case of a table PRIMITIVE* parent; // the primitive (such as a table) to which the cluster belongs long pwidthmax; // maximum width of elements inside the cluster long pheightmax; // maximum height of elements inside the cluster long xmin; // coordinates of the top-left point of the cluster (when the positive Y-axis is downwards) long ymin; long xmax; // coordinates of the bottom-right point of the cluster (when the positive Y-axis is downwards) long ymax; // angle added on October 10, 2000 double angle; // estimated or specified angle of the cluster (for additional functionality) void* pdata; // reserved } CLUSTER;
typedef struct _ALTABLE { int num; // number of clusters int max; // size of cluster array CLUSTER** ppcluster; // cluster array PRIMITIVE* prim; // primitive corresponding to the table long xmin; // top-left (if the positive y-axis is downwards) coordinate of the table long ymin; long xmax; // bottom-right (if the positive y-axis is downwards) coordinate of the table long ymax; } ALTABLE;
Class Name | CJocrPrimRD or CJocrPrimEX or CJocrPrim |
Header Files | ocrdef.h ocrco.h primitive.h cjocrprim.h absparam.h cjocrprimex.h cjocrprimrd.h errcode.h |
Required LIB | NGKOCR4.LIB |
Required DLL | NGKOCR1.DLL NGKOCR2.DLL NGKOCR4.DLL ALVEC.DLL ALPOLYGON.DLL |
Compile Constant | USENGKDLL4 |
CJocrPrim* prim = new CJocrPrim("ABCDEFGHJKLMNPQ23456"); .... delete prim;Alternatively,
CJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd"); .... delete prim;Check if it is initialized using mchecklimit as follows. If the library cannot be used due to reasons such as expiration of the license code or hardware lock failure, the return value is 1. If an unlimited license file is used, there is no need for a check.
if(mpjocrprim->mchecklimit(3)) { delete mpjocrrecognize; mpjocrrecognize = NULL; } // int mchecklimit(int level) // Input: // int level; // Always 3 for library users // Returns 1 if not initialized
// Setting the document image void msetdocument(unsigned char* buffer, int background, int width, int height); // Specifying the scan line size void msetdocument(unsigned char* buffer, int background, int width, int scanlinesize, int height); Input unsigned char* buffer; // starting address of the image int background; // background bit value (0...bit0 is background / 1...bit1 is background) int width; // width of the image (in pixels) int scanlinesize; // number of bytes per scan line int height; // height of the image (in pixels)
// Bitmap to Primitive Conversion // Conversion of the entire bitmap int makeprim(); int makeprim8(); // Specify a rectangular region (not inclined) and only convert the interior int makeprim(int x1, int y1, int x2, int y2); int makeprim8(int x1, int y1, int x2, int y2); Input int x1, y1; Upper-left coordinates of the rectangle int x2, y2; Lower-right coordinates of the rectangle Return Value 0................ Successful completion MEMORY_SHORTAGE... Insufficient memory // Specify an arbitrary convex quadrangle region and only convert the interior // Can also be an arbitrarily angled rectangle int makeprim(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4); int makeprim8(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4); Input int x1, y1; Four coordinates of the convex quadrangle (order does not matter) int x2, y2; int x3, y3; int x4, y4; Return Value 0............... Successful completion MEMORY_SHORTAGE. Insufficient memory // Get the number of primitives int mgetvalidprimitivenum(); // Get the number of primitives on a layer int mgetvalidprimitivenum(int layer); Return Value Number of converted primitives
#include "ocrdef.h" #include "ocrco.h" #include "cjocrprim.h" #include "errcode.h" ... .... // Initialize the library by specifying a 20-digit code supplied by the licenser or the path to a license code file. CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456"); // If using a license code path, use: CJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd"); pjocrprim->msetdocument(mdata,0,mwidth,mheight); // Monochrome image with background as 0 and foreground as 1 ret = pjocrprim->makeprim(); if(ret < 0) { Error; } delete pjocrprim; ...
// Setting dpi // Set dpi to convert points to pixels void msetdpi(int dpi); Input int dpi; // resolution // Setting font size // Specify maximum and minimum primitive sizes void msetpoint(int maxpoint,int minpoint); Input int maxpoint; // maximum primitive size (above minpoint points (1 inch = 72 points)) int minpoint; // minimum primitive size (at least 1 point (1 inch = 72 points)) // Setting document type // The interpretation of the number of points in slanted cases changes // If no slanting is specified, the angle estimate is limited to either 0 degrees or 90 degrees. void msetvflag(int vflag); Input int vflag; // 1...horizontal writing only (bit0) // 2...vertical writing only (bit1) // 3...horizontal writing + vertical writing (no slanting) // 4...slanting (values of bit0 and bit1 are ignored) // Setting number of characters per line, number of blocks per line, character spacing, line spacing // Corresponds to specifying the size of the cluster and the distance between the primitives that make up one cluster // charperline×lineperblock becomes the maximum number of primitives in one cluster void msetcharline(int charperline,int lineperblock,int charspace,int linespace); Input int charperline; // number of characters per line int lineperblock; // number of lines per paragraph int chaspace; // distance between primitives in the horizontal direction (or vertical direction in vertical writing) // (points (1 inch = 72 points)) int linespace; // distance between primitives in the vertical direction (or horizontal direction in vertical writing) // (points (1 inch = 72 points)) // Minimum number of characters in one cluster // Equivalent to the number of primitives included in one cluster void msetminnum(int aminnum); Input int aminnum; // minimum number of primitives /////////////////////// // Estimation of minimum and maximum font size void minferpoint(int& amin,int& amax,int layer); Input int layer; // estimation within the layer Output int& amin; // minimum font size (points (1 inch = 72 points)) int& amax; // maximum font size (points (1 inch = 72 points)) ///////////////// // Cluster extraction // Extract clusters based on the above parameters int mabstractcluster(int from,int to); Input int from; // source layer to move from int to; // destination layer to move to Return Value 0 or more...........number of extracted clusters MEMORY_SHORTAGE...running out of memory // Getting extracted cluster data // The calling side needs to allocate buffer pcluster // The internal cluster area is kept statically, but it also includes invalid clusters that were discarded during calculation, so this function is provided to extract only valid clusters. void mgetvalidcluster(CLUSTER* pcluster); Input CLUSTER* pcluster; buffer to store clusters sizeof(CLUSTER) * number of extracted clusters Output CLUSTER* pcluster; extracted cluster data
#include "ocrdef.h" #include "ocrco.h" #include "cjocrprim.h" #include "errcode.h" ... .... // Initialize the library by specifying a 20-digit code supplied by the licenser or the path to a license code file CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456"); // If using the license code path: CJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd"); pjocrprim->msetdocument(mdata,0,mwidth,mheight); // Monochrome image with 0 for background and 1 for foreground ret = pjocrprim->makeprim(); if(ret < 0) { Error; } // Extract clusters int clusternum = pjocrprim->mabstractcluster(0,1); if(clusternum < 0) { Error; } CLUSTER* pcluster = (CLUSTER*)malloc(sizeof(CLUSTER) * clusternum); if(pcluster) { // Get clusters mgetvalidcluster(pcluster); } delete pjocrprim; ...
// Cluster angle estimation calculation void mcalcangle(CLUSTER* pcluster, double& angle); Input CLUSTER* pcluster: Cluster (obtained with mgetvalidcluster) Output double& angle: Estimated angle (in radians)The angle is estimated within ±5 degrees range from the specified angle. Use this function when estimating the angle based on a user-specified angle in functions like moveprimlinestring.
// Cluster angle estimation calculation void mcalcanglespec(CLUSTER* pcluster, double& angle); Input CLUSTER* pcluster: Cluster (obtained with mgetvalidcluster) double& angle: Specified angle (in radians) Output double& angle: Estimated angle (in radians)
#include "ocrdef.h" #include "ocrco.h" #include "cjocrprim.h" #include "errcode.h" ... .... // Initialize the library by specifying a 20-digit code supplied by the licenser or the path to the license code file CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456"); // Or if providing the path to the license code file, use: CJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd"); pjocrprim->msetdocument(mdata, 0, mwidth, mheight); // Monochrome image with background as 0 and foreground as 1 ret = pjocrprim->makeprim(); if (ret < 0) { Error; } // Extract clusters (move primitives belonging to clusters to Layer 1) int clusternum = pjocrprim->mabstractcluster(0, 1); if (clusternum < 0) { Error; } CLUSTER* pcluster = (CLUSTER*)malloc(sizeof(CLUSTER) * clusternum); if (pcluster) { // Get clusters mgetvalidcluster(pcluster); for (int i = 0; i < clusternum; i++) { double angle; pjocrprim->mcalcangle(pcluster + i, angle); // Angle is the estimated angle (in radians) // The actual baseline angle is either angle or angle + π/2 .... ... } } delete pjocrprim; ...
// The order of the coordinates is as follows. // [0] | [1] // +------------+------------+ // | 2 | 1 | // -+------------+------------+-axis line // | 3 | 4 | // +------------+------------+ // [3] | [2] // Coordinate arrangement by mcalcframe // 0...Second quadrant with respect to the cluster center // 1...First quadrant with respect to the cluster center // 2...Fourth quadrant with respect to the cluster center // 3...Third quadrant with respect to the cluster center // Calculating the outer frame of the cluster void mcalcframe(CLUSTER* pcl, double angle, double* px, double* py, double& dh, double& dv, double ext = 0.0, int recalcflag); Input CLUSTER* pcl; // Cluster double angle; // Angle of the axis line (radians) double ext; // Expand all coordinates by ext pixels outside // The default value is 0.0 // Added functionality on October 10, 2000 int recalcflag // If set to 1, the outer frame will shrink until it touches the primitives // Shrink the gap between the diagonal bounding rectangle and the primitive // The default value is 0 Output double* px; // px[4]...Coordinates of the outer frame double* py; // py[4]...Coordinates of the outer frame
// When the angle of dh is angle (positive if the y-axis direction is downward) (positive counterclockwise if the y-axis direction is upward) double& dh; // Length of the cluster's axis line (not necessarily close to horizontal) double& dv; // Length of the line intersecting the cluster's axis line vertically (not necessarily close to vertical)
{ // CLUSTER* pcluster; // Assume pcluster is a cluster extracted by some API double angle; double dh,dv; double x[4]; double y[4]; mpjocrprim->mcalcangle(pcluster,angle); // Calculate angle based on pcluster mpjocrprim->mcalcframe(pcluster,angle,x,y,dh,dv,0.0,1); // Calculate x[4], y[4], dh, dv based on pcluster and angle // Set recalcflag to 1 to eliminate extra space between the frame and characters even in diagonal cases // (x[3],y[3])-(x[2],y[2]) is the baseline of the text line // The height (width) of the line is dv }
#include "ocrdef.h" #include "ocrco.h" #include "cjocrprim.h" #include "errcode.h" ... .... // Initialize the library by specifying a 20-digit code provided by the licenser or the path to a license code file CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456"); // If using a license code file path: CJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd"); pjocrprim->msetdocument(mdata,0,mwidth,mheight); // Monochrome image with background 0 and foreground 1 ret = pjocrprim->makeprim(); if(ret < 0) { Error; } // Extract clusters int clusternum = pjocrprim->mabstractcluster(0,1); if(clusternum < 0) { Error; } CLUSTER* pcluster = (CLUSTER*)malloc(sizeof(CLUSTER) * clusternum); if(pcluster) { // Retrieve clusters mgetvalidcluster(pcluster); for(int i = 0 ; i < clusternum ; i++) { double x[4]; double y[4]; double dh; double dv; pjocrprim->mcalcframe(pcluster + i,0,x,y,dh,dv); // Get the bounding box as a rotation angle of 0 degrees .... ... } } delete pjocrprim; ...
/////////////////////// // Table Processing Operations // Call after cluster extraction (mabstractcluster) int mabstracttable(int clusterlayer, int from, int to); Input int clusterlayer; // Layer on which clusters were extracted int from; // Layer from which to extract the table int to; // Destination of the extracted table Return 0 or more..........Number of extracted tables MEMORY_SHORTAGE...Insufficient memory // Get the number of extracted tables int mgettablenum(); // Get the extracted tables ALTABLE* mgettable(); // Points to an internal pointer, so cannot be freed or modifiedThe address of a cluster belonging to a table is stored in the ALTABLE structure. The line and column to which each cluster belongs to in the table are assigned to the line and column members of the cluster structure. The counting of rows and columns starts from the 1st row and 1st column.
#include "ocrdef.h" #include "ocrco.h" #include "cjocrprim.h" #include "errcode.h" ... .... // Initialize library by specifying a 20-digit code provided by the licenser or the path of the license code file CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456"); // If using license code path, initialize library like this: CJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd"); pjocrprim->msetdocument(mdata,0,mwidth,mheight); // Monochrome image where background is 0 and foreground is 1 ret = pjocrprim->makeprim(); if(ret < 0) { Error; } // Extract clusters ret = pjocrprim->mabstractcluster(0,1); // Extract tables ret = pjocrprim->mabstracttable(1,0,1); int tablenum = pjocrprim->mgettablenum(); if(tablenum) { // Get tables ALTABLE* ptable = pjocrprim->mgettable(); .... } delete pjocrprim; ...
// Move primitives intersecting with a rectangle from 'from' to 'to' int moveprimrecthook(int x1,int y1,int x2,int y2,int from,int to,int mojiflag); // Move primitives intersecting with a rectangle from 'from' to 'to' and cluster them int moveprimrecthookcluster(int x1,int y1,int x2,int y2,int from,int to,int mojiflag); Input int x1,y1; // Coordinates of rectangle int x2,y2; int from; // Source layer int to; // Destination layer int mojiflag; // If 1, only move primitives that fit within the character size specified by 'msetpoint' // If overridden by Override (Character Definition), prioritized over mojifilter function Return Value >= 0..........Number of moved primitives Negative.............MEMORY_SHORTAGE Memory shortage // Move primitives intersecting with a diagonal rectangle from 'from' to 'to' int moveprimrecthook(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,int from,int to,int mojiflag); // Move primitives intersecting with a diagonal rectangle from 'from' to 'to' and cluster them int moveprimrecthookcluster(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,int from,int to,int mojiflag); Input int x1,y1; // Coordinates of diagonal rectangle (order of coordinates is arbitrary) int x2,y2; int x3,y3; int x4,y4; int from; // Source layer int to; // Destination layer int mojiflag; // If 1, only move primitives that fit within the character size specified by 'msetpoint' // If overridden by Override (Character Definition), prioritized over mojifilter function Return Value >= 0..........Number of moved primitives Negative.............MEMORY_SHORTAGE Memory shortage // Move primitives fully contained within a rectangle from 'from' to 'to' int moveprimrect(int x1,int y1,int x2,int y2,int from,int to,int mojiflag); // Move primitives fully contained within a rectangle from 'from' to 'to' and cluster them int moveprimrectcluster(int x1,int y1,int x2,int y2,int from,int to,int mojiflag); Input int x1,y1; // Coordinates of rectangle int x2,y2; int from; // Source layer int to; // Destination layer int mojiflag; // If 1, only move primitives that fit within the character size specified by 'msetpoint' // If overridden by Override (Character Definition), prioritized over mojifilter function Return Value >= 0..........Number of moved primitives Negative.............MEMORY_SHORTAGE Memory shortage // Move primitives fully contained within a diagonal rectangle from 'from' to 'to' int moveprimrect(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,int from,int to,int mojiflag); // Move primitives fully contained within a diagonal rectangle from 'from' to 'to' and cluster them int moveprimrectcluster(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,int from,int to,int mojiflag); Input int x1,y1; // Coordinates of diagonal rectangle (order of coordinates is arbitrary) int x2,y2; int x3,y3; int x4,y4; int from; // Source layer int to; // Destination layer int mojiflag; // If 1, only move primitives that fit within the character size specified by 'msetpoint' // If overridden by Override (Character Definition), prioritized over mojifilter function Return Value >= 0..........Number of moved primitives Negative.............MEMORY_SHORTAGE Memory shortage // Move primitives that intersect with a line from 'from' to 'to' int moveprimline(int x1,int y1,int x2,int y2,int from,int to); // Move primitives that intersect with a line from 'from' to 'to' and cluster them int moveprimlinecluster(int x1,int y1,int x2,int y2,int from,int to); Input int x1,y1; // Starting point of the line int x2,y2; // End point of the line int from; // Source layer int to; // Destination layer Return Value >= 0..........Number of moved primitives Negative.............MEMORY_SHORTAGE Memory shortage
// Moves primitives that intersect with the line + primitives included in the rectangle formed by the primitives from "from" to "to" int moveprimlinestring(int x1, int y1, int x2, int y2, int from, int to, double* px, double* py); Input int x1, y1; // Starting point of the line int x2, y2; // End point of the line int from; // Source layer int to; // Destination layer double* px; // Address of an array of size sizeof(double) * 4 (for operation check) double* py; // Address of an array of size sizeof(double) * 4 (for operation check) Return Value Greater than or equal to 0.................. Number of moved primitives MEMORY_SHORTAGE...Insufficient memory
#include "ocrdef.h" #include "ocrco.h" #include "cjocrprim.h" #include "errcode.h" ... .... // Initialize the library by specifying a 20-digit code supplied by a license sensor or a path to a license code file CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456"); // If using a license code file path, use CJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd"); pjocrprim->msetdocument(mdata,0,mwidth,mheight); // Monochrome image where the background is 0 and the foreground is 1 ret = pjocrprim->makeprim(); if(ret < 0) { // Error handling } ... // Specify the coordinates from (x1, y1) to (x2, y2) using the mouse or other input method ... double x[4]; double y[4]; ret = pjocrprim->moveprimlinestring(x1, y1, x2, y2, from, to, x, y); if(ret > 0) { CLUSTER cluster; pjocrprim->mgetvalidcluster(&cluster); double angle; angle = atan2((double)(y2 - y1), (double)(x2 - x1)); // Estimate the angle within ± 5 degrees from the user-specified line angle pjocrprim->mcalcanglespec(&cluster, angle); double dh, dv; // Calculate the bounding box (bounding box of the primitives' outer frame) pjocrprim->mcalcframe(mpcluster, angle, x, y, dh, dv); ... } delete pjocrprim; ...
// Move noise to layer int movenoise(int xsize,int ysize,int from,int to); Input int xsize; // Width up to xsize pixels and height up to ysize pixels int ysize; // to process as noise int from; // Source layer int to; // Destination layer Return Greater than or equal to 0..........Number of primitives moved Negative.............MEMORY_SHORTAGE Not enough memory
#include "ocrdef.h" #include "ocrco.h" #include "cjocrprim.h" #include "errcode.h" ... .... // Initialize the library by specifying a 20-digit code or the path to a license code file supplied by the licenser. CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456"); // If using the path to the license code file, use CJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd"); pjocrprim->msetdocument(mdata,0,mwidth,mheight); // Monochrome image where 0 represents background and 1 represents foreground ret = pjocrprim->makeprim(); if(ret < 0) { Error; } // Noise selection pjocrprim->movenoise(7,7,0,1); // Select 4-connected bit 1 regions with up to 7 pixels in both vertical and horizontal directions as noise // Move the primitives corresponding to noise to layer 1 // Noise removal pjocrprim->mdeleteprim(1); // Delete the primitives in layer 1 // Reflect the changes in the original data delete pjocrprim; ...
// Move primitives that touch the outermost frame to the layer int movetouchframe(int from, int to); Input int from; // Source layer int to; // Destination layer Output 0 or more..........Number of moved primitives Negative.............MEMORY_SHORTAGE Out of memory
#include "ocrdef.h" #include "ocrco.h" #include "cjocrprim.h" #include "errcode.h" ... .... // Initialize the library by specifying a 20-digit code supplied by the licenseor or the path to the license code file CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456"); // If using a license code path, use this: CJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd"); pjocrprim->msetdocument(mdata,0,mwidth,mheight); // monochrome image with background 0 and foreground 1 ret = pjocrprim->makeprim(); if(ret < 0) { Error; } // Select primitives that touch the frame pjocrprim->movetouchframe(0,1); // Move primitives that touch the outermost perimeter to layer 1 // Remove primitives that touch the frame pjocrprim->mdeleteprim(1); // Delete primitives in layer 1 // Also update the original data delete pjocrprim; ...
// Move primitives from layer 'from' to layer 'to' int moveprim(int from = 0, int to = 1); Input int from; // Source layer int to; // Destination layer Return Number of primitives moved // Move primitives from layer 'from' to layer 'to' with rectangle specification int moveprimloc(int x1, int y1, int x2, int y2, int from, int to); Input int x1, int y1, int x2, int y2; // (x1,y1)-(x2,y2) Left upper corner and right lower corner coordinates of rectangle Return Number of primitives moved // Move primitives with pixel value amin <= pixel <= amax from layer 'from' to layer 'to' int moveprimpixel(int amin, int amax, int from = 0, int to = 1); Input int amin, int amax; Minimum and maximum area of the primitive Return Number of primitives moved // Move primitives with area amin <= area <= amax, heightmin <= height <= heightmax, widthmin <= width <= widthmax from layer 'from' to layer 'to' int moveprimsizepixel(int areamin, int areamax, int widthmin, int heightmin, int widthmax, int heightmax, int from, int to); Input int areamin, int areamax; Range of area (in square pixels) int widthmin, heightmin; Minimum width and height (in pixels) int widthmax, heightmax; Maximum width and height (in pixels) Return Number of primitives moved
// Remove primitives on the layer and reflect it in the original image void mdeleteprim(int layer); Input: int layer; // Layer to move to
// Primitive -> Bitmap conversion // The width and height are the same as the original document // The buffer should be allocated, managed, and freed by the calling function // Input: // int layer; 0 to 255...the layer to convert to bitmap // Output: // unsigned char* pdata; the bitmap void makebitmap(int layer, unsigned char* pdata);
// Buffer management is done internally in the library // Input // CLUSTER* pcluster; Cluster // double angle; Rotation angle // Output // unsigned char*& pdata; Bitmap // int& width; Width of the bitmap (in pixels) // int& height; Height of the bitmap (in pixels) // Get Bitmap of a Cluster void makebitmapcluster(CLUSTER* pcluster,unsigned char*& pdata,int& width,int& height); // Return the bitmap of the primitives that belong to the cluster, rotated by the angle in radians // Get Bitmap of a Cluster (angle rotation) void makebitmapcluster(CLUSTER* pcluster,double angle,unsigned char*& pdata,int& width,int& height);
#include "ocrdef.h" #include "ocrco.h" #include "cjocrprim.h" #include "errcode.h" ... .... // Initialize the library by specifying the 20-digit code supplied by the licenser or the path of the license code file CJocrPrim* pjocrprim = new CJocrPrim("ABCDEFGHJKLMNPQ23456"); // If using the license code path, use: CJocrPrim* prim = new CJocrPrim("C:\\Program Files\\Foo\\primitive.kcd"); pjocrprim->msetdocument(mdata, 0, mwidth, mheight); // Monochrome image with background=0 and foreground=1 ret = pjocrprim->makeprim(); if(ret < 0) { Error; } // Move the primitive to layer 1 based on user operation // Move the primitives within the diagonal rectangle from from to to + cluster the moved primitives pjocrprim->moveprimrecthookcluster(x1, y1, x2, y2, x3, y3, y4, y4, 0, 1); // Get the cluster // Retrieve the bitmap of the cluster (rotated by angle radians) double angle = atan2((double)(y2 - y1), (double)(x2 - x1)); mpjocrprim->makebitmapcluster(mpjocrprim->mgetcluster(), angle, pdata, width, height); // The pdata array will contain width x height pixel data // The rectangle (x1, y1)-(x2, y2) will be rotated angle degrees to be horizontal delete pjocrprim; ...
// Input // int layer; The layer to convert to display data (monochrome only) // int width; The width of the image to create // int height; The height of the image to create // int offsetx; The x-axis offset // int offsety; The y-axis offset // double mag; The magnification (1.0 for actual size) // Output // unsigned char* pdata; The display data (sufficient size to hold a dib of width × height) // Monochrome DIB (4-byte boundary) void makedispdatadib2(int layer,int width,int height,int offsetx,int offsety,double mag,unsigned char* pdata); // DIB 255-color image data creation (4-byte boundary) // The layer belongs to the palette index void makedispdatadib255(int width,int height,int offsetx,int offsety,double mag,unsigned char* pdata);
// Calculation of primitive features // int mcalcfeature(); // Calculation of primitive features (area only) // int mcalcfeaturepixel();
// Apply customization to cluster extraction // int mabstractclusterfilter(int from,int to); // Functions for override // Target the ones with return value of 1 for clustering // virtual int mprimitivefilter(PRIMITIVE* prim); // Combine the ones with return value of 1 into one cluster // virtual int mlocationfilter(PRIMITIVE* prim1,PRIMITIVE* prim2); // Target the ones with return value of 1 for valid clusters // virtual int mclusterfilter(CLUSTER* pcluster);Customize the cluster extraction using the three virtual functions for override. To perform override, you need to define a subclass of the CJocrPrim class. In addition, within the override function mlocationfilter, you can use the following function:
// Returns 1 if there is a separator (part of a shape that does not belong to a cluster) between two primitives // virtual int mlocationfilter(PRIMITIVE* prim1,PRIMITIVE* prim2);Here is an example code for cluster extraction using override:
class CJocrSub : public CJocrPrim { public: CJocrSub(char* code) : CJocrPrim(alcode){} ~CJocrSub(){} private: int minpixel; // Minimum area of primitives int maxpixel; // Maximum area of primitives double minrate; // Minimum height/width ratio of primitives double maxrate; // Maximum height/width ratio of primitives private: double mindist; // Minimum distance between primitives double maxdist; // Maximum distance between primitives private: int mleft; // Cluster position (top-left) int mtop; // Cluster position (top-left) int mright; // Cluster position (bottom-right) int mbottom; // Cluster position (bottom-right) public: void msetparameter(int aminpixel,int amaxpixel,double aminrate,double amaxrate) { minpixel = aminpixel; // Minimum area of primitives maxpixel = amaxpixel; // Maximum area of primitives minrate = aminrate; // Minimum height/width ratio of primitives maxrate = amaxrate; // Maximum height/width ratio of primitives } void msetparameter(double amindist,double amaxdist) { mindist = amindist; maxdist = amaxdist; } void msetparameter(int left,int top,int right,int bottom) { mleft = left; // Cluster position (top-left) mtop = top; // Cluster position (top-left) mright = right; // Cluster position (bottom-right) mbottom = bottom; // Cluster position (bottom-right) } public: // Override virtual int mprimitivefilter(PRIMITIVE* prim) { PRIMFEATURE* feature = prim->feature; if(feature && minpixel <= feature->pixel && feature->pixel <= maxpixel) return 1; return 0; } // Override virtual int mlocationfilter(PRIMITIVE* prim1,PRIMITIVE* prim2) { double cx1 = (prim1->xmin + prim1->xmax) / 2.0; double cy1 = (prim1->ymin + prim1->ymax) / 2.0; double cx2 = (prim2->xmin + prim2->xmax) / 2.0; double cy2 = (prim2->ymin + prim2->ymax) / 2.0; double d = sqrt((cx2 - cx1) * (cx2 - cx1) + (cy2 - cy1) * (cy2 - cy1)); if(mindist <= d && d < maxdist && !mcheckseparator(prim1,prim2)) return 1; return 0; } // Override virtual int mclusterfilter(CLUSTER* pcluster) { if(pcluster->xmin < mleft) return(0); if(mright < pcluster->xmax) return(0); if(pcluster->ymin < mtop) return(0); if(mbottom < pcluster->ymax) return(0); return(1); } };In the base class, clustering is determined based on the size of the primitives. However, in the subclass, clustering is determined based on the area and aspect ratio of the primitives.
// Function to apply customized inter-layer movement // int moveprimfilter(int from,int to); // Function for override // Move the ones with a return value of 1 // virtual int mprimitivefilter(PRIMITIVE* prim);Customize inter-layer movement using one virtual function for override. To override, you need to define a subclass of the CJocrPrim class. Please refer to Override (Cluster Extraction) for more information.
// Move the ones with return value 1 virtual int mojifilter(PRIMITIVE* prim); Input PRIMITIVE* prim; // Primitive to be evaluated Return Value 1...prim is all or part of a character 0...prim is neither all nor part of a character
virtual int mojifilter(PRIMITIVE* prim) { int width = prim->xmax - prim->xmin; int height = prim->ymax - prim->ymin; if(width <= mdpi / 2 && height <= mdpi / 2) return(1); else return(0); }
// Primitives // Get the size to save the primitive area // Return: // Size of buffer required to save all primitive content int mgetsavesize(); // Save the layers and other information of the primitives // Input/Output: // char* buffer; Buffer to save the content of the primitives // The size obtained from mgetsavesize is required // The buffer contains the following data: // +----------------------+ // | Number of valid primitives n | 4bytes // +----------------------+ // | PRIMITIVE 0 | sizeof(PRIMITIVE) // +----------------------+ // | PRIMITIVE 1 | sizeof(PRIMITIVE) // +----------------------+ // | PRIMITIVE ... | sizeof(PRIMITIVE) // +----------------------+ // | PRIMITIVE n - 1 | sizeof(PRIMITIVE) // +----------------------+ // Return: // 0....Normal termination // Negative...Error int makesavebuffer(char* buffer); // Load the layers and other information of the primitives // Assumption: The same image and the same connectivity conditions (4-connectivity or 8-connectivity) have been used in makeprim // Note: The buffer obtained from mgetsavesize and the buffer provided to mreflectloadbuffer are slightly different // Input: // int rvalidnum; First 4 bytes of the buffer obtained from mgetsavebuffer (number of valid primitives) // char* buffer; Buffer obtained from mgetsavebuffer without the first 4 bytes // +----------------------+ // | PRIMITIVE 0 | sizeof(PRIMITIVE) // +----------------------+ // | PRIMITIVE 1 | sizeof(PRIMITIVE) // +----------------------+ // | PRIMITIVE ... | sizeof(PRIMITIVE) // +----------------------+ // | PRIMITIVE n - 1 | sizeof(PRIMITIVE) // +----------------------+ int mreflectloadbuffer(int rvalidnum,char* buffer); // 0....Normal termination // Negative...Error (including cases where the image or makeprim conditions are different) // Cluster information // Get the size to save the cluster // Input: // CLUSTER* pcluster; Cluster to get the save size // Return: // Size of buffer required to save the pcluster int mgetsaveclustersize(CLUSTER* pcluster); // Generate a cluster save buffer // Input: // CLUSTER* pcluster; Cluster to save // Input/Output: // char* buffer; Content of the cluster, requires size obtained from mgetsaveclustersize/0 // +----------------------+ // | CLUSTER | sizeof(CLUSTER) // +----------------------+-------------------- // | | sizeof(int) Pass the following to the second argument of mrellectclusterbuffer // +----------------------+ // | | sizeof(int) // +----------------------+ // | | sizeof(int) // +----------------------+ // Return: // 0....Normal termination // Negative...Error int makesaveclusterbuffer(CLUSTER* pcluster,char* buffer); // Load the cluster body (Load the cluster, allocate the pprim area, and then load the pprim area) // Load the layers and other information of the primitives // Assumption: The same image and the same connectivity conditions (4-connectivity or 8-connectivity) have been used in makeprim // Note: Before calling this function, allocate the space of sizeof(CLUSTER) and copy the first sizeof(CLUSTER) bytes of the buffer saved with mgetsaveclusterbuffer // Input: // CLUSTER* pcluster; Refer to the "Note" above // int* pi; Buffer obtained from mgetsavebuffer without the first sizeof(CLUSTER) bytes // Return: // 0....Normal termination // Negative...Error int mreflectclusterbuffer(CLUSTER* pcluster,int* pi);
int mgetmemoryinfo();
// Primitive structure editing // Set the upper limit of the number of insertable primitives // If the limit is reached, an error will be returned by medit_insert or medit_separate // In that case, dispose of the class once, then new again, then re-insert after msetinsertmax // Input: // int insertmax; The default value is 0, usually 10000 is sufficient for normal A3, 400dpi Japanese documents void msetinsertmax(int insertmax){minsertmax = insertmax;}
// Delete a primitive // Handles duplicate primitives // Input: // int flag; 1... Reflect in image data // PRIMITIVE* prim; Primitive (copying is not allowed as it uses the address) int medit_delete(int flag,PRIMITIVE* prim); int medit_delete(int flag,CLUSTER* pcluster); // Insert a primitive (if pjocrprim is this, it becomes a copy) // Input: // int flag; 1... Reflect in image data // CJocrPrim* pjocrprim; Instance of CJocrPrim to which prim/pcluster belongs // PRIMITIVE* prim; Inserted primitive (copying is not allowed as it uses the address) // CLUSTER* pcluster; Instance of CJocrPrim to which prim belongs // int left,top; Destination of movement int medit_insert(int flag,CJocrPrim* pjocrprim,PRIMITIVE* prim,int left,int top,PRIMITIVE*& priminsert); int medit_insert(int flag,CJocrPrim* pjocrprim,CLUSTER* pcluster,int left,int top); // Move a primitive (it is better to use this to avoid the high cost of copy+delete) // Input: // int flag; 1... Reflect in image data // PRIMITIVE* prim; Primitive (copying is not allowed as it uses the address) // int left,top; Destination of movement int medit_move(int flag,PRIMITIVE* prim,int left,int top); int medit_move(int flag,CLUSTER* pcluster,int left,int top);
// Cluster all primitives // Used for rendering and cluster movement int mallprim2cluster();
// Separate clusters (Pixel data does not fluctuate. There are no visible seams) // (Note: Initialization is faster than separation if there are many clusters to separate, as it is computationally expensive) // Input // int linenum; Number of line segments // int* px1; x-coordinate value of the starting point of the line segment // int* py1; y-coordinate value of the starting point of the line segment // int* px2; x-coordinate value of the ending point of the line segment // int* py2; y-coordinate value of the ending point of the line segment // CLUSTER* pcluster; Cluster to be separated // Return Value // 0.......Successful completion // Negative......Error int medit_separate(int linenum,int* px1,int* py1,int* px2,int* py2,CLUSTER* pcluster); int medit_sever(int linenum,int* px1,int* py1,int* px2,int* py2,CLUSTER* pcluster); // Separates line raster specified by a single primitive into line segments and line width
// Separates primitives along a polyline (connected set of line segments) // Input // int flag; 0...Not reflected in the bitmap // 1...Reflected in the bitmap // int bridgeflag; 0...No bridge processing // 1...Bridge processing // int horizontalflag; 0...Diagonal lines // 1...Horizontal/vertical lines (usually 0 is fine) // int pointnum; Number of points in the polyline // int* px; x-coordinate values of pointnum points // int* py; y-coordinate values of pointnum points // int lwidth; Line width // PRIMITIVE* prim; Original primitive, the divided primitives are inserted after deletion of prim // Return Value // 0.......Successful completion // Negative......Error int medit_separateline(int flag,int bridgeflag,int horizontalflag,int pointnum,int* px,int* py,int lwidth,PRIMITIVE* prim);
int mgetprim2rlbuffersize(); // Return the size of the buffer when converting the primitive structure to a buffer int mprim2rl(unsigned char* retbuffer); // Convert the primitive structure to a buffer // Input: // unsigned char* retbuffer; a buffer with the size obtained from mgetprim2rlbuffersize // Return: // 0.......Normal termination // Negative......Error int mrl2prim(unsigned char* buffer); // Reproduce the primitive structure // Input: // unsigned char* buffer; PRIMRL buffer obtained from mprim2rl // Return: // 0.......Normal termination // Negative......Error
// Buffer management is performed internally by the library // Input // PRIMITIVE* prim; Primitive // Output // unsigned char*& pdata; Bitmap // int& width; Width of bitmap (in pixels) // int& height; Height of bitmap (in pixels) // Get bitmap of cluster // Get bitmap of primitive void makebitmapprimitive(PRIMITIVE* prim,unsigned char*& pdata,int& width,int& height);
Table of Contents
manual homepage