// 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 modified
The 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