pythonsteganography

How to embed an image to a cover image by selecting random pixels in cover image?


def embedding(hideImagePath,coverImagePath):
    img1 = cv2.imread(coverImagePath, 0)
    img2 = cv2.imread(hideImagePath, 0)
    for i in range (img2.shape[0]):
        for j in range(img2.shape[1]):
                #convert pixel to binary 
                pixels_cover = format(img1[i][j], '08b')
                pixels_hide = format(img2[i][j], '08b')
                #replace the last 2 LSB from cover image with 2 MSB from hide image
                stegoImage = pixels_cover[:6] + pixels_hide[:2]
                img1[i][j] = int(stegoImage, 2)
    cv2.imwrite('StegoImage.png', img1)

Above is the code that I done so far. It hide pixels in cover image sequentially but I need it to hide the image to the cover image by selecting random pixels from the cover image.


Solution

  • Conceptually you want to generate all the pixel coordinates and shuffle them in a deterministic way, so that the extraction knows where to look.

    import itertools as it
    import random
    
    def permute_indices(shape, password):
        indices = list(it.product(*map(range, shape)))
        random.seed(password)
        random.shuffle(indices)
        return iter(indices)
    

    For example

    >>> idx = permute_indices((600, 800), 'hunter2')
    >>> for _ in range(5):
        print(next(idx))
    
        
    (411, 359)
    (379, 680)
    (110, 612)
    (246, 388)
    (232, 605)
    

    Adjustments to your code

    def embedding(hideImagePath, coverImagePath, password):
        img1 = cv2.imread(coverImagePath, 0)
        img2 = cv2.imread(hideImagePath, 0)
        indices = permute_indices(img1.shape, password)
        for i in range (img2.shape[0]):
            for j in range(img2.shape[1]):
                    x, y = next(indices)
                    #convert pixel to binary
                    pixels_cover = format(img1[x][y], '08b')
                    pixels_hide = format(img2[i][j], '08b')
                    #replace the last 2 LSB from cover image with 2 MSB from hide image
                    stegoImage = pixels_cover[:6] + pixels_hide[:2]
                    img1[x][y] = int(stegoImage, 2)
        cv2.imwrite('StegoImage.png', img1)