]> mj.ucw.cz Git - libucw.git/blobdiff - images/sig-init.c
Added the local copy of the regex library back.
[libucw.git] / images / sig-init.c
index 5b0b33f9b4a8af32ca0ec0c7b63c7c493d5ebab1..60b53350548ee642554565df51f3521d475d33fa 100644 (file)
@@ -9,22 +9,24 @@
 
 #undef LOCAL_DEBUG
 
-#include "sherlock/sherlock.h"
-#include "lib/math.h"
+#include "lib/lib.h"
 #include "lib/fastbuf.h"
 #include "lib/conf.h"
-#include "images/math.h"
 #include "images/images.h"
+#include "images/math.h"
+#include "images/error.h"
 #include "images/color.h"
 #include "images/signature.h"
 
 #include <alloca.h>
+#include <math.h>
 
 int
-image_sig_init(struct image_thread *thread, struct image_sig_data *data, struct image *image)
+image_sig_init(struct image_context *ctx, struct image_sig_data *data, struct image *image)
 {
   ASSERT((image->flags & IMAGE_PIXEL_FORMAT) == COLOR_SPACE_RGB);
   data->image = image;
+  data->flags = 0;
   data->cols = (image->cols + 3) >> 2;
   data->rows = (image->rows + 3) >> 2;
   data->full_cols = image->cols >> 2;
@@ -32,7 +34,7 @@ image_sig_init(struct image_thread *thread, struct image_sig_data *data, struct
   data->blocks_count = data->cols * data->rows;
   if (data->blocks_count >= 0x10000)
     {
-      image_thread_err(thread, IMAGE_ERR_INVALID_DIMENSIONS, "Image too large for implemented signature algorithm.");
+      IMAGE_ERROR(ctx, IMAGE_ERROR_INVALID_DIMENSIONS, "Image too large for implemented signature algorithm.");
       return 0;
     }
   data->blocks = xmalloc(data->blocks_count * sizeof(struct image_sig_block));
@@ -102,14 +104,14 @@ image_sig_preprocess(struct image_sig_data *data)
                    }
                  for (; x < 4; x++)
                    {
-                     *tp = tp[-square_cols];
+                     *tp = tp[-(int)square_cols];
                      tp++;
                    }
                }
              for (; y < 4; y++)
                for (x = 0; x < 4; x++)
                  {
-                   *tp = tp[-square_rows * 4];
+                   *tp = tp[-(int)square_rows * 4];
                    tp++;
                  }
              block->area = square_cols * square_rows;
@@ -154,9 +156,9 @@ image_sig_preprocess(struct image_sig_data *data)
            }
 
          /* Extract energies in LH, HL and HH bands */
-         block->v[3] = fast_sqrt_u16(isqr(t[8]) + isqr(t[9]) + isqr(t[12]) + isqr(t[13]));
-         block->v[4] = fast_sqrt_u16(isqr(t[2]) + isqr(t[3]) + isqr(t[6]) + isqr(t[7]));
-         block->v[5] = fast_sqrt_u16(isqr(t[10]) + isqr(t[11]) + isqr(t[14]) + isqr(t[15]));
+         block->v[3] = fast_sqrt_u32(isqr(t[8]) + isqr(t[9]) + isqr(t[12]) + isqr(t[13]));
+         block->v[4] = fast_sqrt_u32(isqr(t[2]) + isqr(t[3]) + isqr(t[6]) + isqr(t[7]));
+         block->v[5] = fast_sqrt_u32(isqr(t[10]) + isqr(t[11]) + isqr(t[14]) + isqr(t[15]));
          sum[3] += block->v[3] * block->area;
          sum[4] += block->v[4] * block->area;
          sum[5] += block->v[5] * block->area;
@@ -177,21 +179,20 @@ image_sig_preprocess(struct image_sig_data *data)
     data->valid = 1;
 }
 
-static double image_sig_inertia_scale[3] = { 3, 1, 0.3 };
-
 void
 image_sig_finish(struct image_sig_data *data, struct image_signature *sig)
 {
   for (uns i = 0; i < IMAGE_VEC_F; i++)
     sig->vec.f[i] = data->f[i];
   sig->len = data->regions_count;
+  sig->flags = data->flags;
   if (!sig->len)
     return;
-  
+
   /* For each region */
   u64 w_total = 0;
-  uns w_border = (MIN(data->cols, data->rows) + 3) / 4;
-  uns w_mul = 127 * 256 / w_border;
+  uns w_border = MIN(data->cols, data->rows) * image_sig_border_size;
+  int w_mul = w_border ? image_sig_border_bonus * 256 / (int)w_border : 0;
   for (uns i = 0; i < sig->len; i++)
     {
       struct image_sig_region *r = data->regions + i;
@@ -207,11 +208,11 @@ image_sig_finish(struct image_sig_data *data, struct image_signature *sig)
       sig->reg[i].f[5] = r->a[5];
 
       /* Compute coordinates centroid and region weight */
-      u64 x_avg = 0, y_avg = 0, w_sum = 0;
+      u64 x_sum = 0, y_sum = 0, w_sum = 0;
       for (struct image_sig_block *b = r->blocks; b; b = b->next)
         {
-         x_avg += b->x;
-         y_avg += b->y;
+         x_sum += b->x;
+         y_sum += b->y;
          uns d = b->x;
          d = MIN(d, b->y);
          d = MIN(d, data->cols - b->x - 1);
@@ -219,28 +220,29 @@ image_sig_finish(struct image_sig_data *data, struct image_signature *sig)
          if (d >= w_border)
            w_sum += 128;
          else
-           w_sum += 128 + (d - w_border) * w_mul / 256;
+           w_sum += 128 + (int)(w_border - d) * w_mul / 256;
        }
       w_total += w_sum;
       r->w_sum = w_sum;
-      x_avg /= r->count;
-      y_avg /= r->count;
-      DBG("  centroid=(%u %u)", (uns)x_avg, (uns)y_avg);
+      uns x_avg = x_sum / r->count;
+      uns y_avg = y_sum / r->count;
+      DBG("  centroid=(%u %u)", x_avg, y_avg);
 
       /* Compute normalized inertia */
       u64 sum1 = 0, sum2 = 0, sum3 = 0;
       for (struct image_sig_block *b = r->blocks; b; b = b->next)
         {
          uns inc2 = isqr(x_avg - b->x) + isqr(y_avg - b->y);
-         uns inc1 = sqrt(inc2);
+         uns inc1 = fast_sqrt_u32(inc2);
          sum1 += inc1;
          sum2 += inc2;
          sum3 += inc1 * inc2;
        }
-      sig->reg[i].h[0] = CLAMP(image_sig_inertia_scale[0] * sum1 * ((3 * M_PI * M_PI) / 2) * pow(r->count, -1.5), 0, 65535);
-      sig->reg[i].h[1] = CLAMP(image_sig_inertia_scale[1] * sum2 * ((4 * M_PI * M_PI * M_PI) / 2) / ((u64)r->count * r->count), 0, 65535);
-      sig->reg[i].h[2] = CLAMP(image_sig_inertia_scale[2] * sum3 * ((5 * M_PI * M_PI * M_PI * M_PI) / 2) * pow(r->count, -2.5), 0, 65535);
-
+      sig->reg[i].h[0] = CLAMP(image_sig_inertia_scale[0] * sum1 * ((3 * M_PI * M_PI) / 2) * pow(r->count, -1.5), 0, 255);
+      sig->reg[i].h[1] = CLAMP(image_sig_inertia_scale[1] * sum2 * ((4 * M_PI * M_PI * M_PI) / 2) / ((u64)r->count * r->count), 0, 255);
+      sig->reg[i].h[2] = CLAMP(image_sig_inertia_scale[2] * sum3 * ((5 * M_PI * M_PI * M_PI * M_PI) / 2) * pow(r->count, -2.5), 0, 255);
+      sig->reg[i].h[3] = (uns)x_avg * 127 / data->cols;
+      sig->reg[i].h[4] = (uns)y_avg * 127 / data->rows;
     }
 
   /* Compute average differences */
@@ -259,16 +261,16 @@ image_sig_finish(struct image_sig_data *data, struct image_signature *sig)
           {
            uns d = 0;
            for (uns k = 0; k < IMAGE_REG_F; k++)
-             d += isqr(sig->reg[i].f[k] - sig->reg[j].f[k]);
-           df += sqrt(d);
+             d += image_sig_cmp_features_weights[k] * isqr(sig->reg[i].f[k] - sig->reg[j].f[k]);
+           df += fast_sqrt_u32(d);
            d = 0;
            for (uns k = 0; k < IMAGE_REG_H; k++)
-             d += isqr(sig->reg[i].h[k] - sig->reg[j].h[k]);
-           dh += sqrt(d);
+             d += image_sig_cmp_features_weights[k + IMAGE_REG_F] * isqr(sig->reg[i].h[k] - sig->reg[j].h[k]);
+           dh += fast_sqrt_u32(d);
            cnt++;
           }
-      sig->df = CLAMP(df / cnt, 1, 255);
-      sig->dh = CLAMP(dh / cnt, 1, 65535);
+      sig->df = CLAMP(df / cnt, 1, 0xffff);
+      sig->dh = CLAMP(dh / cnt, 1, 0xffff);
     }
   DBG("Average regions difs: df=%u dh=%u", sig->df, sig->dh);
 
@@ -278,11 +280,15 @@ image_sig_finish(struct image_sig_data *data, struct image_signature *sig)
     {
       struct image_sig_region *r = data->regions + i;
       wa -= sig->reg[i].wa = CLAMP(r->count * 128 / data->blocks_count, 1, (int)(wa - i));
-      wb -= sig->reg[i].wb = CLAMP(r->w_sum * 128 / w_total, 1, (int)(wa - i));
+      wb -= sig->reg[i].wb = CLAMP(r->w_sum * 128 / w_total, 1, (int)(wb - i));
     }
   sig->reg[0].wa = wa;
   sig->reg[0].wb = wb;
 
+  /* Store image dimensions */
+  sig->cols = data->image->cols;
+  sig->rows = data->image->rows;
+
   /* Dump regions features */
 #ifdef LOCAL_DEBUG
   for (uns i = 0; i < sig->len; i++)
@@ -301,14 +307,17 @@ image_sig_cleanup(struct image_sig_data *data)
 }
 
 int
-compute_image_signature(struct image_thread *thread, struct image_signature *sig, struct image *image)
+compute_image_signature(struct image_context *ctx, struct image_signature *sig, struct image *image)
 {
   struct image_sig_data data;
-  if (!image_sig_init(thread, &data, image))
+  if (!image_sig_init(ctx, &data, image))
     return 0;
   image_sig_preprocess(&data);
   if (data.valid)
-    image_sig_segmentation(&data);
+    {
+      image_sig_segmentation(&data);
+      image_sig_detect_textured(&data);
+    }
   image_sig_finish(&data, sig);
   image_sig_cleanup(&data);
   return 1;