00001
00020
00021
00022
00023 #include "pieces.h"
00024 #include "plotseg.h"
00025 #include "hideedge.h"
00026 #include "wordclass.h"
00027 #include "freelist.h"
00028 #include "blobs.h"
00029 #include "matchtab.h"
00030
00031
00032
00033
00034
00038 #define set_bounds_entry(array,index,top_left,bot_right) \
00039 ((array)[index].topleft = (top_left), \
00040 (array)[index].botright = (bot_right)) \
00041
00042
00043
00047 #define get_bounds_entry(array,index,top_left,bot_right) \
00048 ((top_left) = (array)[index].topleft, \
00049 (bot_right) = (array)[index].botright) \
00050
00051
00052
00053
00054
00055
00061 void break_pieces(TBLOB *blobs, SEAMS seams, INT16 start, INT16 end) {
00062 TESSLINE *outline = blobs->outlines;
00063 TBLOB *next_blob;
00064 INT16 x;
00065
00066 for (x = start; x < end; x++)
00067 reveal_seam ((SEAM *) array_value (seams, x));
00068
00069 next_blob = blobs->next;
00070
00071 while (outline && next_blob) {
00072 if (outline->next == next_blob->outlines) {
00073 outline->next = NULL;
00074 outline = next_blob->outlines;
00075 next_blob = next_blob->next;
00076 }
00077 else {
00078 outline = outline->next;
00079 }
00080 }
00081 }
00082
00083
00084
00089 void join_pieces(TBLOB *piece_blobs, SEAMS seams, INT16 start, INT16 end) {
00090 TBLOB *next_blob;
00091 TBLOB *blob;
00092 INT16 x;
00093 TESSLINE *outline;
00094 SEAM *seam;
00095
00096 for (x = 0, blob = piece_blobs; x < start; x++)
00097 blob = blob->next;
00098 next_blob = blob->next;
00099 outline = blob->outlines;
00100 if (!outline)
00101 return;
00102
00103 while (x < end) {
00104 seam = (SEAM *) array_value (seams, x);
00105 if (x - seam->widthn >= start && x + seam->widthp < end)
00106 hide_seam(seam);
00107 while (outline->next)
00108 outline = outline->next;
00109 outline->next = next_blob->outlines;
00110 next_blob = next_blob->next;
00111
00112 x++;
00113 }
00114 }
00115
00116
00117
00122 void hide_seam(SEAM *seam) {
00123 if (seam == NULL || seam->split1 == NULL)
00124 return;
00125 hide_edge_pair (seam->split1->point1, seam->split1->point2);
00126
00127 if (seam->split2 == NULL)
00128 return;
00129 hide_edge_pair (seam->split2->point1, seam->split2->point2);
00130
00131 if (seam->split3 == NULL)
00132 return;
00133 hide_edge_pair (seam->split3->point1, seam->split3->point2);
00134 }
00135
00136
00137
00142 void hide_edge_pair(EDGEPT *pt1, EDGEPT *pt2) {
00143 EDGEPT *edgept;
00144
00145 edgept = pt1;
00146 do {
00147 hide_edge(edgept);
00148 edgept = edgept->next;
00149 }
00150 while (!exact_point (edgept, pt2) && edgept != pt1);
00151 if (edgept == pt1) {
00152
00153
00154 }
00155 edgept = pt2;
00156 do {
00157 hide_edge(edgept);
00158 edgept = edgept->next;
00159 }
00160 while (!exact_point (edgept, pt1) && edgept != pt2);
00161 if (edgept == pt2) {
00162
00163
00164 }
00165 }
00166
00167
00168
00173 void reveal_seam(SEAM *seam) {
00174 if (seam == NULL || seam->split1 == NULL)
00175 return;
00176 reveal_edge_pair (seam->split1->point1, seam->split1->point2);
00177
00178 if (seam->split2 == NULL)
00179 return;
00180 reveal_edge_pair (seam->split2->point1, seam->split2->point2);
00181
00182 if (seam->split3 == NULL)
00183 return;
00184 reveal_edge_pair (seam->split3->point1, seam->split3->point2);
00185 }
00186
00187
00188
00193 void reveal_edge_pair(EDGEPT *pt1, EDGEPT *pt2) {
00194 EDGEPT *edgept;
00195
00196 edgept = pt1;
00197 do {
00198 reveal_edge(edgept);
00199 edgept = edgept->next;
00200 }
00201 while (!exact_point (edgept, pt2) && edgept != pt1);
00202 if (edgept == pt1) {
00203
00204
00205 }
00206 edgept = pt2;
00207 do {
00208 reveal_edge(edgept);
00209 edgept = edgept->next;
00210 }
00211 while (!exact_point (edgept, pt1) && edgept != pt2);
00212 if (edgept == pt2) {
00213
00214
00215 }
00216 }
00217
00218
00219
00224 void bounds_of_piece(BOUNDS_LIST bounds,
00225 INT16 start,
00226 INT16 end,
00227 TPOINT *extreme_tl,
00228 TPOINT *extreme_br) {
00229 TPOINT topleft;
00230 TPOINT botright;
00231 INT16 x;
00232
00233 get_bounds_entry(bounds, start, *extreme_tl, *extreme_br);
00234
00235 for (x = start + 1; x <= end; x++) {
00236 get_bounds_entry(bounds, x, topleft, botright);
00237
00238 extreme_tl->x = min (topleft.x, extreme_tl->x);
00239 extreme_tl->y = max (topleft.y, extreme_tl->y);
00240 extreme_br->x = max (botright.x, extreme_br->x);
00241 extreme_br->y = min (botright.y, extreme_br->y);
00242 }
00243 }
00244
00245
00246
00253 CHOICES classify_piece(TBLOB *pieces,
00254 SEAMS seams,
00255 INT16 start,
00256 INT16 end,
00257 INT32 fx,
00258 STATE *this_state,
00259 STATE *best_state,
00260 INT32 pass,
00261 INT32 blob_index) {
00262 STATE current_state;
00263 CHOICES choices;
00264 TBLOB *pblob;
00265 TBLOB *blob;
00266 TBLOB *nblob;
00267 INT16 x;
00268 SEARCH_STATE chunk_groups;
00269
00270 set_n_ones (¤t_state, array_count (seams));
00271
00272 join_pieces(pieces, seams, start, end);
00273 for (blob = pieces, pblob = NULL, x = 0; x < start; x++) {
00274 pblob = blob;
00275 blob = blob->next;
00276 }
00277 for (nblob = blob->next; x < end; x++)
00278 nblob = nblob->next;
00279 choices = classify_blob (pblob, blob, nblob, NULL, fx, "pieces:", White,
00280 this_state, best_state, pass, blob_index);
00281
00282 break_pieces(blob, seams, start, end);
00283 #ifndef GRAPHICS_DISABLED
00284 if (display_segmentations > 2) {
00285 chunk_groups = bin_to_chunks (¤t_state, array_count (seams));
00286 display_segmentation(pieces, chunk_groups);
00287 window_wait(segm_window);
00288 memfree(chunk_groups);
00289 }
00290 #endif
00291
00292 return (choices);
00293 }
00294
00295
00296
00304 CHOICES get_piece_rating(MATRIX ratings,
00305 TBLOB *blobs,
00306 SEAMS seams,
00307 INT16 start,
00308 INT16 end,
00309 INT32 fx,
00310 STATE *this_state,
00311 STATE *best_state,
00312 INT32 pass,
00313 INT32 blob_index) {
00314 CHOICES choices;
00315
00316 choices = matrix_get (ratings, start, end);
00317 if (choices == NOT_CLASSIFIED) {
00318 choices =
00319 classify_piece(blobs,
00320 seams,
00321 start,
00322 end,
00323 fx,
00324 this_state,
00325 best_state,
00326 pass,
00327 blob_index);
00328 matrix_put(ratings, start, end, choices);
00329 }
00330 return (choices);
00331 }
00332
00333
00334
00339 BOUNDS_LIST record_blob_bounds(TBLOB *blobs) {
00340 TBLOB *blob;
00341 BOUNDS_LIST bounds;
00342 TPOINT topleft;
00343 TPOINT botright;
00344 INT16 x = 0;
00345
00346 bounds = (BOUNDS_LIST) memalloc (count_blobs (blobs) * sizeof (BOUNDS));
00347
00348 iterate_blobs(blob, blobs) {
00349 blob_bounding_box(blob, &topleft, &botright);
00350 set_bounds_entry(bounds, x, topleft, botright);
00351 x++;
00352 }
00353 return (bounds);
00354 }
00355
00356
00357
00365 MATRIX record_piece_ratings(TBLOB *blobs) {
00366 BOUNDS_LIST bounds;
00367 INT16 num_blobs;
00368 INT16 x;
00369 INT16 y;
00370 TPOINT tp_topleft;
00371 TPOINT tp_botright;
00372 unsigned int topleft;
00373 unsigned int botright;
00374 MATRIX ratings;
00375 CHOICES choices;
00376
00377 bounds = record_blob_bounds (blobs);
00378 num_blobs = count_blobs (blobs);
00379 ratings = create_matrix (num_blobs);
00380
00381 for (x = 0; x < num_blobs; x++) {
00382 for (y = x; y < num_blobs; y++) {
00383 bounds_of_piece(bounds, x, y, &tp_topleft, &tp_botright);
00384 topleft = *(unsigned int *) &tp_topleft;
00385 botright = *(unsigned int *) &tp_botright;
00386 choices = get_match_by_bounds (topleft, botright);
00387 if (choices != NIL) {
00388 matrix_put(ratings, x, y, choices);
00389 }
00390 }
00391 }
00392 memfree(bounds);
00393 return (ratings);
00394 }