]> AND Private Git Repository - canny.git/commitdiff
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
après remarques christophe
authorcouchot <jf.couchot@gmail.com>
Mon, 17 Nov 2014 08:16:55 +0000 (09:16 +0100)
committercouchot <jf.couchot@gmail.com>
Mon, 17 Nov 2014 08:16:55 +0000 (09:16 +0100)
code/canny_p3-p7-stc.py [deleted file]
code/canny_p3_stc.py [deleted file]
complexity.tex
intro.tex
ourapproach.tex
stc.tex

diff --git a/code/canny_p3-p7-stc.py b/code/canny_p3-p7-stc.py
deleted file mode 100644 (file)
index 6f00045..0000000
+++ /dev/null
@@ -1,600 +0,0 @@
-#-*- coding:utf-8 -*-
-import Image as im
-import numpy 
-from sys import argv
-from pylab import *
-import string
-import cv
-import os
-from random import *
-from math import *
-
-infinity = 1000000000
-
-
-#paths for cover and stego
-path_stego = '/home/couturie/ajeter/stego/'
-path_cover = '/home/couturie/ajeter/cover/'
-
-# forward part
-
-
-def dec(ch,n):    
-    l = len(ch)
-    acc = 0
-    for i in xrange(l):
-        if ch[i]==1:
-            acc = acc + 2**(n-i-1)        
-    return acc
-
-
-def bin(elem,n):
-    """Convertit un nombre en binaire"""
-    q = -1
-    res = [0 for i in xrange(n)]
-    i = 1
-    while q != 0:
-        q = elem // 2
-        r = elem % 2
-        res[n-i] =  r
-        elem = q
-        i+=1
-    return res
-
-
-
-def xorb(a,b):
-    return 1 if a != b else 0
-
-def xor(e1,e2,h):
-    e1b,e2b  = bin(e1,h),bin(e2,h)
-    d = dec([xorb(e1b[j],e2b[j]) for j in xrange(h)],h)
-    return d
-
-def lit(d,(indx,indy)):
-    if (indx,indy) in d :
-        return d[(indx,indy)]
-    else :
-        return 0
-
-
-
-
-def forward(H_hat,x,message,lnm,rho):
-    (h,w) = int(log(max(H_hat),2))+1, len(H_hat)
-    path = dict() 
-    nbblock = lnm
-    wght = [infinity for _ in xrange(int(2**h))] 
-    wght[0]=0    
-    newwght = [0 for _ in xrange(int(2**h))]
-#    rho = 1
-#    rho= [1 for _ in xrange(len(x))]
-    indx,indm = 0,0
-    i=0
-    while i < nbblock: # pour chaque bit du message
-        for j in xrange(w):   # pour chaque colonne de H_hat
-            #print indx, "en entrant",wght
-            k = 0
-            while k < int(2**h): # pour chaque ligne de H
-                w0 = wght[k] + x[indx]*rho[indx]
-                w1 = wght[xor(k,H_hat[j],h)] + (1-x[indx])*rho[indx]
-                if w1 < w0 :
-                    path[(indx,k)] = 1 
-                else : 
-                    if (indx,k) in path:
-                        del path[(indx,k)]
-                newwght[k] = min(w0,w1)
-                k +=1 
-            indx +=1
-            wght = [t for t in newwght]
-            #print " apres calcul",wght
-
-        for j in xrange(int(2**(h-1))):   # pour chaque colonne de H
-            wght[j] = wght[2*j + message[indm]]
-        wght = wght[:int(pow(2,h-1))] + [infinity for _ in xrange(int(pow(2,h)-pow(2,h-1)))]
-        indm +=1
-        i +=1
-    start = np.argmin(wght)
-    return (start,path)
-
-
-def backward(start,H_hat,x,message,lnm,path):
-    (h,w) = int(log(max(H_hat),2))+1, len(H_hat)
-    indx,indm = len(x)-1,lnm-1
-    state = 2*start + message[indm]
-    indm -=1
-    # l'initialisation de state n'est pas optimale...
-    nbblock = lnm
-    y=np.zeros(len(x))
-    i=0
-    while i < nbblock:
-        l = range(w)
-        l.reverse()
-        for j in l:   # pour chaque colonne de H_hat
-            y[indx] = lit(path,(indx,state))
-            state = xor(state,y[indx]*H_hat[j],h)
-            indx -=1
-        state = 2*state + message[indm]
-        indm -=1 
-        i +=1
-    return [int(t) for t in y]
-
-    
-
-
-
-def trouve_H_hat(n,m,h):
-    assert h ==7 
-    alpha = float(n)/m
-    assert alpha >= 1 
-    index = min(int(alpha),9)
-    mat = {
-        1 : [127],
-        2 : [71,109],
-        3 : [95, 101, 121],
-        4 : [81, 95, 107, 121],
-        5 : [75, 95, 97, 105, 117],
-        6 : [73, 83, 95, 103, 109, 123],
-        7 : [69, 77, 93, 107, 111, 115, 121],
-        8 : [69, 79, 81, 89, 93, 99, 107, 119],
-        9 : [69, 79, 81, 89, 93, 99, 107, 119, 125]
-        }[index]
-    return(mat, index*m)
-
-
-def stc(x,rho,message):
-    lnm = len(message)
-    (mat,taille_suff) = trouve_H_hat(len(x),len(message),7)
-    x_b = x[:taille_suff]
-    (start,path) = forward(mat,x_b,message,lnm,rho)
-    return (x_b,backward(start,mat,x_b,message,lnm,path),mat)
-
-
-
-
-
-def nbdif(x,y):
-    r,it = 0,0
-    l = len(y)
-    while it < l :
-        if x[it] != y[it] :
-            r +=1
-        it += 1
-    return float(r)/l 
-        
-
-
-
-
-
-def prod(H_hat,lnm,y):
-    (h,w) = int(log(max(H_hat),2))+1, len(H_hat)
-    i=0
-    H =[]
-    V=[0 for _ in range(len(y))]
-    sol=[]
-    while i < lnm: # pour chaque ligne 
-        V=[0 for _ in range(len(y))]    
-        k = max([(i-h+1)*w,0])
-        dec = max([i-h+1,0])
-        for j in xrange(min([i+1,h])): #nbre de blocks presents sur la ligne i
-            for l in xrange(w): # pour chaque collone de H_hat
-                V[k] = bin(H_hat[l],h)[h-i-1+j+dec]
-                k+=1
-                
-        sol.append(np.dot(np.array(V),np.array(y)))
-        i+=1
-        #H += [V]
-    #H = np.array(H)    
-    #y = np.array(y)
-    #print "dot",np.dot(H,y),H.shape
-    #print "sol",sol
-    return sol#list(np.dot(H,y))
-    
-def equiv(x,y): 
-    lx = len(x)
-    assert lx == len(y)
-    i=0
-    while i < lx :
-        if x[i] % 2 != y[i]%2 : 
-            return False
-        i += 1
-    return True
-        
-
-
-
-
-
-def conversion(nombre, base, epsilon = 0.00001 ):
-    ''' Soit nombre écrit en base 10, le retourne en base base'''
-    if not 2 <= base <= 36:
-        raise ValueError, "La base doit être entre 2 et 36"
-    if not base == 2 and '.' in str(nombre):
-        raise ValueError, "La partie décimale n'est pas gérée pour les bases\
-                           différentes de 2."
-    # IMPROVE : Convertir aussi la partie décimale, quand la base n'est pas égale
-    # à 2.
-    abc = string.digits + string.letters
-    result = ''
-    if nombre < 0:
-        nombre = -nombre
-        sign = '-'
-    else:
-        sign = ''
-    if '.' in str(nombre):
-        entier,decimal = int(str(nombre).split('.')[0]),\
-                         float('.'+str(nombre).split('.')[1])
-    else:
-        entier,decimal = int(str(nombre)),0
-    while entier !=0 :
-        entier, rdigit = divmod( entier, base )
-        result = abc[rdigit] + result
-    flotante, decimalBin = 1./float(base),''
-    while flotante > epsilon :
-        if decimal >= flotante:
-            decimalBin+='1'
-            decimal-=flotante
-        else :
-            decimalBin+='0'    
-        flotante = flotante/float(base)
-    if '1' in decimalBin :
-        reste = '.'+decimalBin
-        while reste[-1]=='0':
-            reste = reste[:-1]
-    else :
-        reste = ''
-    return sign + result + reste
-
-    
-def getBit(X,pos):
-    '''Récupère le bit en position pos de X.
-    Par exemple, getBit(8,1) = 0, puisque le bit le plus à droite de 8 = 1000 est 0.
-    On fera attention à ce que :
-        - on compte à partir du point,
-        - l'élément juste à gauche du point est en position 1,
-        - celui juste à droite est en position -1.'''
-    assert pos != 0
-    entier = conversion(X,2)
-    if '.' in entier:
-        entier, decimal = entier.split('.')  
-        if decimal == '0':
-            decimal = ''  
-    else:
-        decimal = ''
-    if '-' in entier:
-        entier = entier.replace('-','')
-    entier  = entier.zfill(abs(pos))
-    decimal = (decimal+'0'*abs(pos))[:max(len(decimal),abs(pos))]
-
-    return int(entier[len(entier)-pos]) if pos >0 else int(decimal[-pos-1])
-
-
-def setBit(X,pos,y):
-    '''Fixe le bit pos de X à la valeur y.
-    Le fonctionnement est similaire à getBit : 
-        - on compte à partir du point,
-        - l'élément juste à gauche du point est en position 1,
-        - celui juste à droite est en position -1.'''
-    assert pos != 0
-    entier = conversion(X,2)
-    if '.' in entier:
-        entier, decimal = entier.split('.')    
-    else:
-        decimal = ''
-    entier  = list(entier.zfill(abs(pos)))
-    decimal = list((decimal+'0'*abs(pos))[:max(len(decimal),abs(pos))])
-    if pos>0:
-        entier[len(entier)-pos]=str(int(y))
-    else:
-        decimal[-pos-1] = str(int(y))
-    if decimal == []:
-        return int(''.join(entier),2)
-    else:
-        S=0
-        for k in range(len(decimal)):
-            S += 1./2**(k+1)*int(decimal[k])
-        return float(str(int(''.join(entier),2))+'.'+str(S).split('.')[1])
-
-
-def a2b(a): 
-    ai = ord(a) 
-    return ''.join('01'[(ai >> x) & 1] for x in xrange(7, -1, -1)) 
-
-
-
-def a2b_list(L):
-    LL=[]
-    for i in L:
-        for j in list(a2b(i)):
-            LL.append(j)
-    return LL
-
-
-
-def toDecimal(x):
-    return sum(map(lambda z: int(x[z]) and 2**(len(x) - z - 1),
-                   range(len(x)-1, -1, -1)))            
-
-def conv_list_bit(L):
-    L2=[]
-    for j in range(len(L)/8):
-        L2.append(chr(toDecimal("".join(L[j*8:(j+1)*8]))))
-    return ''.join(L2)
-
-def Denary2Binary(n):
-    '''convert denary integer n to binary string bStr'''
-    bStr = ''
-    if n < 0:  raise ValueError, "must be a positive integer"
-    if n == 0: return '0'
-    while n > 0:
-        bStr = str(n % 2) + bStr
-        n = n >> 1
-    return bStr
-
-
-def compute_filter_sobel(level,image):
-    level2=level.copy()
-    level2= array(level2.getdata()).flatten()
-    l=0
-    for x in level2:
-        level2[l]=(x/2)*2
-        l+=1
-    level2_im=im.new('L',image.size)
-    level2_im.putdata(level2)
-
-    cv_im = cv.CreateImageHeader(image.size, cv.IPL_DEPTH_8U, 1)
-    cv.SetData(cv_im, level2_im.tostring())
-    dst16 = cv.CreateImage(cv.GetSize(cv_im), cv.IPL_DEPTH_16S, 1)
-
-    laplace = cv.Sobel(cv_im, dst16,1, 1,7)
-    
-    dst8 = cv.CreateImage (cv.GetSize(cv_im), cv.IPL_DEPTH_8U, 1)
-    cv.ConvertScale(dst16,dst8)
-    processed=im.fromstring("L", cv.GetSize(dst8), dst8.tostring())
-#    cv.ShowImage ('canny', dst8)
-#    cv.WaitKey()
-
-    return processed
-
-
-
-def compute_list_bit_to_change(threshold,processed):
-    List=[]
-    nb=0
-    l=0
-    for i in processed:
-        if (processed[l]>=threshold):
-            #if nb%2==0:
-                List.append(l)
-            #nb+=1
-        l+=1
-    return List
-
-
-def compute_filter_canny(level,image):
-    level2=level.copy()
-    level2= array(level2.getdata()).flatten()
-    l=0
-    for x in level2:
-        level2[l]=(x/2)*2
-        l+=1
-    level2_im=im.new('L',image.size)
-    level2_im.putdata(level2)
-    level2_im=im.merge("RGB",(level2_im,level2_im,level2_im))
-
-    mean=numpy.mean(level2)
-    std=numpy.std(level2)
-
-    cv_im = cv.CreateImageHeader(image.size, cv.IPL_DEPTH_8U, 3)
-    cv.SetData(cv_im, level2_im.tostring())
-
-    yuv = cv.CreateImage(cv.GetSize(cv_im), 8, 3)
-    gray = cv.CreateImage(cv.GetSize(cv_im), 8, 1)
-    cv.CvtColor(cv_im, yuv, cv.CV_BGR2YCrCb)
-    cv.Split(yuv, gray, None, None, None)
-
-    canny = cv.CreateImage(cv.GetSize(cv_im), 8, 1)
-
-    List_bit_to_change=set([])
-    Weight=[]
-
-
-    
-    cv.Canny(gray, canny, mean-1*std, mean+1*std,3)  #avant 10 255
-    processed=im.fromstring("L", cv.GetSize(canny), canny.tostring())
-    processed= array(processed.getdata()).flatten()
-    List3=set(compute_list_bit_to_change(100,processed))
-
-    cv.Canny(gray, canny, mean-1*std, mean+1*std,5)  #avant 10 255
-    processed=im.fromstring("L", cv.GetSize(canny), canny.tostring())
-    processed= array(processed.getdata()).flatten()
-    List5=set(compute_list_bit_to_change(100,processed))
-
-    cv.Canny(gray, canny, mean-1*std, mean+1*std,7)  #avant 10 255
-    processed=im.fromstring("L", cv.GetSize(canny), canny.tostring())
-    processed= array(processed.getdata()).flatten()
-    List7=set(compute_list_bit_to_change(100,processed))
-
-    nb_bit_embedded=(512*512/10)+40
-    AvailablePixel3=List3
-    AvailablePixel5=AvailablePixel3.union(List5)
-    AvailablePixel7=AvailablePixel5.union(List7)
-    if len(AvailablePixel3)>nb_bit_embedded:
-        step=1
-        WorkingPixel=AvailablePixel3
-    elif len(AvailablePixel5)>nb_bit_embedded:
-        step=2
-        WorkingPixel=AvailablePixel5
-    elif len(AvailablePixel7)>nb_bit_embedded:
-        step=3
-        WorkingPixel=AvailablePixel7
-    else:
-        step=4
-        WorkingPixel=range(len(level2))
-
-    print "avail P3",len(AvailablePixel3)
-    print "avail P5",len(AvailablePixel5)
-    print "avail P7",len(AvailablePixel7)
-
-    print "size WorkingPixel",len(WorkingPixel)
-    Weight=[0 for _ in WorkingPixel]
-
-    l=0
-    for i in WorkingPixel:
-        if step>=1 and i in List3:
-            Weight[l]=1
-        if step>=2 and i in List5 and Weight[l]==0:
-            Weight[l]=10
-        if step>=3 and i in List7 and Weight[l]==0:
-            Weight[l]=100
-        if step>=4 and Weight[l]==0:
-            Weight[l]=1000
-        l+=1
-
-            
-        
-
-    List_bit_to_change=WorkingPixel
-        
-        
-
-
-
-    return [List_bit_to_change,Weight]
-
-
-
-
-
-
-
-
-
-
-
-def mystego(filein, fileout):
-    dd = im.open(filein)
-    dd = dd.convert('RGB') 
-    red, green, blue = dd.split()
-    level=red.copy()
-
-    [List_bit_to_change,Weight]=compute_filter_canny(level,dd)
-    level= array(level.getdata()).flatten()
-
-
-    bit_to_read=1  
-
-
-
-
-
-
-#parameters for BBS
-    M=18532395500947174450709383384936679868383424444311405679463280782405796233163977*39688644836832882526173831577536117815818454437810437210221644553381995813014959
-    X=18532395500947174450709383384936679868383424444311
-
-
-
-
-
-
-    l=0
-
-
-
-    message="Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete   Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete  Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete   Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete  Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete   Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete  Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete   Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete   Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete  Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete   Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete Ce que j'écris est très original... Bref, je suis un poete   Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete Ce que j'écris est très original... Bref, je suis un poete   Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete voila c'est la fin blablabla:-)"
-    message=message[0:len(message)/1]
-    leng_msg=len(message)
-    message=message+((leng_msg+7)/8*8-leng_msg)*" "
-    leng_msg=len(message)
-
-    leng='%08d'%len(message)
-
-
-
-
-    len_leng=len(leng)
-    leng_error=int(len_leng)
-    leng_cor=leng
-    List_pack=a2b_list(leng_cor)
-
-    List_random=[]
-    while len(List_random)<len(List_bit_to_change):
-        X=(X*X)%M
-        List_random.extend(Denary2Binary(X))
-
-    size=0
-    for i in range(leng_msg/8):
-        m=message[i*8:(i+1)*8]
-        m_cor=m
-        m_bin=a2b_list(m_cor)
-        size=size+len(m_bin)
-        List_pack.extend(m_bin) 
-
-
-
-
-
-
-   
-
-    Support=[getBit(level[l],bit_to_read) for l in List_bit_to_change]
-
-
-    Message=[(int(List_pack[l])^int(List_random[l])) for l in xrange(len(List_pack))]
-
-    print "support",len(List_bit_to_change)
-    print "message",len(Message)
-    print "weight",len(Weight)
-
-    (x_b,Stc_message,H_hat) = stc(Support,Weight,Message)
-
-    print "pourcentage modif",nbdif(x_b,Stc_message)
-    print "taille Stc_message",len(Stc_message)
-
-
-
-    l=0
-    size_mesg=0
-    val_mod=0
-
-    
-
-    for l in List_bit_to_change:
-        if(size_mesg<len(Stc_message)):
-            b=getBit(level[l],bit_to_read)
-            if b!=Stc_message[size_mesg]:
-                val_mod+=1
-            level[l]=float64(setBit(level[l],bit_to_read,Stc_message[size_mesg]))
-            size_mesg+=1
-
-    print 'size mesg',size_mesg
-    print 'val mod',val_mod
-    print 'len message',len(Message),len(List_pack)
-
-
-
-    zz3=im.new('L',dd.size)
-    zz3.putdata(level)
-
-    zz3.save(fileout)
-
-
-
-
-listing = os.listdir(path_cover)
-
-print listing
-
-list_nb_bit=[]
-l=0
-
-
-
-for infile in listing:
-    print "current file is: " + infile, path_stego+infile
-    mystego(path_cover+infile,path_stego+infile)
-    l+=1
-
diff --git a/code/canny_p3_stc.py b/code/canny_p3_stc.py
deleted file mode 100644 (file)
index fc5db79..0000000
+++ /dev/null
@@ -1,599 +0,0 @@
-#-*- coding:utf-8 -*-
-import Image as im
-import numpy 
-from sys import argv
-from pylab import *
-import string
-import cv
-import os
-from random import *
-from math import *
-
-infinity = 1000000000
-
-path_stego = '/home/couturie/ajeter/stego/'
-path_cover = '/home/couturie/ajeter/cover/'
-
-
-# forward part
-
-
-def dec(ch,n):    
-    l = len(ch)
-    acc = 0
-    for i in xrange(l):
-        if ch[i]==1:
-            acc = acc + 2**(n-i-1)        
-    return acc
-
-
-def bin(elem,n):
-    """Convertit un nombre en binaire"""
-    q = -1
-    res = [0 for i in xrange(n)]
-    i = 1
-    while q != 0:
-        q = elem // 2
-        r = elem % 2
-        res[n-i] =  r
-        elem = q
-        i+=1
-    return res
-
-
-
-def xorb(a,b):
-    return 1 if a != b else 0
-
-def xor(e1,e2,h):
-    e1b,e2b  = bin(e1,h),bin(e2,h)
-    d = dec([xorb(e1b[j],e2b[j]) for j in xrange(h)],h)
-    return d
-
-def lit(d,(indx,indy)):
-    if (indx,indy) in d :
-        return d[(indx,indy)]
-    else :
-        return 0
-
-
-
-
-def forward(H_hat,x,message,lnm,rho):
-    (h,w) = int(log(max(H_hat),2))+1, len(H_hat)
-    path = dict() 
-    nbblock = lnm
-    wght = [infinity for _ in xrange(int(2**h))] 
-    wght[0]=0    
-    newwght = [0 for _ in xrange(int(2**h))]
-#    rho = 1
-#    rho= [1 for _ in xrange(len(x))]
-    indx,indm = 0,0
-    i=0
-    while i < nbblock: # pour chaque bit du message
-        for j in xrange(w):   # pour chaque colonne de H_hat
-            #print indx, "en entrant",wght
-            k = 0
-            while k < int(2**h): # pour chaque ligne de H
-                w0 = wght[k] + x[indx]*rho[indx]
-                w1 = wght[xor(k,H_hat[j],h)] + (1-x[indx])*rho[indx]
-                if w1 < w0 :
-                    path[(indx,k)] = 1 
-                else : 
-                    if (indx,k) in path:
-                        del path[(indx,k)]
-                newwght[k] = min(w0,w1)
-                k +=1 
-            indx +=1
-            wght = [t for t in newwght]
-            #print " apres calcul",wght
-
-        for j in xrange(int(2**(h-1))):   # pour chaque colonne de H
-            wght[j] = wght[2*j + message[indm]]
-        wght = wght[:int(pow(2,h-1))] + [infinity for _ in xrange(int(pow(2,h)-pow(2,h-1)))]
-        indm +=1
-        i +=1
-    start = np.argmin(wght)
-    return (start,path)
-
-
-def backward(start,H_hat,x,message,lnm,path):
-    (h,w) = int(log(max(H_hat),2))+1, len(H_hat)
-    indx,indm = len(x)-1,lnm-1
-    state = 2*start + message[indm]
-    indm -=1
-    # l'initialisation de state n'est pas optimale...
-    nbblock = lnm
-    y=np.zeros(len(x))
-    i=0
-    while i < nbblock:
-        l = range(w)
-        l.reverse()
-        for j in l:   # pour chaque colonne de H_hat
-            y[indx] = lit(path,(indx,state))
-            state = xor(state,y[indx]*H_hat[j],h)
-            indx -=1
-        state = 2*state + message[indm]
-        indm -=1 
-        i +=1
-    return [int(t) for t in y]
-
-    
-
-
-
-def trouve_H_hat(n,m,h):
-    assert h ==7 
-    alpha = float(n)/m
-    assert alpha >= 1 
-    index = min(int(alpha),9)
-    mat = {
-        1 : [127],
-        2 : [71,109],
-        3 : [95, 101, 121],
-        4 : [81, 95, 107, 121],
-        5 : [75, 95, 97, 105, 117],
-        6 : [73, 83, 95, 103, 109, 123],
-        7 : [69, 77, 93, 107, 111, 115, 121],
-        8 : [69, 79, 81, 89, 93, 99, 107, 119],
-        9 : [69, 79, 81, 89, 93, 99, 107, 119, 125]
-        }[index]
-    return(mat, index*m)
-
-
-def stc(x,rho,message):
-    lnm = len(message)
-    (mat,taille_suff) = trouve_H_hat(len(x),len(message),7)
-    x_b = x[:taille_suff]
-    (start,path) = forward(mat,x_b,message,lnm,rho)
-    return (x_b,backward(start,mat,x_b,message,lnm,path),mat)
-
-
-
-
-
-def nbdif(x,y):
-    r,it = 0,0
-    l = len(y)
-    while it < l :
-        if x[it] != y[it] :
-            r +=1
-        it += 1
-    return float(r)/l 
-        
-
-
-
-
-
-def prod(H_hat,lnm,y):
-    (h,w) = int(log(max(H_hat),2))+1, len(H_hat)
-    i=0
-    H =[]
-    V=[0 for _ in range(len(y))]
-    sol=[]
-    while i < lnm: # pour chaque ligne 
-        V=[0 for _ in range(len(y))]    
-        k = max([(i-h+1)*w,0])
-        dec = max([i-h+1,0])
-        for j in xrange(min([i+1,h])): #nbre de blocks presents sur la ligne i
-            for l in xrange(w): # pour chaque collone de H_hat
-                V[k] = bin(H_hat[l],h)[h-i-1+j+dec]
-                k+=1
-                
-        sol.append(np.dot(np.array(V),np.array(y)))
-        i+=1
-        #H += [V]
-    #H = np.array(H)    
-    #y = np.array(y)
-    #print "dot",np.dot(H,y),H.shape
-    #print "sol",sol
-    return sol#list(np.dot(H,y))
-    
-def equiv(x,y): 
-    lx = len(x)
-    assert lx == len(y)
-    i=0
-    while i < lx :
-        if x[i] % 2 != y[i]%2 : 
-            return False
-        i += 1
-    return True
-        
-
-
-
-
-
-def conversion(nombre, base, epsilon = 0.00001 ):
-    ''' Soit nombre écrit en base 10, le retourne en base base'''
-    if not 2 <= base <= 36:
-        raise ValueError, "La base doit être entre 2 et 36"
-    if not base == 2 and '.' in str(nombre):
-        raise ValueError, "La partie décimale n'est pas gérée pour les bases\
-                           différentes de 2."
-    # IMPROVE : Convertir aussi la partie décimale, quand la base n'est pas égale
-    # à 2.
-    abc = string.digits + string.letters
-    result = ''
-    if nombre < 0:
-        nombre = -nombre
-        sign = '-'
-    else:
-        sign = ''
-    if '.' in str(nombre):
-        entier,decimal = int(str(nombre).split('.')[0]),\
-                         float('.'+str(nombre).split('.')[1])
-    else:
-        entier,decimal = int(str(nombre)),0
-    while entier !=0 :
-        entier, rdigit = divmod( entier, base )
-        result = abc[rdigit] + result
-    flotante, decimalBin = 1./float(base),''
-    while flotante > epsilon :
-        if decimal >= flotante:
-            decimalBin+='1'
-            decimal-=flotante
-        else :
-            decimalBin+='0'    
-        flotante = flotante/float(base)
-    if '1' in decimalBin :
-        reste = '.'+decimalBin
-        while reste[-1]=='0':
-            reste = reste[:-1]
-    else :
-        reste = ''
-    return sign + result + reste
-
-    
-def getBit(X,pos):
-    '''Récupère le bit en position pos de X.
-    Par exemple, getBit(8,1) = 0, puisque le bit le plus à droite de 8 = 1000 est 0.
-    On fera attention à ce que :
-        - on compte à partir du point,
-        - l'élément juste à gauche du point est en position 1,
-        - celui juste à droite est en position -1.'''
-    assert pos != 0
-    entier = conversion(X,2)
-    if '.' in entier:
-        entier, decimal = entier.split('.')  
-        if decimal == '0':
-            decimal = ''  
-    else:
-        decimal = ''
-    if '-' in entier:
-        entier = entier.replace('-','')
-    entier  = entier.zfill(abs(pos))
-    decimal = (decimal+'0'*abs(pos))[:max(len(decimal),abs(pos))]
-
-    return int(entier[len(entier)-pos]) if pos >0 else int(decimal[-pos-1])
-
-
-def setBit(X,pos,y):
-    '''Fixe le bit pos de X à la valeur y.
-    Le fonctionnement est similaire à getBit : 
-        - on compte à partir du point,
-        - l'élément juste à gauche du point est en position 1,
-        - celui juste à droite est en position -1.'''
-    assert pos != 0
-    entier = conversion(X,2)
-    if '.' in entier:
-        entier, decimal = entier.split('.')    
-    else:
-        decimal = ''
-    entier  = list(entier.zfill(abs(pos)))
-    decimal = list((decimal+'0'*abs(pos))[:max(len(decimal),abs(pos))])
-    if pos>0:
-        entier[len(entier)-pos]=str(int(y))
-    else:
-        decimal[-pos-1] = str(int(y))
-    if decimal == []:
-        return int(''.join(entier),2)
-    else:
-        S=0
-        for k in range(len(decimal)):
-            S += 1./2**(k+1)*int(decimal[k])
-        return float(str(int(''.join(entier),2))+'.'+str(S).split('.')[1])
-
-
-def a2b(a): 
-    ai = ord(a) 
-    return ''.join('01'[(ai >> x) & 1] for x in xrange(7, -1, -1)) 
-
-
-
-def a2b_list(L):
-    LL=[]
-    for i in L:
-        for j in list(a2b(i)):
-            LL.append(j)
-    return LL
-
-
-
-def toDecimal(x):
-    return sum(map(lambda z: int(x[z]) and 2**(len(x) - z - 1),
-                   range(len(x)-1, -1, -1)))            
-
-def conv_list_bit(L):
-    L2=[]
-    for j in range(len(L)/8):
-        L2.append(chr(toDecimal("".join(L[j*8:(j+1)*8]))))
-    return ''.join(L2)
-
-def Denary2Binary(n):
-    '''convert denary integer n to binary string bStr'''
-    bStr = ''
-    if n < 0:  raise ValueError, "must be a positive integer"
-    if n == 0: return '0'
-    while n > 0:
-        bStr = str(n % 2) + bStr
-        n = n >> 1
-    return bStr
-
-
-def compute_filter_sobel(level,image):
-    level2=level.copy()
-    level2= array(level2.getdata()).flatten()
-    l=0
-    for x in level2:
-        level2[l]=(x/2)*2
-        l+=1
-    level2_im=im.new('L',image.size)
-    level2_im.putdata(level2)
-
-    cv_im = cv.CreateImageHeader(image.size, cv.IPL_DEPTH_8U, 1)
-    cv.SetData(cv_im, level2_im.tostring())
-    dst16 = cv.CreateImage(cv.GetSize(cv_im), cv.IPL_DEPTH_16S, 1)
-
-    laplace = cv.Sobel(cv_im, dst16,1, 1,7)
-    
-    dst8 = cv.CreateImage (cv.GetSize(cv_im), cv.IPL_DEPTH_8U, 1)
-    cv.ConvertScale(dst16,dst8)
-    processed=im.fromstring("L", cv.GetSize(dst8), dst8.tostring())
-#    cv.ShowImage ('canny', dst8)
-#    cv.WaitKey()
-
-    return processed
-
-
-
-def compute_list_bit_to_change(threshold,processed):
-    List=[]
-    nb=0
-    l=0
-    for i in processed:
-        if (processed[l]>=threshold):
-            #if nb%2==0:
-                List.append(l)
-            #nb+=1
-        l+=1
-    return List
-
-
-def compute_filter_canny(level,image):
-    level2=level.copy()
-    level2= array(level2.getdata()).flatten()
-    l=0
-    for x in level2:
-        level2[l]=(x/2)*2
-        l+=1
-    level2_im=im.new('L',image.size)
-    level2_im.putdata(level2)
-    level2_im=im.merge("RGB",(level2_im,level2_im,level2_im))
-#    histo=level2_im.histogram()
-    mean=numpy.mean(level2)
-    std=numpy.std(level2)
-
-    cv_im = cv.CreateImageHeader(image.size, cv.IPL_DEPTH_8U, 3)
-    cv.SetData(cv_im, level2_im.tostring())
-
-    yuv = cv.CreateImage(cv.GetSize(cv_im), 8, 3)
-    gray = cv.CreateImage(cv.GetSize(cv_im), 8, 1)
-    cv.CvtColor(cv_im, yuv, cv.CV_BGR2YCrCb)
-    cv.Split(yuv, gray, None, None, None)
-    #print 'mean',mean
-    #print 'std',std
-
-    canny = cv.CreateImage(cv.GetSize(cv_im), 8, 1)
-
-    List_bit_to_change=set([])
-    Weight=[]
-
-
-    
-    cv.Canny(gray, canny, mean-1*std, mean+1*std,3)  #avant 10 255
-    processed=im.fromstring("L", cv.GetSize(canny), canny.tostring())
-    processed= array(processed.getdata()).flatten()
-    List3=set(compute_list_bit_to_change(100,processed))
-
-    cv.Canny(gray, canny, mean-1*std, mean+1*std,5)  #avant 10 255
-    processed=im.fromstring("L", cv.GetSize(canny), canny.tostring())
-    processed= array(processed.getdata()).flatten()
-    List5=set(compute_list_bit_to_change(100,processed))
-
-    cv.Canny(gray, canny, mean-1*std, mean+1*std,7)  #avant 10 255
-    processed=im.fromstring("L", cv.GetSize(canny), canny.tostring())
-    processed= array(processed.getdata()).flatten()
-    List7=set(compute_list_bit_to_change(100,processed))
-
-    nb_bit_embedded=len(List3)/2
-    AvailablePixel3=List3
-    AvailablePixel5=AvailablePixel3.union(List5)
-    AvailablePixel7=AvailablePixel5.union(List7)
-    if len(AvailablePixel3)>nb_bit_embedded:
-        step=1
-        WorkingPixel=AvailablePixel3
-    elif len(AvailablePixel5)>nb_bit_embedded:
-        step=2
-        WorkingPixel=AvailablePixel5
-    elif len(AvailablePixel7)>nb_bit_embedded:
-        step=3
-        WorkingPixel=AvailablePixel7
-    else:
-        step=4
-        WorkingPixel=range(len(level2))
-
-
-
-    print "avail P3",len(AvailablePixel3)
-    print "avail P5",len(AvailablePixel5)
-    print "avail P7",len(AvailablePixel7)
-
-    print "size WorkingPixel",len(WorkingPixel)
-    Weight=[0 for _ in WorkingPixel]
-
-    l=0
-    for i in WorkingPixel:
-        if step>=1 and i in List3:
-            Weight[l]=1
-        if step>=2 and i in List5 and Weight[l]==0:
-            Weight[l]=10
-        if step>=3 and i in List7 and Weight[l]==0:
-            Weight[l]=100
-        if step>=4 and Weight[l]==0:
-            Weight[l]=1000
-        l+=1
-
-            
-        
-
-    List_bit_to_change=WorkingPixel
-        
-        
-
-    Size_message=nb_bit_embedded
-
-    return [Size_message,Weight,List3]
-
-
-
-
-
-
-
-
-
-
-
-def mystego(filein, fileout):
-    dd = im.open(filein)
-    dd = dd.convert('RGB') 
-    red, green, blue = dd.split()
-    level=red.copy()
-
-    [Size_message,Weight,List_support]=compute_filter_canny(level,dd)
-    level= array(level.getdata()).flatten()
-
-
-    bit_to_read=1  
-
-
-#parameters for BBS
-    M=18532395500947174450709383384936679868383424444311405679463280782405796233163977*39688644836832882526173831577536117815818454437810437210221644553381995813014959
-    X=18532395500947174450709383384936679868383424444311
-
-
-
-
-
-
-
-
-    l=0
-
-
-
-    message="Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete   Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete  Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete   Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete  Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete   Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete  Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete   Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete   Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete  Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete   Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete Ce que j'écris est très original... Bref, je suis un poete   Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete Ce que j'écris est très original... Bref, je suis un poete   Salut christophe, arrives tu à lire ce message? normalement tu dois lire cela. Bon voici un test avec un message un peu plus long. Bon j'en rajoute pour voir. Ce que j'écris est très original... Bref, je suis un poete voila c'est la fin blablabla:-)"
-
-
-    message=message+message+message+message+message+message+message+message
-    message=message[0:len(message)/1]
-    leng_msg=len(message)
-    message=message+((leng_msg+7)/8*8-leng_msg)*" "
-    leng_msg=len(message)
-
-    leng='%08d'%len(message)
-
-
-
-
-    len_leng=len(leng)
-    leng_error=int(len_leng)
-    leng_cor=leng
-    List_pack=a2b_list(leng_cor)
-
-    List_random=[]
-    while len(List_random)<Size_message:
-        X=(X*X)%M
-        List_random.extend(Denary2Binary(X))
-
-    size=0
-    for i in range(leng_msg/8):
-        m=message[i*8:(i+1)*8]
-        m_cor=m
-        m_bin=a2b_list(m_cor)
-        size=size+len(m_bin)
-        List_pack.extend(m_bin) 
-
-
-    Support=[getBit(level[l],bit_to_read) for l in List_support]
-
-
-    Message=[(int(List_pack[l])^int(List_random[l])) for l in xrange(Size_message)]
-
-    print "support",len(List_support)
-    print "message",len(Message)
-    print "weight",len(Weight)
-
-    if Size_message!=0:
-        (x_b,Stc_message,H_hat) = stc(Support,Weight,Message)
-
-    if Size_message!=0:
-        print "pourcentage modif",nbdif(x_b,Stc_message)
-        print "taille Stc_message",len(Stc_message)
-
-
-
-    l=0
-    size_mesg=0
-    val_mod=0
-    #print LL
-    
-
-    for l in List_support:
-        if(size_mesg<len(Stc_message)):
-            level[l]=float64(setBit(level[l],bit_to_read,Stc_message[size_mesg]))
-            size_mesg+=1
-
-    print 'size mesg',size_mesg
-    print 'len message',len(Message),len(List_pack)
-
-
-
-    zz3=im.new('L',dd.size)
-    zz3.putdata(level)
-
-    zz3.save(fileout)
-    list_nb_bit.append(filein)
-    list_nb_bit.append(Size_message)
-
-
-
-
-
-
-listing = os.listdir(path_cover)
-
-list_nb_bit=[]
-l=0
-
-
-
-
-for infile in listing:
-    print "current file is: " + infile, path_stego+infile
-    mystego(path_cover+infile,path_stego+infile)
-    l+=1
-
index a5904a7efcc25a84ab0136ae95d860a200ad4eac..7dce9c6fd26e6129d1d68b613849a5e6beef2278 100644 (file)
@@ -2,16 +2,16 @@
 This section aims at justifying the lightweight attribute of our approach.
 To be more precise, we compare the complexity of our schemes to some of 
 current state of the art of 
-steganographic scheme, namely HUGO~\cite{DBLP:conf/ih/PevnyFB10},
+steganographic schemes, namely HUGO~\cite{DBLP:conf/ih/PevnyFB10},
 WOW~\cite{conf/wifs/HolubF12}, and UNIWARD~\cite{HFD14}.
-Each of these scheme starts with the computation of the distortion cost 
+Each of these schemes starts with the computation of the distortion cost 
 for each pixel switch and is later followed by the STC algorithm.
 Since this last step is shared by all, 
 we separately evaluate this complexity.
-In all the rest of this section, we consider a $n \times n$ square image. 
+In all the remainder of this section, we consider a $n \times n$ square image. 
 
 First of all, HUGO starts with computing the second order SPAM Features.
-This steps is in  $\theta(n^2 + 2\times 343^2)$ due to the calculation 
+This steps is in  $\theta(n^2 + 2\times 343^2)$ due to the computation
 of the difference arrays and next of the 686 features (of size 343).
 Next for each pixel, the distortion measure is calculated by +1/-1 modifying
 its value and computing again the SPAM 
@@ -47,14 +47,15 @@ To summarize, the complixity is in $\theta(6n^4\ln(n) +n^2)$
 
 What follows details the complexity of the distortion evaluation of the 
 UNIWARD scheme. This one is based to a convolution product $W$ of two elements 
-of size $n$ and is again in   $\theta(n^2 \times n^2\ln(n^2))$ and a sum $D$ of 
+of size $n$ and is again in   $\theta(n^2 \times n^2\ln(n^2))$,
+ and a sum $D$ of 
 these $W$ which is in $\theta(n^2)$. 
 This distortion computation step is thus in $\theta(6n^4\ln(n) + n^2)$.
 
 
-Our edge selection is based on a Canny  Filter. When applied on a 
+Our edge selection is based on a Canny filter. When applied on a 
 $n \times n$ square image, the noise reduction step is in $\theta(5^3 n^2)$.
-Next, let $T$ be the size of the canny mask.
+Next, let $T$ be the size of the Canny mask.
 Computing gradients is in $\theta(4Tn^2)$ since derivatives of each direction (vertical or horizontal) 
 are in $\theta(2Tn^2)$.
 Finally, thresholding with hysteresis is in $\theta(n^2)$.
index cd2aeea16a1ed0cf355eb5ece703a5a1668ddf0e..5fa4b70725b3bd8a1c4d3998ec469c8ba5f32cb1 100644 (file)
--- a/intro.tex
+++ b/intro.tex
@@ -16,7 +16,7 @@ steganalysis methods~\cite{DBLP:journals/tsp/DumitrescuWW03,DBLP:conf/mmsec/Frid
 
 Let us recall too that this drawback 
 can be fixed by considering the LSB matching (LSBM) subcategory, in which
-the $+1$ or $-1$ is randomly added to the cover pixel's LSB value 
+a $+1$ or $-1$ is randomly added to the cover pixel's LSB value 
 only if this one does not correspond to the secret bit.
 %TODO : modifier ceci
 By considering well-encrypted hidden messages, the probabilities of increasing or decreasing the value of pixels  are equal. Then usual statistical approaches 
@@ -60,15 +60,13 @@ The features embedded in WOW and UNIWARD are based on Wavelet-based
 directional filter. Thus, similarly, the distortion function is 
 the sum  of the differences between these wavelet coefficients  
 computed from the cover and from the stego images.
-
-
 Due to this distortion measures, HUGO, WOW and UNIWARD allow
 to embed messages that are $7$ times longer than the former
 ones with the same level of 
 indetectability as LSB matching. 
 However, this improvement has a larger computation cost, mainly due to
  the distortion function
-calculus. 
+computation.
 
 
 There remains a large place between random selection of LSB and feature based modification of pixel values.
@@ -113,7 +111,7 @@ For instance, studied payloads range from 0.04 to 0.4 modified bits per pixel.
 Contrarily, we argue that some images should not be taken 
 as a cover because of the nature of their signals.
 Consider for instance a uniformly black image: a very tiny modification of its 
-pixels can be easily detectable.
+pixels can be easily detected.
 Practically speaking, if Alice would send
 a hidden message to Bob, she would never consider
 such kind of image and a high embedding rate.   
@@ -143,11 +141,11 @@ even in the worst case scenario, the attacker
 will not be able to obtain the original message content.
 Doing so makes our steganographic protocol, to a certain extend, an asymmetric one.
 
-To sum up, in this research work, well-studied and experimented
+To sum up, well-studied and experimented
 techniques of signal processing (adaptive edges detection), 
 coding theory (syndrome-trellis codes), and cryptography 
-(Blum-Goldwasser encryption protocol) are combined 
-to compute an efficient steganographic
+(Blum-Goldwasser encryption protocol) are combined in this research work.
+The objective is to  compute an efficient steganographic
 scheme, whose principal characteristic is to take into 
 consideration the cover image and to be compatible with small computation resources.  
 
index 35376405172d6ca2d35c1e93beb8ed3b1839dc62..f9ca3d15a0b5660ee9e12ef69b117262d8bbbf49 100644 (file)
@@ -140,7 +140,7 @@ In the former the embedding rate depends on the number of edge pixels.
 The higher it is, the larger the message length that can be inserted is.
 Practically, a set of edge pixels is computed according to the 
 Canny algorithm with parameters $b=7$ and $T=3$.
-The message length is thus defined to be less than 
+The message length is thus defined to be lesser than 
 half of this set cardinality.
 If $x$ is too short for $m$, the message is split into sufficient parts
 and a new cover image should be used for the remaining part of the message. 
@@ -151,13 +151,13 @@ This is the classical approach adopted in steganography.
 Practically, the Canny algorithm generates  
 a set of edge pixels related to increasing values of $T$ and 
 until its cardinality
-is sufficient. Even in this situation, our scheme is adapting 
+is sufficient. Even in this situation, our scheme adapts
 its algorithm to meet all the user's requirements. 
 
 
 Once the map of possibly modified pixels is computed, 
 two methods may further be applied to extract bits that 
-are really modified. 
+are really changed. 
 The first one randomly chooses the subset of pixels to modify by 
 applying the BBS PRNG again. This method is further denoted  as a \emph{sample}.
 Once this set is selected, a classical LSB replacement is applied to embed the 
@@ -197,7 +197,7 @@ It  is further referred to as \emph{STC} and is detailed in the next section.
 % the fuzzy logic edge detector.   
 
 For a given set of parameters, 
-the canny algorithm returns a numerical value and
+the Canny algorithm returns a numerical value and
 states whether a given pixel is an edge or not.
 In this article, in the Adaptive strategy 
 we consider that all the edge pixels that 
@@ -226,7 +226,7 @@ follows the data embedding approach
 since there exists a reverse function for all its steps.
 
 More precisely,  let $b$ be the most significant bits and 
-$T$ be the size of the canny mask, both be given as a key.
+$T$ be the size of the Canny mask, both be given as a key.
 Thus, the same edge detection is applied on a stego content $Y$ to 
 produce the sequence $y$ of LSBs. 
 If the STC approach has been selected in embedding, the STC reverse
@@ -358,7 +358,7 @@ V_{ij}= \left\{
 150 & \textrm{if} &  \vert X_{ij} - Y_{ij} \vert = 2 \\
 225 & \textrm{if} &  \vert X_{ij} - Y_{ij} \vert = 3 
 \end{array}
-\right..
+\right.
 $$
 This function allows to emphasize differences between contents.
 Notice that since $b$ is 7 in Fig.~\ref{fig:diff7}, the embedding is binary 
diff --git a/stc.tex b/stc.tex
index db985853fa8dd98b21b8c676d242e8f4d65e4f63..0d1541a44916f9034d0691a89d59630bb5517153 100644 (file)
--- a/stc.tex
+++ b/stc.tex
@@ -19,9 +19,9 @@ $m$ for a given binary matrix $H$.
 
 Let us explain this embedding on a small illustrative example where
 $m$ and $x$ are respectively  a 3 bits column
-vector and a 7 bits column vector and where 
+vector and a 7 bits column vector, and where 
 $\rho_X(i,x,y)$ is equal to 1 for any $i$, $x$, $y$
-(\textit{i.e.}, $\rho_X(i,x,y) = 0$ if $x = y$ and $0$ otherwise).  
+(\textit{i.e.}, $\rho_X(i,x,y) = 0$ if $x = y$ and $1$ otherwise).  
 
 Let  $H$ be the binary Hamming matrix  
 $$
@@ -59,8 +59,8 @@ at most 1 bit.
 In the general case, communicating a message of $p$ bits in a cover of 
 $n=2^p-1$ pixels needs $1-1/2^p$ average changes.
 
-This Hamming embeding is really efficient to very small payload and is 
-not well suited when the size of the message is larger, as in real situation.
+This Hamming embedding is really efficient to very small payload and is 
+not well suited when the size of the message is larger, as in real situations.
 The matrix $H$ should be changed to deal with higher payload.
 Moreover, for any given $H$, finding $y$ that solves $Hy=m$ and  
 that minimizes $D_X(x,y)$, has an exponential complexity with respect to $n$.