]> mj.ucw.cz Git - libucw.git/commitdiff
- detection of textured images
authorPavel Charvat <pavel.charvat@netcentrum.cz>
Sun, 27 Aug 2006 13:40:28 +0000 (15:40 +0200)
committerPavel Charvat <pavel.charvat@netcentrum.cz>
Sun, 27 Aug 2006 13:40:28 +0000 (15:40 +0200)
- playing with thresholds

cf/images
images/Makefile
images/config.c
images/image-sim-test.c
images/sig-init.c
images/sig-txt.c [new file with mode: 0644]
images/signature.h

index 7772e8587c2c4deee1a8954f4dd0ad31229775d5..9e5339853b009c6d524c078ac501c57326071b94 100644 (file)
--- a/cf/images
+++ b/cf/images
@@ -12,11 +12,13 @@ ImageSig {
 MinWidth       16
 MinHeight      16
 
-PreQuantThresholds     9 100 1000 1000 2000 4000 8000 10000 10000 20000 20000 40000 40000 40000 40000
+PreQuantThresholds     9 100 400 1000 2000 2000 4000 4000 4000 8000 8000 8000 10000 10000 10000
 PostQuantMinSteps      2
 PostQuantMaxSteps      10
 PostQuantThreshold     2
 
+TexturedThreshold      0.32
+
 }
 
 ######## Duplicates finder ######################################################
index 3283e44b3f499c51dc426c2c7108b5877ff98ae6..839a5f2d701e8fc46f6711f84fe9ea6a15bd9169 100644 (file)
@@ -6,7 +6,7 @@ PROGS+=$(addprefix $(o)/images/,image-tool image-dup-test image-sim-test)
 
 CONFIGS+=images
 
-LIBIMAGES_MODS=math config image scale color alpha io-main dup-init dup-cmp sig-dump sig-init sig-seg sig-cmp object
+LIBIMAGES_MODS=math config image scale color alpha io-main dup-init dup-cmp sig-dump sig-init sig-seg sig-txt sig-cmp object
 
 LIBIMAGES_LIBS=-lm
 
index 7b02cbfbb36c07628f184e42e59b445e769d4a20..a6e69a19886529c5a9b172e269256b63e5c60190 100644 (file)
@@ -19,6 +19,7 @@ uns *image_sig_prequant_thresholds;
 uns image_sig_postquant_min_steps;
 uns image_sig_postquant_max_steps;
 uns image_sig_postquant_threshold;
+double image_sig_textured_threshold;
 
 static struct cf_section sig_config = {
   CF_ITEMS{
@@ -28,6 +29,7 @@ static struct cf_section sig_config = {
     CF_UNS("PostQuantMinSteps", &image_sig_postquant_min_steps),
     CF_UNS("PostQuantMaxSteps", &image_sig_postquant_max_steps),
     CF_UNS("PostQuantThreshold", &image_sig_postquant_threshold),
+    CF_DOUBLE("TexturedThreshold", &image_sig_textured_threshold),
     CF_END
   }
 };
index 8116206fe8461c9ecb6dbad5f5e2d98d8cb58558..021dd7e675c0c5536881fd8be6134eca3ba65f58 100644 (file)
@@ -235,7 +235,10 @@ main(int argc, char **argv)
       TRY(image_sig_init(&it, &data, img1));
       image_sig_preprocess(&data);
       if (data.valid)
-       image_sig_segmentation(&data);
+        {
+         image_sig_segmentation(&data);
+         image_sig_detect_textured(&data);
+       }
       if (segmentation_name_1)
        write_segmentation(&data, segmentation_name_1);
       image_sig_finish(&data, &sig1);
@@ -248,7 +251,10 @@ main(int argc, char **argv)
       TRY(image_sig_init(&it, &data, img2));
       image_sig_preprocess(&data);
       if (data.valid)
-       image_sig_segmentation(&data);
+        {
+         image_sig_segmentation(&data);
+         image_sig_detect_textured(&data);
+       }
       if (segmentation_name_2)
        write_segmentation(&data, segmentation_name_2);
       image_sig_finish(&data, &sig2);
index 5b0b33f9b4a8af32ca0ec0c7b63c7c493d5ebab1..6c5e75e5bac98635f623b498fd2533f340f391de 100644 (file)
@@ -25,6 +25,7 @@ image_sig_init(struct image_thread *thread, struct image_sig_data *data, struct
 {
   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;
@@ -157,9 +158,9 @@ image_sig_preprocess(struct image_sig_data *data)
          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]));
-         sum[3] += block->v[3] * block->area;
-         sum[4] += block->v[4] * block->area;
-         sum[5] += block->v[5] * block->area;
+         sum[3] += block->v[3] * block->area / 2;
+         sum[4] += block->v[4] * block->area / 2;
+         sum[5] += block->v[5] * block->area / 2;
         }
     }
 
@@ -185,6 +186,7 @@ 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;
   
@@ -308,7 +310,10 @@ compute_image_signature(struct image_thread *thread, struct image_signature *sig
     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;
diff --git a/images/sig-txt.c b/images/sig-txt.c
new file mode 100644 (file)
index 0000000..3673c11
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ *     Image Library -- Detection of textured images
+ *
+ *     (c) 2006 Pavel Charvat <pchar@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
+ */
+
+#define LOCAL_DEBUG
+
+#include "sherlock/sherlock.h"
+#include "images/images.h"
+#include "images/signature.h"
+#include "images/math.h"
+
+#include <string.h>
+
+#define MAX_CELLS_COLS 4
+#define MAX_CELLS_ROWS 4
+
+void
+image_sig_detect_textured(struct image_sig_data *data)
+{
+  uns cols = data->cols;
+  uns rows = data->rows;
+  uns cell_cols = MIN(cols, MAX_CELLS_COLS);
+  uns cell_rows = MIN(rows, MAX_CELLS_ROWS);
+  uns cell_x[MAX_CELLS_COLS + 1];
+  uns cell_y[MAX_CELLS_ROWS + 1];
+  uns i, j;
+  u32 cnt[IMAGE_REG_MAX];
+
+  DBG("Detecting textured image... cols=%u rows=%u cell_cols=%u cell_rows=%u", cols, rows, cell_cols, cell_rows);
+  
+  /* Compute cells boundaries */
+  for (i = 1, j = 0; i < cell_cols; i++)
+    cell_x[i] = fast_div_u32_u8(j += cols, cell_cols);
+  cell_x[0] = 0;
+  cell_x[cell_cols] = cols;
+  for (i = 1, j = 0; i < cell_rows; i++)
+    cell_y[i] = fast_div_u32_u8(j += rows, cell_rows);
+  cell_y[0] = 0;
+  cell_y[cell_rows] = rows;
+
+  /* Preprocess blocks */
+  for (uns i = 0; i < data->regions_count; i++)
+    for (struct image_sig_block *block = data->regions[i].blocks; block; block = block->next)
+      block->region = i;
+  
+  /* Process cells */
+  double e = 0;
+  for (uns j = 0; j < cell_rows; j++)
+    for (uns i = 0; i < cell_cols; i++)
+      {
+       uns cell_area = 0;
+        bzero(cnt, data->regions_count * sizeof(u32));
+       struct image_sig_block *b1 = data->blocks + cell_x[i] + cell_y[i] * cols, *b2;
+        for (uns y = cell_y[j]; y < cell_y[j + 1]; y++, b1 += cols)
+         {
+           b2 = b1;
+            for (uns x = cell_x[i]; x < cell_x[i + 1]; x++, b2++)
+             {
+               cnt[b2->region]++;
+               cell_area++;
+             }
+         }
+       for (uns k = 0; k < data->regions_count; k++)
+         {
+           int a = data->blocks_count * cnt[k] - cell_area * data->regions[k].count; 
+           e += (double)a * a / ((double)isqr(data->regions[k].count) * cell_area);
+         }
+      }
+
+  DBG("Coefficient=%g", (double)e / (data->regions_count * data->blocks_count));
+
+  /* Threshold */
+  if (e <= image_sig_textured_threshold * data->regions_count * data->blocks_count)
+    {
+      data->flags |= IMAGE_SIG_TEXTURED;
+      DBG("Image is textured.");
+    }
+  else
+    DBG("Image is not textured.");
+}
index aeb649673358db0e60495374962e3b1addca5678..8c332cf3ab31c513cddd99898862dcbe8f1bdbaf 100644 (file)
@@ -5,6 +5,7 @@
 extern uns image_sig_min_width, image_sig_min_height;
 extern uns *image_sig_prequant_thresholds;
 extern uns image_sig_postquant_min_steps, image_sig_postquant_max_steps, image_sig_postquant_threshold;
+extern double image_sig_textured_threshold;
 
 #define IMAGE_VEC_F    6
 #define IMAGE_REG_F    IMAGE_VEC_F
@@ -24,11 +25,14 @@ struct image_region {
   u16 wb;                      /* normalized weight */
 } PACKED;
 
+#define IMAGE_SIG_TEXTURED     0x1
+
 /* Image signature (10 + len * 16 bytes) */
 struct image_signature {
   byte len;                    /* Number of regions */
-  byte df;                     /* average f dist */
-  u16 dh;                      /* average h dist */
+  byte flags;                  /* IMAGE_SIG_xxx */
+  byte df;                     /* Average f dist */
+  u16 dh;                      /* Average h dist */
   struct image_vector vec;     /* Combination of all regions... simple signature */
   struct image_region reg[IMAGE_REG_MAX];/* Feature vector for every region */
 } PACKED;
@@ -51,6 +55,7 @@ struct image_sig_block {
   struct image_sig_block *next;                /* linked list */
   u32 x, y;                            /* block position */
   byte area;                           /* block area in pixels (usually 16) */
+  byte region;                         /* region index */
   byte v[IMAGE_VEC_F];                 /* feature vector */
 };
 
@@ -72,6 +77,7 @@ struct image_sig_data {
   u32 rows;
   u32 full_cols;
   u32 full_rows;
+  u32 flags;
   u32 area;
   u32 valid;
   u32 blocks_count;
@@ -92,6 +98,10 @@ void image_sig_cleanup(struct image_sig_data *data);
 
 void image_sig_segmentation(struct image_sig_data *data);
 
+/* sig-txt.c */
+
+void image_sig_detect_textured(struct image_sig_data *data);
+
 /* sig-cmp.c */
 
 #define IMAGE_SIG_DIST_SCALE (3 + 3 + 8 + 16)