|
1 #include <stdarg.h> |
|
2 #include "tcl_interface.h" |
|
3 #include "project.h" |
|
4 #include "histogram.h" |
|
5 #include "bitmap.h" |
|
6 #include <stdio.h> |
|
7 #include <math.h> |
|
8 #include <cstdlib> |
|
9 #include "status_message.h" |
|
10 |
|
11 int docommand(char* fmt, ...); |
|
12 |
|
13 |
|
14 |
|
15 void draw_bitmap(int x, int y, char* xbm_file) |
|
16 { |
|
17 docommand(".t.f.c create bitmap %d %d -bitmap @%s", x, y, xbm_file); |
|
18 docommand("update"); |
|
19 } |
|
20 |
|
21 #define LINE_SKIP 5 |
|
22 #define DRAW_RAYS 0 |
|
23 #define DEBUG_PROJECT_HISTOGRAM 1 |
|
24 #define DRAW_PIXELS 0 |
|
25 #define PRINT_STATUS 1 |
|
26 |
|
27 Histogram* project_histogram(RLEMap* r, double cut_angle) |
|
28 { |
|
29 if (ENABLE_USER_INTERFACE) |
|
30 { |
|
31 docommand("update"); |
|
32 if(DRAW_RAYS) |
|
33 { |
|
34 docommand(".main_window.display.work_space delete project_ray"); |
|
35 } |
|
36 if(DRAW_PIXELS) |
|
37 { |
|
38 docommand(".t.f.c delete project_pixels"); |
|
39 } |
|
40 } |
|
41 int num_values = r->imageLength() / LINE_SKIP; |
|
42 int* ret_array = (int*) malloc (sizeof(int) * num_values); |
|
43 for(int current_value = 0; current_value < num_values; current_value++) |
|
44 { |
|
45 ret_array[current_value] = calculate_one_rle_ray_weight(r, cut_angle, current_value*LINE_SKIP); /* the real work */ |
|
46 } |
|
47 Histogram* h = new Histogram(num_values - 1, ret_array, cut_angle); |
|
48 if(PRINT_STATUS && ENABLE_USER_INTERFACE) |
|
49 { |
|
50 set_status("Deskewing: @%.3lf degrees, standard deviation = %.3lf", cut_angle, h->get_standard_dev()); |
|
51 } |
|
52 if(0) |
|
53 h->display(); |
|
54 return h; |
|
55 } |
|
56 |
|
57 inline double deg_to_rad(double deg) |
|
58 { |
|
59 return deg * (M_PI / 180.00); |
|
60 } |
|
61 |
|
62 int PRINT_RAYS = 0; |
|
63 |
|
64 int calculate_one_rle_ray_weight(RLEMap* rlemap, double cut_angle, int row_num) |
|
65 { |
|
66 /* cuts through b at cut_angle (cut angle in DEG) , adding up the weights */ |
|
67 /* of the pixels in the cut line */ |
|
68 /* RLEMap methodology: Translate the angular slope into rise/run slope, |
|
69 find out how many bits (how much run) to read horizontally before |
|
70 jumping upwards one bit. Make use of RLEMap::pixels_between(row,st,fi) */ |
|
71 /* possible optimizations: calculate this initial stuff "run_bits" "slope" |
|
72 once for each histogram, pass as args to this */ |
|
73 |
|
74 |
|
75 double slope; |
|
76 double float_run_bits; |
|
77 int y_update; |
|
78 double new_x; |
|
79 double rad_cut_angle = deg_to_rad(cut_angle); |
|
80 |
|
81 slope = tan(rad_cut_angle); |
|
82 float_run_bits = fabs((((double)1)/sin(rad_cut_angle)) * cos(rad_cut_angle)); |
|
83 |
|
84 int ray_weight = 0; |
|
85 |
|
86 double cur_x = 0; |
|
87 int cur_y = row_num; |
|
88 |
|
89 if(cut_angle < 0) |
|
90 y_update = -1; |
|
91 else |
|
92 y_update = 1; |
|
93 |
|
94 |
|
95 int image_height = rlemap->imageLength(); |
|
96 int image_width = rlemap->imageWidth(); |
|
97 |
|
98 while(((new_x = cur_x + float_run_bits) < image_width) && |
|
99 (cur_y >= 0) && (cur_y < image_height)) |
|
100 { |
|
101 /* watch out about going past rlemap bounds */ |
|
102 ray_weight += rlemap->pixels_between((int)cur_x, (int)new_x, cur_y); |
|
103 cur_x = new_x + 1; |
|
104 cur_y = cur_y + y_update; |
|
105 } |
|
106 |
|
107 /* and once more for posterity */ |
|
108 if((cur_y >= 0) && (cur_y < image_height) && (cur_x < image_width)) |
|
109 ray_weight += rlemap->pixels_between((int)cur_x, image_width, cur_y); |
|
110 |
|
111 if(1) |
|
112 if(DRAW_RAYS) |
|
113 { |
|
114 docommand(".main_window.display.work_space create line %d %d %d %d -fill blue -tags {project_ray IMAGE_TAG}", 0, row_num, (int)cur_x, (int)cur_y); |
|
115 } |
|
116 if(PRINT_RAYS) |
|
117 printf("---Ray weight for cut angle %lf = %d\n", cut_angle, ray_weight); |
|
118 return ray_weight; |
|
119 } |
|
120 |
|
121 |
|
122 |
|
123 |