昨年末、著作権フリーの画像を駆使して年賀状を作成しました。しかし、画像の背景が透明でなく白色であったため、少し画像が重なると下の画像を隠してしまうので、画像を配置するのに苦労しました。Photoshopなどの画像処理ソフトを使えば、背景色を透明にできるのでしょうが、もっと簡単に透明にすることができたらいいのにと思ったので、Pythonで特定の色を透明にするプログラムを作ってみました。

準備

今回のプログラムではOpenCVを使用しますので、以下のコマンドでインストールします。

使い方

プログラムを実行するとすぐに画像を選択するダイアログが開きます。

画像を開くと、以下のような複数のトラックバーが配置されたダイアログと、画像が2行3列に連結されたウィンドウ(Resultウィンドウ)が開きます。

トラックバーではHSV色空間において、Hue(色相)、Saturation(彩度)、Value(明度)の最小値と最大値を変更できるようになっています。また最終的なエッジの閾値を決める値(Threshold1, Threshold2)もあります。

これらのトラックバーをいろいろ調節すると、Resultウィンドウの真ん中下にあるFilled Contourというラベルのついた場所で、元の画像を残す領域が緑色に塗りつぶされます。逆に言うとここで緑色に塗りつぶされていない領域が透明になります。最終的な画像は一番右の下側にある、Finalというラベルがついた場所に表示されます。

トラックバーを調整して、透過させる領域を決定したら、トラックバーダイアログ上でキーボードの「s」ボタンを押してください。するとファイルを保存するダイアログが開くので、透過処理をした画像ファイルを保存します。

以下が元の画像(左)と透過した画像(右)です。右側の画像の背景が透明(チェッカボード)になっているのが分かると思います。

ソースコード

ソースコードの説明

複数の画像を1つのウィンドウにまとめて表示する関数です。この関数はCVZoneで公開されているソースコードを参考にさせていただいております。

トラックバーから値を取り出す関数です。

画像を読み込む関数と書き出す関数です。OpenCVは画像ファイルのパスに日本語が含まれていると、読み込みエラーとなるのでそれを避けるためにnumpy経由でファイルを開いています。ここまでが以下のプログラムで使用する関数の定義です。

ここからプログラムの実行内容です。まずファイル入力ダイアログを開き、ユーザーにファイルを選択してもらいます。

ファイルを読み込みます。上で述べたように日本語を含むファイルパスに対応するために独自に定義したimread関数を使用しています。また、透過させる場所を調節するにあたり、画像をスタック(連結)させやすいように、画像サイズを一律で640×480に変更しています。

トラックバーとそのダイアログを作成しています。

無限ループで現在のトラックバーの値に合わせて、画像処理を行い、stackImages関数で処理内容を表示しています。キーボードで「q」ボタンを押すとプログラム終了、「s」ボタンを押すとファイルを保存する処理を行います。

「s」ボタンが押された場合、ダイアログを開き保存するファイル名を取得します。またトラックバーによる画像の調節においては、元の画像を640×480にリサイズしていましたが、保存するのは元のサイズの画像なので、再度、画像ファイルを開いて、パラメータ調節時と同様の画像処理をしています。