2015-01-24 5 views
0

В Wikipedia's Steganography Article приведен пример изображения со скрытыми данными изображения.Использование Python для декодирования изображений стеганографии (примеры изображений в Википедии)

Википедия отмечает:

Image of a tree с стеганографии скрытым изображением. Скрытое изображение обнаруживается путем удаления всех, кроме двух младших значащих бит каждого компонента цвета, и последующей нормализации. Скрытое изображение показано (here).

ВОПРОС: Я запутался о "последующей нормализацией"; предполагая, что рабочий код Python 2.x основан на модуле PIL, как фактор нормирования в поиске?

+0

ли вы на самом деле есть вопрос? –

+0

* Учитывая приведенную выше информацию, как код Python будет декодировать изображение кота из древовидного изображения? * - Должен ли я перефразировать? –

+0

Это не вопрос, это сайт QA, а не служба «write-my-code-for-me». –

ответ

3

Последующая нормализация составляет linear interpolation каждого цветового компонента.

Скажем, красный компонент цвета пиксела 1,1 является 234.

Двоичное представление 234

In [1]: bin(234) 
Out[1]: '0b11101010' 

Мы можем удалить все, кроме двух младших битов с некоторой побитовой операции :

In [2]: bin(234 & 0b11) 
Out[2]: '0b10' 

Диапазон 8-разрядного изображения - 8 бит или 256 возможных оттенков. Но диапазон нашего значения цвета - всего 2 бита или 4 возможных оттенка.

Нормализация часть делает linear interpolation растянуть 2-битное значение, чтобы заполнить 8-разрядное пространство:

In [3]: (234 & 0b11) * (256/4) 
Out[2]: 128 

ли это делается на каждом компоненте цвета и кот появится.

+1

Правильный коэффициент пересчета: 255/3. Если вы умножаете значения в диапазоне [0,3] на 256/4 = 64, вы получаете значения в диапазоне [0,192]. – Reti43

2

Нормализация - это процесс изменения диапазона значений в другой диапазон значений.

У вас есть диапазон [0,3] из-за двоичных значений 00, 01, 10 и 11. Причина, по которой вы хотите нормализовать это значение [0,255], - охватить весь диапазон интенсивностей пикселей. Если бы вы просто сохранили изображение из массива со значениями в диапазоне [0,3], он выглядел бы черным, потому что все эти значения очень близки к 0 и очень далеки от 255.

Страница wikipedia на image normalization дает вам общую формулу для этого. Он также показывает пример преобразования диапазона [50, 180] (назовем этот диапазон A) на [0,255] (диапазон B).

Во-первых, мы сдвигаем А так, чтобы оно начиналось с нуля. Эффективно вычитаете наименьшее значение (50), чтобы [50, 180] становилось [0,130] (назовем это C). Максимальное расстояние для C составляет 130-0 = 130, а для B - 255-0 = 255. Таким образом, вам нужно будет умножить все значения C на 255/130. Так как наименьшее значение в C равно 0, то это будет для C * 255/130. Но если B не начинается с 0, вы просто добавляете необходимое смещение для учетной записи для этого.

В случае, если слова запутывают, вот визуализация преобразования [2,5] в [-4,4].

Range normalization demonstration

В ваших случаях, нормализация от [0,3] до [0,255]. Поскольку оба диапазона начинаются с 0, вам не нужны никакие смещения, простое умножение на 255/3. Этот результат преобразует {0,1,2,3} в {0,85,170,255}.

Здесь необходимо соблюдать осторожность, 255/3 - это целое число. Но если бы вы нормализовались, скажем [0,7], для наиболее точного преобразования потребуется коэффициент масштабирования float 255/7. Сохраняете ли вы это как float или округлите его до целого, выходит за рамки этого ответа.

Простейший код для достижения этой цели будет

import Image 
import numpy as np 

# The array will be of type `np.uint8`. For integer computations that exceed 
# this range, use `np.asarray(Image.open(...), dtype=int)`. 
stego = np.asarray(Image.open('Steganography_original.png')) 
extracted = stego & 0b00000011 
extracted *= (255/3) 

# Compare result with the one from wikipedia 
wiki_extracted = np.asarray(Image.open('Steganography_recovered.png').convert('RGB')) 
if np.all(wiki_extracted == extracted): 
    print 'All pixels match' 
+0

* Сохраняете ли вы это как float или округлите его до целого числа, выходящего за рамки этого ответа. *: Можете ли вы порекомендовать источник по этому предмету, который я могу отслеживать? –

+0

Если 255/7 = 36, то {0,1,2,3,4,5,6,7} -> {0,36,72,108,144,180,216,252}. Если 255/7 = 36.4285 ..., вы сначала нормализуете диапазон [0,7], а затем округлите значения до целых чисел, затем {0,36,72,109,145,182,218,255}. Я бы выбрал последний из-за ошибки кумулятивной точности первого. Если вы работаете с форматом изображения, где интенсивность пикселей хранится как плавающие, вам также нужно, чтобы коэффициент масштабирования был плавающим. – Reti43