自分で撮った写真に隠し署名をつけよう


はじめに

最近流行りのソーシャルメディアのおかげで自分が撮影したオリジナルの写真を世の中に見てもらえる機会が増えてモチベーション向上につながるが、その一方、画像のコピーやスクリーンキャプチャーで著作権侵害が生じる恐れも増えていると思う。
その防止策として、自分で撮影した写真に何らかの形で隠し署名を入れておくことを考えられる。
署名を入れておく方法もいろいろある中、よく知られている一つの簡単な方法は、例えば、カラー画像(RGB)のR,GかBのいずれかの最下位Bitに[0,1]の組み合わせで何らかの署名をつけておくことである。
本稿では、MATLABを使ってそのようなことをやってみた。

署名を追加する方法の概要

カラー画像はR(赤色成分)、G(緑色成分)、B(青色成分)の組み合わせであり、それぞれの成分画像が2次元の行列になっている。例えば、よく目にするM×N画素数の画像は、実は、R、G、Bそれぞれに対するM×N行列を合わせ、合計 M×N×3の行列になっている。この、M×N行列のそれぞれの要素を画素(ピクセル)という。一般的に、8ビット画像だと、画素一つ一つが0~255の間の一つの値(以下、ピクセル値)を持っている。10ビット画像だとその範囲が0~1023になるという。
署名を追加する方法では、例えば、青色成分のB画像のすべてのピクセル値の最下位ビットを0にすると、ピクセル値が奇数の画素に対してその値が1だけ減り、全体的画像の見た目にほぼ影響を及ばないと言える。
この処理によって、B画像のすべてのピクセル値の最下位ビットが空くので、そこに、[0,1]の組み合わせで作ったバイナリ(1ビットの白黒)画像(例えば、黒い背景で白いテキストが見えるような画像)を足し算して簡単に署名を追加できる(この追加でも上記同様に、画像の見た目に影響がほぼ出ないといえる)。

環境

Windows上でMATLABを使っている。そのバージョン、と、ツールボックスリストは以下になる。

>> version
    '9.6.0.1072779 (R2019a)'
>> license('inuse')
image_toolbox
matlab
video_and_image_blockset

処理のステップ

以下、MATLABコードを使いながらそのステップを示す。

ステップ1:元画像に合わせ、署名画像を作成

まずは、画像を読み込む。今回は、MATLABに入っている'pears.png'を使用。

'I = imread('pears.png');%変数Iに画像を読み込んだ'

次は、何らかの署名入り白黒画像を作成する。

signText = 'Don Quixote';%署名内容
fontsize = 25;%フォントサイズ
bI       = zeros(size(I,1),size(I,2));%空の背景(黒)画像を作成
position = [10 size(I,1)/2-10 size(I,2)*0.8 size(I,1)*0.3];%署名の位置を指定

これで、パラメータがそろったので、後は、署名画像を作成。
※今回はテキスト文字列を埋め込んでみましたが、MATLABのdrawfreehand()関数を利用して自分オリジナルの手書き署名も入れることができる。

In      = insertObjectAnnotation(bI,...
    'rectangle',...
    position,...
    signText,...
    'Color',[0 0 0],...
    'TextColor',[1 1 1],...
    'FontSize',fontsize);%署名を挿入(MATLABのビルトイン関数)
In      = rgb2gray(In);%グレー画像
In      = In >=1;%ピクセル値が「1」未満のピクセルの値を0に戻す

これによって、下記のような署名画像(0か1のバイナリ画像)が作られる。

ステップ2:元画像のB成分の最下位ビットに署名画像を加算

この処理は、元画像のB成分で、ピクセル値が奇数の画素について、1を引き算しておくと、B成分のすべての画素の最下位ビットが0を持つようになる。そこに、署名画像(0か1の値を持つ)を足し算するだけで、B成分の最下位ビットに署名のテキストだけが残るようになる。

Iout        = I;%出力画像初期化
ind         = mod(Iout,2)>0;%出力画像のピクセル値が奇数の画素を検出
Iout(ind)   = Iout(ind) - 1;%上記検出した画素のピクセル値より1を引き算
In          = cast(In,'like',I);%署名画像の型を元画像と合わせる
Iout(:,:,3) = Iout(:,:,3) + In;%出力画像のB成分に署名画像を入れる

ステップ3:表示確認

元画像、署名を入れた後の画像、を表示する。以下画像をご参考すると、見た目にほとんど差異がないことがわかる。
ここで、例えば、署名を入れた後の画像をソーシャルメディアに投稿すれば、誰かに著作権が侵害されてもクレームできる。その方法については、ステップ4をご参考。

subplot(1,3,1), imshow(I), title('元画像')
subplot(1,3,2), imshow(Iout),title('署名入れた後の画像')

ステップ4:署名の復元

自分の写真の何番目の成分に署名を入れたかのみをパラメータとして持っていれば、いつでもその写真から入れておいた署名の復元ができる。

indI = mod(Iout(:,:,3),2)>0;%3番目の成分(B成分)のピクセル値が奇数の画素のみが1になるようなバイナリ画像を作成
subplot(3,1,3), imshow(indI),title('復元した署名') %バイナリ画像を表示

おわりに

今回の投稿では多少遊び間隔で、MATLABによってできる画像処理系の簡単な用途を紹介した。
こんなことがやりたいなど、アイディアがあればぜひ、シェアーしてください。
最後に、面白かったと思われたら、「いいね」をお忘れなく!