changeset 18:3bdb67e76858

mse opt.
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 30 Jan 2009 12:46:49 +0100
parents 824d192e5614
children 0fffb6f03ebf
files Meerwald/cmp_koch_sig.c Meerwald/wm_koch_e.c
diffstat 2 files changed, 118 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/Meerwald/cmp_koch_sig.c	Thu Jan 29 18:28:05 2009 +0100
+++ b/Meerwald/cmp_koch_sig.c	Fri Jan 30 12:46:49 2009 +0100
@@ -132,6 +132,15 @@
     else
       corr--;
 
+  if (verbose > 1) {
+    for (i = 0; i < nbit_signature2; i++)
+      fprintf(stderr, "%d", get_signature1_bit(i % nbit_signature1));
+    fprintf(stderr, "\n");
+    for (i = 0; i < nbit_signature2; i++)
+      fprintf(stderr, "%d", get_signature2_bit(i));
+    fprintf(stderr, "\n");
+  }
+
   if (correlation_only)
     fprintf(out, "%lf\n", (double) corr / nbit_signature2);
   else {
--- a/Meerwald/wm_koch_e.c	Thu Jan 29 18:28:05 2009 +0100
+++ b/Meerwald/wm_koch_e.c	Fri Jan 30 12:46:49 2009 +0100
@@ -2,10 +2,54 @@
 #include "dct.h"
 #include "signature.h"
 #include "coord.h"
+#include "gray.h"
 #include "pgm.h"
 
 char *progname;
 
+double sign(double x) {
+    if (x >= 0.0) return 1.0;
+    else return -1.0;
+}
+
+double try_modif(gray **image_block, double **dcts, int c1, int c2, double w1, double w2) {
+    int i, j;
+    gray **altered_block;
+    double **altered_dcts;
+    double sum;
+
+    altered_block = alloc_grays_8x8();
+    altered_dcts = alloc_coeffs_8x8();
+
+    for (i = 0; i < 8; i++) {
+        memcpy(altered_dcts[i], dcts[i], sizeof(double) * 8);
+    }
+        
+    // put the changed coefficients back to black
+    altered_dcts[c1 / NJPEG][c1 % NJPEG] = w1;
+    altered_dcts[c2 / NJPEG][c2 % NJPEG] = w2;
+
+    dequantize_8x8(altered_dcts);
+
+    idct_block_8x8(altered_dcts, altered_block, 0, 0);
+    
+    // compute MSE
+    sum = 0.0;
+    for (i = 0; i < 8; i++) {
+        for (j = 0; j < 8; j++) {  
+            double ib = image_block[i][j];
+            double ab = altered_block[i][j];
+            sum += (ib - ab) * (ib - ab);
+        }
+    }
+    sum /= 64.0;
+    
+    free(altered_block);
+    free(altered_dcts);
+    
+    return sum;
+}
+
 void usage(void) {
   fprintf(stderr, "usage: %s [-h] [-l n] [-o file] [-q n] [-v n] -s file file\n", progname);
   fprintf(stderr, "\t-h\t\tprint usage\n");
@@ -44,6 +88,7 @@
 
   gray **image;
   double **dcts;
+  gray **image_block;
 
   progname = argv[0]; 
 
@@ -161,6 +206,7 @@
   init_quantum_JPEG_lumin(quantization);
 
   dcts = alloc_coeffs_8x8();
+  image_block = alloc_grays_8x8();
 
   if ((coords = alloc_coords(nbit_signature)) == NULL) {
     fprintf(stderr, "%s: unable to allocate memory\n", progname);
@@ -183,7 +229,12 @@
     int c1, c2;
     double v1, v2;
     double w1, w2;
-    double diff, abs_diff;
+    double best_w1, best_w2;
+    double diff;
+    double mod;
+    double try;
+    double best_mse;
+    int no_mse_opt = 0;
 
     // randomly select a block, check to get distinct blocks
     // (don't watermark a block twice)
@@ -195,6 +246,8 @@
     // do the forward 8x8 DCT of that block
     fdct_block_8x8(image, xb * NJPEG, yb * NJPEG, dcts);
 
+    copy_grays_to_block(image_block, image, xb*NJPEG, yb*NJPEG, NJPEG, NJPEG);
+
     // randomly select two distinct coefficients from block
     // only accept coefficients in the middle frequency range
     do {
@@ -213,40 +266,69 @@
     v1 = dcts[c1 / NJPEG][c1 % NJPEG];
     v2 = dcts[c2 / NJPEG][c2 % NJPEG];
 
+    best_w1 = DBL_MAX, best_w2 = DBL_MAX;
+    try = 0.0;
+    best_mse = DBL_MAX;
+
     diff = fabs(v1) - fabs(v2);
-    abs_diff = (fabs(diff) + quality) / 2.0;
 
-    // modify coefficient's relationship to embed signature bit
-    // using mean square error to minimize error
-    if (get_signature_bit(n)) {
-      if (diff < quality) {
-        // we have to impose the relationship, does not occur naturally
-        w1 = (v1 > 0.0) ? (v1 + abs_diff) : (v1 - abs_diff);
-        w2 = v2;
-      }
-      else {
+    if (get_signature_bit(n)) 
+      mod = fabs(quality - ( fabs(v1) - fabs(v2) ));
+    else
+      mod = fabs(quality -  (fabs(v2) - fabs(v1)));
+    
+    if (verbose > 2)
+        fprintf(stderr, "%d / %d: %.2f %.2f %.2f | %d\n", xb, yb, diff, v1, v2, get_signature_bit(n));    
+    
+    while (try <= mod) {
         w1 = v1;
         w2 = v2;
-      }
-    }
-    else {
-      if (diff > -quality) {
-        // force the relationship
-        w1 = v1;
-        w2 = (v2 > 0.0) ? (v2 + abs_diff) : (v2 - abs_diff);
-      }
-      else {
-        w1 = v1;
-        w2 = v2;
-      }
+
+        // modify coefficient's relationship to embed signature bit
+        // using mean square error to minimize error
+        if (get_signature_bit(n)) {
+          if (diff < quality) {
+            // we have to impose the relationship, does not occur naturally
+            w1 = sign(v1)*(fabs(v1) + mod - try);
+            w2 = sign(v2)*(fabs(v2) - try);
+          }
+        }
+        else {
+          if (diff > -quality) {
+            // force the relationship
+            w2 = sign(v2)*(fabs(v2) + mod - try);
+            w1 = sign(v1)*(fabs(v1) - try);
+          }
+        }
+
+        double mse = try_modif(image_block, dcts, c1, c2, w1, w2);
+        if (mse < best_mse) {
+            best_w1 = w1;
+            best_w2 = w2;
+            best_mse = mse;
+        }
+        
+        if (verbose > 2)
+            fprintf(stderr, "%d / %d: MSE %.2f %.2f; %.2f: %.2f %.2f\n", xb, yb, mse, best_mse, try, w1, w2);
+        
+        if (fabs(mse) == 1e-3)
+            break;
+        
+        if (fabs(fabs(w1) - fabs(w2) + quality) > 1e-3)
+            break;
+
+        if (no_mse_opt)
+            break;
+
+        try += 0.05;
     }
 
     if (verbose > 1)
-      fprintf(stderr, "  %f -> %f, %f -> %f\n", v1, w1, v2, w2);
+      fprintf(stderr, "  %f -> %f, %f -> %f\n", v1, best_w1, v2, best_w2);
 
     // put the changed coefficients back to black
-    dcts[c1 / NJPEG][c1 % NJPEG] = w1;
-    dcts[c2 / NJPEG][c2 % NJPEG] = w2;
+    dcts[c1 / NJPEG][c1 % NJPEG] = best_w1;
+    dcts[c2 / NJPEG][c2 % NJPEG] = best_w2;
 
     // the obvious :-)
     dequantize_8x8(dcts);
@@ -257,6 +339,7 @@
     n++;
   }
 
+  free_grays(image_block);
   free_coeffs(dcts);
 
   pgm_writepgminit(out, cols, rows, maxval, 0);

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.