]> mj.ucw.cz Git - libucw.git/blob - images/sig-txt.c
Random: Implemented new pseudo-random interface.
[libucw.git] / images / sig-txt.c
1 /*
2  *      Image Library -- Detection of textured images
3  *
4  *      (c) 2006 Pavel Charvat <pchar@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #undef LOCAL_DEBUG
11
12 #include <ucw/lib.h>
13 #include <images/images.h>
14 #include <images/signature.h>
15 #include <images/math.h>
16
17 #include <string.h>
18
19 #define MAX_CELLS_COLS 4
20 #define MAX_CELLS_ROWS 4
21
22 void
23 image_sig_detect_textured(struct image_sig_data *data)
24 {
25   if (image_sig_textured_threshold <= 0)
26     {
27       DBG("Zero textured threshold.");
28       return;
29     }
30
31   uint cols = data->cols;
32   uint rows = data->rows;
33   uint cell_cols = MIN((cols + 1) / 2, MAX_CELLS_COLS);
34   uint cell_rows = MIN((rows + 1) / 2, MAX_CELLS_ROWS);
35   uint cell_x[MAX_CELLS_COLS + 1];
36   uint cell_y[MAX_CELLS_ROWS + 1];
37   uint i, j;
38   u32 cnt[IMAGE_REG_MAX];
39
40   if (cell_cols * cell_rows < 4)
41     {
42       DBG("Image is not textured.");
43       return;
44     }
45
46   DBG("Detecting textured image... cols=%u rows=%u cell_cols=%u cell_rows=%u", cols, rows, cell_cols, cell_rows);
47
48   /* Compute cells boundaries */
49   for (i = 1, j = 0; i < cell_cols; i++)
50     cell_x[i] = fast_div_u32_u8(j += cols, cell_cols);
51   cell_x[0] = 0;
52   cell_x[cell_cols] = cols;
53   for (i = 1, j = 0; i < cell_rows; i++)
54     cell_y[i] = fast_div_u32_u8(j += rows, cell_rows);
55   cell_y[0] = 0;
56   cell_y[cell_rows] = rows;
57
58   /* Preprocess blocks */
59   for (uint i = 0; i < data->regions_count; i++)
60     for (struct image_sig_block *block = data->regions[i].blocks; block; block = block->next)
61       block->region = i;
62
63   /* Process cells */
64   double e = 0;
65   for (uint j = 0; j < cell_rows; j++)
66     for (uint i = 0; i < cell_cols; i++)
67       {
68         uint cell_area = 0;
69         bzero(cnt, data->regions_count * sizeof(u32));
70         struct image_sig_block *b1 = data->blocks + cell_x[i] + cell_y[j] * cols, *b2;
71         for (uint y = cell_y[j]; y < cell_y[j + 1]; y++, b1 += cols)
72           {
73             b2 = b1;
74             for (uint x = cell_x[i]; x < cell_x[i + 1]; x++, b2++)
75               {
76                 cnt[b2->region]++;
77                 cell_area++;
78               }
79           }
80         for (uint k = 0; k < data->regions_count; k++)
81           {
82             int a = data->blocks_count * cnt[k] - cell_area * data->regions[k].count;
83             e += (double)a * a / ((double)isqr(data->regions[k].count) * cell_area);
84           }
85       }
86
87   DBG("Coefficient=%g", (double)e / (data->regions_count * data->blocks_count));
88
89   /* Threshold */
90   if (e < image_sig_textured_threshold * data->regions_count * data->blocks_count)
91     {
92       data->flags |= IMAGE_SIG_TEXTURED;
93       DBG("Image is textured.");
94     }
95   else
96     DBG("Image is not textured.");
97 }