Please note: There is no warranty or support for the applications below. They are supplied free of charge. We cannot be held responsible for damage caused to your computer. If you are unsure about any aspect of installing this software then please do not proceed.
All the code on this page is provided under the GPL licence.

 * Copyright 2009-2011 Florent Autrusseau.
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  GNU General Public License for more details.
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <>.

Goal: This software was used in a subjective experiment, whose goal was to determine the visibility threshold of a watermarking technique in the wavelet domain.
A new subjective protocol is proposed here.
Please, read carefully the "Experiment" section below if you intend to run the test.

    Unix-like systems

    Windows (as a dev-cpp project)

Random display:
I recommend using these files, which use a random order for displaying the images:  and

For Octave/Matlab source code, please check below.

Two papers are related to this experiment
If you are using this source code for your work, please, cite:

      • F. Autrusseau, S. David, V. Pankajakshan, P. Campisi, "A perceptually driven hybrid additive-multiplicative watermarking technique in the wavelet domain", in Electronic Imaging: Media Watermarking, Security and Forensics XIII, San Francisco, USA, 23-27 Jan. 2011. pdf paper
      • F. Autrusseau, S. David and Vinod Pankajakshan, "A Subjective Study of Visibility Thresholds for wavelet domain watermarking", in IEEE International Conference on Image Processing, ICIP'2010, pp. 201-204, Hong Kong, Sept. 26-29, 2010. pdf paper


    To compile this code, you will need:
       - The libit library: download
       - The Simple Directmedia Layer library (SDL): download
       - The SDL_Image library: download

    On Unix-like systems, a Make should work.
     If not, here's a brief explanation.

    For MS Windows OS, please read the whole installation process  here.

    Important note:
    For some reasons, it seems that the program crashes on "Windows Vista". I guess this is due to a SDL bug on Vista.

    The observers are asked to modulate two distinct embedding parameters, this is done in 4 steps:
    - Modulate one embedding parameter with the UP / DOWN ARROWS (until we get just below visibility threshold),
    - Validate this first selection with the SPACE BAR,
    - Modulate the second embedding parameter with the LEFT / RIGHT ARROWS (before visibility Th),
    - Hit RETURN to validate. (note that observers can still use the up/down arrows at this step).

    Note: It is impossible to validate (return) until both parameters have been modified
    Optional: The observer can tune the embedding strength step by pressing the 1, 2, ... 9 keys (the default step is set to 2).
    You can reset the watermarked image to it's original version by pressing "o" anytime.

    The file playlist2.txt is loaded for every trial, here's an example of playlist file:
    1      (curve equation 1: stands for linear equation during embedding (ax+b), 2: stands for ax^2+b, and 3: stands for a.sqrt(x)+b)
    30    (number of input images)
    farm.bmp   (image name, should be in the same folder as 'viewimages.exe')
    4                      (number of wavelet decompositions steps)
    1                      (wavelet level index, see decomposition below)
    1                      (wavelet orientation index, see decomposition below)
    plane.bmp  (image #2)
    caps.bmp  (image #3)
    ...    (until image #30)

    Note that you can use your own playlist file.
    You will have to give the playlist name as an argument (i.e. C:\YOUR_PATH> viewimages.exe myplaylist.txt)

    Here is an alternative image set (along with its playlist file)

        Wavelet indexes:

        Here are the wavelet indexes in the playlist file:

           DWT decomposition index

      If you need to change the input images, you will have to put them in the same directory as the viewimages executable.

      Here are the images we used during our experiment (Images are from the Kodak Database:

    "caps" "caps"

    "caps" "caps"


      Once the test is finished, an output file is generated, the file name indicates the date and hour:

      Please, send this output file to Florent<dot>Autrusseau<at>univ-nantes<dot>fr

      Please, let me know in your email which input images you have used.

    • GNU Octave code:

    package is a piece of GNU Octave code which does the watermark embedding only (not the whole subjective experiment).

    Hopefully, this code should work with Matlab.

    A brief explanation:
    The function is as follows:
    MarkedImg = Octave_WavJND(Eqn_coef, level, orientation, filename, a_val, b_val)

    * "Eqn_coef"  is either 0.5, 1, or 2
    it corresponds to the power parameter (c) in:
    y = x + (a.|x|.^c + b). w
    * "level" and "orientation" are wavelet sub-bands positions (only horizontal and vertical sub-bands have been tested during the subjective experiment and with a 3 level wavelet decomp)
    * "filename" is the image name (without any extension)
    * "a_val" & "b_val" are the strength parameters in the equation above.
       - If "a_val" & "b_val" are omitted, the code will grab the coefficients provided by the observers (in files "a_and_b_...txt"
        - If, for the given input image, no "a_val" & "b_val" are available, the user will be asked for "a" & "b" values.
        - If "a_val" & "b_val" are both set to 0, a polynomial fitting ( Levenberg-Marquardt nonlinear regression) will be performed based on the observers' optimal curves.

    Type "help Octave_WavJND" in octave for further details.

    You'll need some of the octave-forge packages (at least "image", but maybe some more...).
    Here are a few scripts to interface Gnu Octave with Plot (as a replacement of gnuplot), and with ImageJ (instead of imshow or imagesc using AquaTerm). Tested only on a Mac !

    A few examples:

    MarkedLighthouse_3_3 = Octave_WavJND(0.5, 3, 3, 'lighthouse');

    Will embed a watermark in SB [3,3] for the "lighthouse" image, using the sqrt equation ("a" and "b" will be grabbed from the file "a_and_b_sqrt.txt").

    MarkedMotorbikes_1_3 = Octave_WavJND(2, 1, 3, 'motorbikes');

    Will embed a watermark in SB [1,3] for the "motorbikes" image, using the ^2 equation (as "a" and "b" are not in the file "a_and_b_pow.txt", the user will be asked to give some values - give it a try with .2 and .2-).

    MarkedCapsOptim_2_1 = Octave_WavJND(x, 2, 1, 'caps',0,0);

    Will embed a watermark in SB [2,1] for the "caps image, using a least square polynomial fitting to model the three different equations. You'll have to set "DispPlots" to 1 in "Octave_WavJND.m" if you want to have the plots displayed.