00001
00020 #include "mfcpch.h"
00021 #include <stdlib.h>
00022 #include <math.h>
00023 #include <string.h>
00024 #include <ctype.h>
00025 #ifdef __UNIX__
00026 #include <assert.h>
00027 #endif
00028 #include "tessvars.h"
00029 #include "stderr.h"
00030 #include "img.h"
00031 #include "evnts.h"
00032 #include "showim.h"
00033 #include "hosthplb.h"
00034 #include "grphics.h"
00035 #include "evnts.h"
00036 #include "adaptions.h"
00037 #include "matmatch.h"
00038 #include "secname.h"
00039
00040 #define EXTERN
00041
00044 EXTERN BOOL_VAR (tessedit_display_mm, FALSE, "Display matrix matches");
00045 EXTERN BOOL_VAR (tessedit_mm_debug, FALSE,
00046 "Print debug information for matrix matcher");
00047 EXTERN INT_VAR (tessedit_mm_prototype_min_size, 3,
00048 "Smallest number of samples in a cluster for a prototype to be used");
00051
00052 #define BB_COLOUR 0
00053 #define BW_COLOUR 1
00054 #define WB_COLOUR 3
00055 #define UB_COLOUR 5
00056 #define BU_COLOUR 7
00057 #define UU_COLOUR 9
00058 #define WU_COLOUR 11
00059 #define UW_COLOUR 13
00060 #define WW_COLOUR 15
00061
00062 #define BINIM_BLACK 0
00063 #define BINIM_WHITE 1
00064
00068 float matrix_match(
00069 IMAGE *image1,
00070 IMAGE *image2) {
00071 ASSERT_HOST (image1->get_bpp () == 1 && image2->get_bpp () == 1);
00072
00073 if (image1->get_xsize () >= image2->get_xsize ())
00074 return match1 (image1, image2);
00075 else
00076 return match1 (image2, image1);
00077 }
00078
00079
00087 float match1(
00088 IMAGE *image_w,
00089 IMAGE *image_n) {
00090 INT32 x_offset;
00091 INT32 y_offset;
00092 INT32 x_size = image_w->get_xsize ();
00093 INT32 y_size;
00094 INT32 x_size2 = image_n->get_xsize ();
00095 INT32 y_size2;
00096 IMAGE match_image;
00097 IMAGELINE imline_w;
00098 IMAGELINE imline_n;
00099 IMAGELINE match_imline;
00100 INT32 x;
00101 INT32 y;
00102 float sum = 0.0;
00103
00104 x_offset = (image_w->get_xsize () - image_n->get_xsize ()) / 2;
00105
00106 ASSERT_HOST (x_offset >= 0);
00107 match_imline.init (x_size);
00108
00109 sum = 0;
00110
00111 if (image_w->get_ysize () < image_n->get_ysize ()) {
00112 y_size = image_n->get_ysize ();
00113 y_size2 = image_w->get_ysize ();
00114 y_offset = (y_size - y_size2) / 2;
00115
00116 if (tessedit_display_mm && !tessedit_mm_use_prototypes)
00117 tprintf ("I1 (%d, %d), I2 (%d, %d), MI (%d, %d)\n", x_size,
00118 image_w->get_ysize (), x_size2, image_n->get_ysize (),
00119 x_size, y_size);
00120
00121 match_image.create (x_size, y_size, 4);
00122
00123 for (y = 0; y < y_offset; y++) {
00124 image_n->fast_get_line (0, y, x_size2, &imline_n);
00125 for (x = 0; x < x_size2; x++) {
00126 if (imline_n.pixels[x] == BINIM_BLACK) {
00127 sum += -1;
00128 match_imline.pixels[x] = UB_COLOUR;
00129 }
00130 else {
00131 match_imline.pixels[x] = UW_COLOUR;
00132 }
00133 }
00134 match_image.fast_put_line (x_offset, y, x_size2, &match_imline);
00135 }
00136
00137 for (y = y_offset + y_size2; y < y_size; y++) {
00138 image_n->fast_get_line (0, y, x_size2, &imline_n);
00139 for (x = 0; x < x_size2; x++) {
00140 if (imline_n.pixels[x] == BINIM_BLACK) {
00141 sum += -1.0;
00142 match_imline.pixels[x] = UB_COLOUR;
00143 }
00144 else {
00145 match_imline.pixels[x] = UW_COLOUR;
00146 }
00147 }
00148 match_image.fast_put_line (x_offset, y, x_size2, &match_imline);
00149 }
00150
00151 for (y = y_offset; y < y_offset + y_size2; y++) {
00152 image_w->fast_get_line (0, y - y_offset, x_size, &imline_w);
00153 image_n->fast_get_line (0, y, x_size2, &imline_n);
00154 for (x = 0; x < x_offset; x++) {
00155 if (imline_w.pixels[x] == BINIM_BLACK) {
00156 sum += -1.0;
00157 match_imline.pixels[x] = BU_COLOUR;
00158 }
00159 else {
00160 match_imline.pixels[x] = WU_COLOUR;
00161 }
00162 }
00163
00164 for (x = x_offset + x_size2; x < x_size; x++) {
00165 if (imline_w.pixels[x] == BINIM_BLACK) {
00166 sum += -1.0;
00167 match_imline.pixels[x] = BU_COLOUR;
00168 }
00169 else {
00170 match_imline.pixels[x] = WU_COLOUR;
00171 }
00172 }
00173
00174 for (x = x_offset; x < x_offset + x_size2; x++) {
00175 if (imline_n.pixels[x - x_offset] == imline_w.pixels[x]) {
00176 sum += 1.0;
00177 if (imline_w.pixels[x] == BINIM_BLACK)
00178 match_imline.pixels[x] = BB_COLOUR;
00179 else
00180 match_imline.pixels[x] = WW_COLOUR;
00181 }
00182 else {
00183 sum += -1.0;
00184 if (imline_w.pixels[x] == BINIM_BLACK)
00185 match_imline.pixels[x] = BW_COLOUR;
00186 else
00187 match_imline.pixels[x] = WB_COLOUR;
00188 }
00189 }
00190
00191 match_image.fast_put_line (0, y, x_size, &match_imline);
00192 }
00193 }
00194 else {
00195 y_size = image_w->get_ysize ();
00196 y_size2 = image_n->get_ysize ();
00197 y_offset = (y_size - y_size2) / 2;
00198
00199 if (tessedit_display_mm && !tessedit_mm_use_prototypes)
00200 tprintf ("I1 (%d, %d), I2 (%d, %d), MI (%d, %d)\n", x_size,
00201 image_w->get_ysize (), x_size2, image_n->get_ysize (),
00202 x_size, y_size);
00203
00204 match_image.create (x_size, y_size, 4);
00205
00206 for (y = 0; y < y_offset; y++) {
00207 image_w->fast_get_line (0, y, x_size, &imline_w);
00208 for (x = 0; x < x_size; x++) {
00209 if (imline_w.pixels[x] == BINIM_BLACK) {
00210 sum += -1;
00211 match_imline.pixels[x] = BU_COLOUR;
00212 }
00213 else {
00214 match_imline.pixels[x] = WU_COLOUR;
00215 }
00216 }
00217 match_image.fast_put_line (0, y, x_size, &match_imline);
00218 }
00219
00220 for (y = y_offset + y_size2; y < y_size; y++) {
00221 image_w->fast_get_line (0, y, x_size, &imline_w);
00222 for (x = 0; x < x_size; x++) {
00223 if (imline_w.pixels[x] == BINIM_BLACK) {
00224 sum += -1;
00225 match_imline.pixels[x] = BU_COLOUR;
00226 }
00227 else {
00228 match_imline.pixels[x] = WU_COLOUR;
00229 }
00230 }
00231 match_image.fast_put_line (0, y, x_size, &match_imline);
00232 }
00233
00234 for (y = y_offset; y < y_offset + y_size2; y++) {
00235 image_w->fast_get_line (0, y, x_size, &imline_w);
00236 image_n->fast_get_line (0, y - y_offset, x_size2, &imline_n);
00237 for (x = 0; x < x_offset; x++) {
00238 if (imline_w.pixels[x] == BINIM_BLACK) {
00239 sum += -1.0;
00240 match_imline.pixels[x] = BU_COLOUR;
00241 }
00242 else {
00243 match_imline.pixels[x] = WU_COLOUR;
00244 }
00245 }
00246
00247 for (x = x_offset + x_size2; x < x_size; x++) {
00248 if (imline_w.pixels[x] == BINIM_BLACK) {
00249 sum += -1.0;
00250 match_imline.pixels[x] = BU_COLOUR;
00251 }
00252 else {
00253 match_imline.pixels[x] = WU_COLOUR;
00254 }
00255 }
00256
00257 for (x = x_offset; x < x_offset + x_size2; x++) {
00258 if (imline_n.pixels[x - x_offset] == imline_w.pixels[x]) {
00259 sum += 1.0;
00260 if (imline_w.pixels[x] == BINIM_BLACK)
00261 match_imline.pixels[x] = BB_COLOUR;
00262 else
00263 match_imline.pixels[x] = WW_COLOUR;
00264 }
00265 else {
00266 sum += -1.0;
00267 if (imline_w.pixels[x] == BINIM_BLACK)
00268 match_imline.pixels[x] = BW_COLOUR;
00269 else
00270 match_imline.pixels[x] = WB_COLOUR;
00271 }
00272 }
00273
00274 match_image.fast_put_line (0, y, x_size, &match_imline);
00275 }
00276 }
00277
00278 #ifndef GRAPHICS_DISABLED
00279 if (tessedit_display_mm && !tessedit_mm_use_prototypes) {
00280 tprintf ("Match score %f\n", 1.0 - sum / (x_size * y_size));
00281 display_images(image_w, image_n, &match_image);
00282 }
00283 #endif
00284
00285 if (tessedit_mm_debug)
00286 tprintf ("Match score %f\n", 1.0 - sum / (x_size * y_size));
00287
00288 return (1.0 - sum / (x_size * y_size));
00289 }
00290
00291
00295 void display_images(IMAGE *image_w, IMAGE *image_n, IMAGE *match_image) {
00296 WINDOW w_im_window;
00297 WINDOW n_im_window;
00298 WINDOW match_window;
00299 #ifndef GRAPHICS_DISABLED
00300 GRAPHICS_EVENT event;
00301 INT16 i;
00302
00303
00304 w_im_window = create_window ("Image 1", SCROLLINGWIN, 20, 100,
00305 10 * image_w->get_xsize (), 10 * image_w->get_ysize (),
00306 0, image_w->get_xsize (), 0, image_w->get_ysize (),
00307 TRUE, FALSE, FALSE, TRUE);
00308
00309 clear_view_surface(w_im_window);
00310 show_sub_image (image_w,
00311 0, 0,
00312 image_w->get_xsize (), image_w->get_ysize (),
00313 w_im_window, 0, 0);
00314
00315 line_color_index(w_im_window, RED);
00316 for (i = 1; i < image_w->get_xsize (); i++) {
00317 move2d (w_im_window, i, 0);
00318 draw2d (w_im_window, i, image_w->get_ysize ());
00319 }
00320 for (i = 1; i < image_w->get_ysize (); i++) {
00321 move2d (w_im_window, 0, i);
00322 draw2d (w_im_window, image_w->get_xsize (), i);
00323 }
00324
00325
00326 n_im_window = create_window ("Image 2", SCROLLINGWIN, 240, 100,
00327 10 * image_n->get_xsize (), 10 * image_n->get_ysize (),
00328 0, image_n->get_xsize (), 0, image_n->get_ysize (),
00329 TRUE, FALSE, FALSE, TRUE);
00330
00331 clear_view_surface(n_im_window);
00332 show_sub_image (image_n,
00333 0, 0,
00334 image_n->get_xsize (), image_n->get_ysize (),
00335 n_im_window, 0, 0);
00336
00337 line_color_index(n_im_window, RED);
00338 for (i = 1; i < image_n->get_xsize (); i++) {
00339 move2d (n_im_window, i, 0);
00340 draw2d (n_im_window, i, image_n->get_ysize ());
00341 }
00342 for (i = 1; i < image_n->get_ysize (); i++) {
00343 move2d (n_im_window, 0, i);
00344 draw2d (n_im_window, image_n->get_xsize (), i);
00345 }
00346 overlap_picture_ops(TRUE);
00347
00348
00349 match_window = create_window ("Match Result", SCROLLINGWIN, 460, 100,
00350 10 * match_image->get_xsize (), 10 * match_image->get_ysize (),
00351 0, match_image->get_xsize (), 0, match_image->get_ysize (),
00352 TRUE, FALSE, FALSE, TRUE);
00353
00354 clear_view_surface(match_window);
00355 show_sub_image (match_image,
00356 0, 0,
00357 match_image->get_xsize (), match_image->get_ysize (),
00358 match_window, 0, 0);
00359
00360 line_color_index(match_window, RED);
00361 for (i = 1; i < match_image->get_xsize (); i++) {
00362 move2d (match_window, i, 0);
00363 draw2d (match_window, i, match_image->get_ysize ());
00364 }
00365 for (i = 1; i < match_image->get_ysize (); i++) {
00366 move2d (match_window, 0, i);
00367 draw2d (match_window, match_image->get_xsize (), i);
00368 }
00369 overlap_picture_ops(TRUE);
00370
00371 await_event(match_window, TRUE, ANY_EVENT, &event);
00372 destroy_window(w_im_window);
00373 destroy_window(n_im_window);
00374 destroy_window(match_window);
00375 }
00376
00377
00381 WINDOW display_image(IMAGE *image,
00382 const char *title,
00383 INT32 x,
00384 INT32 y,
00385 BOOL8 wait) {
00386 WINDOW im_window;
00387 INT16 i;
00388 GRAPHICS_EVENT event;
00389
00390
00391 im_window = create_window (title, SCROLLINGWIN, x, y,
00392 10 * image->get_xsize (), 10 * image->get_ysize (),
00393 0, image->get_xsize (), 0, image->get_ysize (),
00394 TRUE, FALSE, FALSE, TRUE);
00395
00396 clear_view_surface(im_window);
00397 show_sub_image (image,
00398 0, 0,
00399 image->get_xsize (), image->get_ysize (), im_window, 0, 0);
00400
00401 line_color_index(im_window, RED);
00402 for (i = 1; i < image->get_xsize (); i++) {
00403 move2d (im_window, i, 0);
00404 draw2d (im_window, i, image->get_ysize ());
00405 }
00406 for (i = 1; i < image->get_ysize (); i++) {
00407 move2d (im_window, 0, i);
00408 draw2d (im_window, image->get_xsize (), i);
00409 }
00410 overlap_picture_ops(TRUE);
00411
00412 if (wait)
00413 await_event(im_window, TRUE, ANY_EVENT, &event);
00414
00415 return im_window;
00416 }
00417 #endif