0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【画像処理】Pythonを使ってネガポジ反転を自動化してみた!

Last updated at Posted at 2019-06-30

概要

実験などで,オシロスコープの波形を保存し,レポートに貼り付けるなんてことがあったのですが,
オシロスコープの波形は黒ベースの画像なので,そのまま貼り付けると,見づらいかつ,大量のインクを使ってしまうため,
あるアプリケーションで色を反転してから,レポートに貼っていました.

しかし,1枚1枚色を反転してというのは非常にめんどくさい!

ということで,画像のネガポジ反転をPythonを使って自動化してみました!

動作環境

  • Windows10(64bit)
  • Python 3.7.2
  • OpenCV 4.1.0

やりたいこと

上の画像を下の画像のようにするのが目標です.

sin.jpg

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

sin.jpg

どのようにしてネガポジ反転を行うのか

OpenCVにあるbitwise_not()関数を使ってあげれば,ネガポジ反転した画像を得られます.非常に簡単ですね.
bitwiseとはビット単位という意味です.それをnotすることで反転するというイメージでしょうか?
もしくは,関数を使わなくても,以下の1行でもできます.numpy恐ろしやですね.
計算時間も%timeitコマンドで調べてみましたが,数枚程度の画像であればそれほど変わりません.

img2 = 255 - img

ネガポジ反転させる関数の定義

では,ネガポジ反転させる関数を定義します.これがこのプログラムの核となる部分です.

# 画像のネガポジ反転をする関数
def negaposi(image):
    # 画像の読み込み
    img = cv2.imread(image)

    # ネガポジ反転
    img2 = cv2.bitwise_not(img)

    return img, img2

コードの解説

では解説をしていきます.

  • 画像の読み込み

まずは,画像を読み込ませます.

    img = cv2.imread(image)
  • ネガポジ反転

次に,先ほど説明したbitwise_not()関数を用いて,ネガポジ反転をさせます.

    img2 = cv2.bitwise_not(img)

あとはこの関数の返り値に対して,画像を表示したり保存したりすれば,所望の画像を保存することができます.

複数の画像に対して一気にネガポジ反転を行う

では複数の画像に対して,一気にネガポジ反転をやってみようと思います.
ネガポジ反転させたい画像がimages_for_negaposiディレクトリにあり,拡張子は.bmpであるとします.
そして保存先のディレクトリはnegaposi_imagesとします.

INPUTDIR = 'images_for_negaposi'
OUTPUTDIR = 'negaposi_images'
EXT = 'bmp'

# 編集後の画像の保存ディレクトリの作成
if not os.path.isdir(OUTPUTDIR):
    os.mkdir(OUTPUTDIR)

# ORIGINALFILE内の全ての画像に対してループ
for image in glob.glob(INPUTDIR + '/*.' + EXT):
    img, img2 = negaposi(image)
    # cv2.imshow('unedited', img) # 編集前の画像

    # 相対パスの部分を削除
    image = image[len(INPUTDIR) + 1:] 

    # ネガポジ反転した画像を表示
    cv2.imshow(image, img2)
    # cv2.moveWindow('unedited', 400, 0)
    # cv2.moveWindow(image, 0, 0) # 画像表示の位置変更
    cv2.waitKey(0) # 何らかのキーが押されるまで待機
    cv2.destroyAllWindows() # 全てのウィンドウを削除

    # 画像を保存
    cv2.imwrite(OUTPUTDIR + '/' + image, img2) # 画像の保存

コードの解説

それでは,コードの解説をしていきます.

  • 保存用ディレクトリの作成

保存先のディレクトリを作成します.同名のファイルがあるとエラーが出てしまうので,isdir()関数で,引数名のディレクトリがあるか否かを確認し,なければmkdir()関数で作成します.

if not os.path.isdir(OUTPUTDIR):
    os.mkdir(OUTPUTDIR)
  • ループ

INPUTDIR内の全ての画像に対して,ループします.
glob.glob()は引数パターンにマッチするファイルリストの作成を行います.
ここで,*はいわゆるワイルドカードです.
EXTは拡張子extensionの略です。

for image in glob.glob(INPUTDIR + '/*.' + EXT):
  • 相対パスの部分を削除

glob.glob()関数は,パターンにマッチしたファイルを相対パスの形で返すので,相対パスの部分を削除することで,
元のファイルと同じ名前で,ネガポジ反転後のファイルを保存できます.
具体的に説明すると,今の場合には,imageはimages_for_negaposi/*.bmpなので,最初のimages_for_negaposi/の部分をスライスによって削除します.
[start:]はstratオフセットから末尾までのシーケンスを抽出します.ちなみにオフセットはゼロから始まります.

    image = image[len(INPUTDIR) + 1:] 
  • 画像の表示

1行目で画像を表示します.これだけだと,すぐにウィンドウが消えてしまうので,
waitKey(0)で何らかのキーが入力されるまで,ここで待機します.
何らかのキーが押されたら,プログラムを再開し,destroyAllWindows()で全てのウインドウを削除します.
コメントアウトの部分は,ネガポジ反転前の画像も表示したいときに使います.
そのままimshow()だけだと,ウインドウが重なってしまうことがあるため,moveWindow()でウインドウを移動させます.

    cv2.imshow(image, img2)
    # cv2.moveWindow('unedited', 400, 0)
    # cv2.moveWindow(image, 0, 0) # 画像表示の位置変更
    cv2.waitKey(0) # 何らかのキーが押されるまで待機
    cv2.destroyAllWindows() # 全てのウィンドウを削除
  • 画像の保存

最後に画像を保存します.ここでも保存先はもちろん相対パスで指定します.

    cv2.imwrite(OUTPUTDIR + '/' + image, img2) # 画像の保存

まとめ

いかがだったでしょうか?今回はOpenCVを使って画像をネガポジ反転させる方法を説明しました.
これを使えばとても効率的ですね.ぜひ,活用してみてください.
また,プログラムに関する建設的なフィードバックもお待ちしています!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?