22#include <allheaders.h>
90 Image pix = pixConvertTo8(input,
false);
93 int width = pixGetWidth(input);
94 int height = pixGetHeight(input);
101 input = pixErodeGray(pix, 3, 3);
106 pix = pixBlockconv(input, 1, 1);
109 if (rotation !=
nullptr) {
110 float radians_clockwise = 0.0f;
112 radians_clockwise = *rotation;
113 }
else if (randomizer !=
nullptr) {
117 input = pixRotate(pix, radians_clockwise, L_ROTATE_AREA_MAP, L_BRING_IN_WHITE, 0, 0);
119 *rotation = radians_clockwise;
125 if (exposure >= 3 || exposure == 1) {
131 input = pixErodeGray(pix, 3, 3);
137 int erosion_offset = 0;
150 l_uint32 *data = pixGetData(input);
151 for (
int y = 0;
y < height; ++
y) {
152 for (
int x = 0;
x < width; ++
x) {
153 int pixel = GET_DATA_BYTE(data,
x);
154 if (randomizer !=
nullptr) {
158 pixel -= (2 *
x +
y) * 32 / (height + width);
160 pixel += erosion_offset;
167 SET_DATA_BYTE(data,
x, pixel);
169 data += pixGetWpl(input);
180 bool smooth_noise,
bool blur,
int box_reduction,
TRand *randomizer,
181 std::vector<TBOX> *boxes) {
184 if ((white_noise || smooth_noise) && randomizer->
SignedRand(1.0) > 0.0) {
188 Image pixn = pixAddGaussianNoise(distorted, 8.0);
191 distorted = pixBlockconv(pixn, 1, 1);
197 if (blur && randomizer->
SignedRand(1.0) > 0.0) {
198 Image blurred = pixBlockconv(distorted, 1, 1);
205 if (boxes !=
nullptr) {
206 for (
auto &b : *boxes) {
207 b.scale(1.0f / box_reduction);
208 if (b.width() <= 0) {
209 b.set_right(b.left() + 1);
213 if (invert && randomizer->
SignedRand(1.0) < -0) {
214 pixInvert(distorted, distorted);
223 std::vector<TBOX> *boxes) {
224 if (pix !=
nullptr && *pix !=
nullptr) {
225 width = pixGetWidth(*pix);
226 height = pixGetHeight(*pix);
228 float *im_coeffs =
nullptr;
229 float *box_coeffs =
nullptr;
230 l_int32 incolor =
ProjectiveCoeffs(width, height, randomizer, &im_coeffs, &box_coeffs);
231 if (pix !=
nullptr && *pix !=
nullptr) {
233 Image transformed = pixProjective(*pix, im_coeffs, incolor);
234 if (transformed ==
nullptr) {
235 tprintf(
"Projective transformation failed!!\n");
241 if (boxes !=
nullptr) {
243 for (
auto &b : *boxes) {
246 projectiveXformSampledPt(box_coeffs, box.
left(), height - box.
top(), &x1, &y1);
247 projectiveXformSampledPt(box_coeffs, box.
right(), height - box.
bottom(), &x2, &y2);
248 TBOX new_box1(x1, height - y2, x2, height - y1);
249 projectiveXformSampledPt(box_coeffs, box.
left(), height - box.
bottom(), &x1, &y1);
250 projectiveXformSampledPt(box_coeffs, box.
right(), height - box.
top(), &x2, &y2);
251 TBOX new_box2(x1, height - y1, x2, height - y2);
255 lept_free(im_coeffs);
256 lept_free(box_coeffs);
264 float **box_coeffs) {
266 Pta *src_pts = ptaCreate(4);
267 ptaAddPt(src_pts, 0.0f, 0.0f);
268 ptaAddPt(src_pts, width, 0.0f);
269 ptaAddPt(src_pts, width, height);
270 ptaAddPt(src_pts, 0.0f, height);
279 shear = shear >= 0.0 ? shear * shear : -shear * shear;
281 if (shear < -factors[
FN_X0]) {
282 shear = -factors[
FN_X0];
284 if (shear > factors[
FN_X1]) {
285 shear = factors[
FN_X1];
291 factors[
i] *= 5.0 / 8.0;
295 factors[
i] *= factors[
i];
299 Pta *dest_pts = ptaCreate(4);
300 ptaAddPt(dest_pts, factors[
FN_X0] * width, factors[
FN_Y0] * height);
301 ptaAddPt(dest_pts, (1.0f - factors[
FN_X1]) * width, factors[
FN_Y1] * height);
302 ptaAddPt(dest_pts, (1.0f - factors[
FN_X1] + shear) * width, (1 - factors[
FN_Y2]) * height);
303 ptaAddPt(dest_pts, (factors[
FN_X0] + shear) * width, (1 - factors[
FN_Y3]) * height);
304 getProjectiveXformCoeffs(dest_pts, src_pts, im_coeffs);
305 getProjectiveXformCoeffs(src_pts, dest_pts, box_coeffs);
306 ptaDestroy(&src_pts);
307 ptaDestroy(&dest_pts);
308 return factors[
FN_INCOLOR] > 0.5f ? L_BRING_IN_WHITE : L_BRING_IN_BLACK;
const float kRotationRange
const int kExposureFactor
void tprintf(const char *format,...)
Image PrepareDistortedPix(const Image pix, bool perspective, bool invert, bool white_noise, bool smooth_noise, bool blur, int box_reduction, TRand *randomizer, std::vector< TBOX > *boxes)
int ProjectiveCoeffs(int width, int height, TRand *randomizer, float **im_coeffs, float **box_coeffs)
void GeneratePerspectiveDistortion(int width, int height, TRand *randomizer, Image *pix, std::vector< TBOX > *boxes)
Image DegradeImage(Image input, int exposure, TRand *randomizer, float *rotation)
TBOX bounding_union(const TBOX &box) const
TDimension bottom() const
double SignedRand(double range)