こんにちは!最近業務で使うキーボードを変えたポンです。
前回はOpenCVのインストール、画像の表示を行いました。今回は画像を加工してみようと思います!
エンボス加工とは??
文字や絵を浮き彫りにする加工のことです。点字を想像するとわかりやすいと思います。
処理の流れ
まずは大まかな処理の流れを説明していきたいと思います。今回は以下のような形で処理を進めていきます。
- 入力画像をグレースケールで読み込む
- 入力画像をコピーしネガポジ反転する
- ネガポジ反転した画像を斜めに数ピクセル平行移動させる
- グレースケール画像と平行移動したネガポジ画像を合成する
- いい感じに出来上がり!
実際にやってみる
コードを書いていきます。まずはグレースケールで読み込むところまで実装していきます。
import cv2
import numpy as np
# 画像のパス
IMG_PATH = 'path/to/image.jpg'
# グレイスケールで読み込み
gray_img = cv2.imread(IMG_PATH, cv.IMREAD_GRAYSCALE)
ここまでで画像をグレースケールで読み込むことができました。imshow()で表示するとこのような感じになります。
続いてネガポジ反転です。ネガポジ反転は、各画素の値を255から引くことで表現できます。今回はLUT(Look Up Table)を使用した関数を実装してみます。
def nega_convert(input_img):
"""
ネガポジ反転を行う
Parameters
----------
input_img : uint8
入力画像
Returns
-------
nega_img : uint8
ネガポジ反転後の画像
"""
# LUTの作成
lut = np.zeros((256, 1), dtype = 'uint8')
for i in range(256):
lut[i][0] = 255 - i
# LUTの適用
nega_img = cv2.LUT(input_img, lut)
return nega_img
こちらもimshow()で出力してみると……
なんだか気味が悪いですが、いい感じに反転できていますね。
この調子で平行移動も実装していきましょう! 平行移動はアフィン変換を適用する形で実装します。アフィン変換とは 3x3 の行列を使用しての変換のことを指します。こちらも関数を作って実装していきます。
def move_img(input_img, mv_x, mv_y):
"""
平行移動を行う
Parameters
----------
input_img : uint8
入力画像
mv_x : int
x軸移動量
mv_y : int
y軸移動量
Returns
-------
mv_img : uint8
平行移動後の画像
"""
# 画像の大きさを取得
width = input_img.shape[0]
height = input_img.shape[1]
# 移動用の行列の作成
mat = np.float32([[1, 0, mv_x], [0, 1, mv_y]])
# 移動の実行
mv_img = cv2.warpAffine(input_img, mat, (height, width))
return mv_img
実装できたら同じようにimshow()で出力してみましょう!
少し分りづらいですが、斜め右下に移動していることがわかると思います。上記の画像では平行移動していることを確認するために、移動量の引数に大きめの数値を与えています。
ここまできたら最後は合成です! どんどん進めていきます。
def add_img(gray_img, mv_img):
"""
画像の合成を行う
Parameters
----------
gray_img : uint8
入力画像1 (グレースケール画像)
mv_img : uint8
入力画像2 (平行移動後のネガポジ反転画像)
Returns
-------
emboss_img : uint8
エンボス画像
"""
# 画像の合成 127を引くのは凹凸をめだたせるため
emboss_img = (gray_img + mv_img) - 127
# 0から255の範囲に値をおさめる
emboss_img = emboss_img.clip(0, 255)
return emboss_img
最後もimshow()で出力してみましょう。
一風違った面白い画像が出来上がりました!
ちなみに今回与えた移動量はx、yともに 2 です。画像の大きさなどによって最適の移動量は変わってくるので、試行錯誤していい感じの移動量を見つけてください。また、ノイズが目立つ場合は、medianBlur()などでノイズ除去するのも良いかもしれません。
まとめ
今回はOpenCVを使って画像加工(エンボス加工)を行いました。OpenCVはやろうと思えば、大抵のことはできるので、色々試してみるのも楽しいと思います。
機会があればまたOpenCVの記事を書くかもしれません! それでは!