Fixed issue 1134

git-svn-id: https://tesseract-ocr.googlecode.com/svn/trunk@1082 d0cd1f9f-072b-0410-8dd7-cf729c803f20
This commit is contained in:
theraysmith@gmail.com 2014-04-25 01:07:26 +00:00
parent 84e0f6470f
commit 42bfdc21d8
4 changed files with 63 additions and 13 deletions

View File

@ -28,6 +28,49 @@
#include <stdio.h>
#include <string.h>
#include "host.h"
// TODO(rays) Put the rest of the helpers in the namespace.
namespace tesseract {
// A simple linear congruential random number generator, using Knuth's
// constants from:
// http://en.wikipedia.org/wiki/Linear_congruential_generator.
class TRand {
public:
TRand() : seed_(1) {}
// Sets the seed to the given value.
void set_seed(uinT64 seed) {
seed_ = seed;
}
// Returns an integer in the range 0 to MAX_INT32.
inT32 IntRand() {
Iterate();
return seed_ >> 33;
}
// Returns a floating point value in the range [-range, range].
double SignedRand(double range) {
return range * 2.0 * IntRand() / MAX_INT32 - range;
}
// Returns a floating point value in the range [0, range].
double UnsignedRand(double range) {
return range * IntRand() / MAX_INT32;
}
private:
// Steps the generator to the next value.
void Iterate() {
seed_ *= 6364136223846793005;
seed_ += 1442695040888963407;
}
// The current value of the seed.
uinT64 seed_;
};
} // namespace tesseract
// Remove newline (if any) at the end of the string.
inline void chomp_string(char *str) {
int last_index = strlen(str) - 1;

View File

@ -22,6 +22,7 @@
#include <stdlib.h>
#include "allheaders.h" // from leptonica
#include "helpers.h" // For TRand.
namespace tesseract {
@ -34,17 +35,13 @@ const int kSaltnPepper = 5;
// Min sum of width + height on which to operate the ramp.
const int kMinRampSize = 1000;
static unsigned int random_seed = 0x18273645;
#ifndef rand_r // _MSC_VER, ANDROID
#define rand_r(random_seed) rand()
#endif // _MSC_VER
// Degrade the pix as if by a print/copy/scan cycle with exposure > 0
// corresponding to darkening on the copier and <0 lighter and 0 not copied.
// Exposures in [-2,2] are most useful, with -3 and 3 being extreme.
// If rotation is NULL, rotation is skipped. If *rotation is non-zero, the pix
// is rotated by *rotation else it is randomly rotated and *rotation is
// modified.
//
// HOW IT WORKS:
// Most of the process is really dictated by the fact that the minimum
// available convolution is 3X3, which is too big really to simulate a
@ -65,7 +62,8 @@ static unsigned int random_seed = 0x18273645;
// the edges.
// Finally a greyscale ramp provides a continuum of effects between exposure
// levels.
Pix* DegradeImage(Pix* input, int exposure, float* rotation) {
Pix* DegradeImage(Pix* input, int exposure, TRand* randomizer,
float* rotation) {
Pix* pix = pixConvertTo8(input, false);
pixDestroy(&input);
input = pix;
@ -85,12 +83,11 @@ Pix* DegradeImage(Pix* input, int exposure, float* rotation) {
pixDestroy(&input);
// A small random rotation helps to make the edges jaggy in a realistic way.
if (rotation != NULL) {
float radians_clockwise;
float radians_clockwise = 0.0f;
if (*rotation) {
radians_clockwise = *rotation;
} else {
radians_clockwise = (2.0*rand_r(&random_seed)/RAND_MAX - 1.0) *
kRotationRange;
} else if (randomizer != NULL) {
radians_clockwise = randomizer->SignedRand(kRotationRange);
}
input = pixRotate(pix, radians_clockwise,
@ -131,7 +128,8 @@ Pix* DegradeImage(Pix* input, int exposure, float* rotation) {
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
int pixel = GET_DATA_BYTE(data, x);
pixel += rand_r(&random_seed) % (kSaltnPepper*2 + 1) - kSaltnPepper;
if (randomizer != NULL)
pixel += randomizer->IntRand() % (kSaltnPepper*2 + 1) - kSaltnPepper;
if (height + width > kMinRampSize)
pixel -= (2*x + y) * 32 / (height + width);
pixel += erosion_offset;

View File

@ -24,12 +24,15 @@ struct Pix;
namespace tesseract {
class TRand;
// Degrade the pix as if by a print/copy/scan cycle with exposure > 0
// corresponding to darkening on the copier and <0 lighter and 0 not copied.
// If rotation is not NULL, the clockwise rotation in radians is saved there.
// The input pix must be 8 bit grey. (Binary with values 0 and 255 is OK.)
// The input image is destroyed and a different image returned.
struct Pix* DegradeImage(struct Pix* input, int exposure, float* rotation);
struct Pix* DegradeImage(struct Pix* input, int exposure, TRand* randomizer,
float* rotation);
} // namespace tesseract

View File

@ -43,6 +43,7 @@
#include "degradeimage.h"
#include "errcode.h"
#include "fileio.h"
#include "helpers.h"
#include "normstrngs.h"
#include "stringrenderer.h"
#include "tlog.h"
@ -55,6 +56,9 @@ using std::map;
using std::pair;
#endif
// A number with which to initialize the random number generator.
const int kRandomSeed = 0x18273645;
// The text input file.
STRING_PARAM_FLAG(text, "", "File name of text input to process");
@ -534,6 +538,8 @@ int main(int argc, char** argv) {
vector<float> page_rotation;
const char* to_render_utf8 = src_utf8.c_str();
tesseract::TRand randomizer;
randomizer.set_seed(kRandomSeed);
// We use a two pass mechanism to rotate images in both direction.
// The first pass(0) will rotate the images in random directions and
// the second pass(1) will mirror those rotations.
@ -560,7 +566,7 @@ int main(int argc, char** argv) {
rotation = -1 * page_rotation[page_num];
}
if (FLAGS_degrade_image) {
pix = DegradeImage(pix, FLAGS_exposure, &rotation);
pix = DegradeImage(pix, FLAGS_exposure, &randomizer, &rotation);
}
render.RotatePageBoxes(rotation);