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

Private GIT Repository
ajout canny_p3_stc.py
authorraphael couturier <couturie@extinction>
Sun, 2 Nov 2014 17:31:43 +0000 (18:31 +0100)
committerraphael couturier <couturie@extinction>
Sun, 2 Nov 2014 17:31:43 +0000 (18:31 +0100)
code/canny_p3-p7-stc.py [moved from code/canny_p3-p7.py with 98% similarity]
code/canny_p3_stc.py [new file with mode: 0644]

similarity index 98%
rename from code/canny_p3-p7.py
rename to code/canny_p3-p7-stc.py
index 316c81642c61c09a830e08fc1bacbb87982cc773..6f000452b7f75a8d862f506ac2fbb9196660c839 100644 (file)
@@ -16,12 +16,6 @@ infinity = 1000000000
 path_stego = '/home/couturie/ajeter/stego/'
 path_cover = '/home/couturie/ajeter/cover/'
 
 path_stego = '/home/couturie/ajeter/stego/'
 path_cover = '/home/couturie/ajeter/cover/'
 
-#parameters for BBS
-M=18532395500947174450709383384936679868383424444311405679463280782405796233163977*39688644836832882526173831577536117815818454437810437210221644553381995813014959
-X=18532395500947174450709383384936679868383424444311
-
-
-
 # forward part
 
 
 # forward part
 
 
@@ -497,6 +491,12 @@ def mystego(filein, fileout):
 
 
 
 
 
 
+#parameters for BBS
+    M=18532395500947174450709383384936679868383424444311405679463280782405796233163977*39688644836832882526173831577536117815818454437810437210221644553381995813014959
+    X=18532395500947174450709383384936679868383424444311
+
+
+
 
 
 
 
 
 
diff --git a/code/canny_p3_stc.py b/code/canny_p3_stc.py
new file mode 100644 (file)
index 0000000..fc5db79
--- /dev/null
@@ -0,0 +1,599 @@
+#-*- 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
+