はじめに
前に、Pythonによる二値化画像処理の基本という記事を書いた。この記事の発展となる。
実行処理について
今回は記事の名前にもある通り、
・ノイズの除去
・背景透過
それに、
・反転画像処理
も実行
ソースコード
import cv2
import numpy as np
# 画像の読み込み
img = cv2.imread('sample2-1.png')
# グレースケール変換
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# 閾値の設定
threshold_value = 110
# 配列の作成(output用)
threshold_img = gray.copy()
# 実装(numpy)
threshold_img[gray < threshold_value] = 0
threshold_img[gray >= threshold_value] = 255
# Output:sample2-2
cv2.imwrite(f'C:\\Users\\[username]\\python\\project1\\sample2-2.png',threshold_img)
# グレースケール変換された画像の読み込み
img = cv2.imread("sample2-2.png")
# ノイズ除去処理
ksize=3
# 中央値フィルタ
img_mask = cv2.medianBlur(img,ksize)
# 白黒反転画像
img2 = cv2.bitwise_not(img_mask)
# output:sample2-3,2-4
cv2.imwrite("C:\\Users\\[username]\\python\\project1\\sample2-3.png",img_mask)
cv2.imwrite("C:\\Users\\[username]\\python\\project1\\sample2-4.png",img2)
# 背景透過
from PIL import Image
# 画像の読み込み
org = Image.open( 'sample2-3.png' )
# サイズが同じ画像作成
trans = Image.new('RGBA', org.size, (0, 0, 0, 0))
# 縦横のサイズ
width = org.size[0]
height = org.size[1]
# for文で処理
for x in range(width):
for y in range(height):
pixel = org.getpixel( (x, y) )
# 白色処理なし
if pixel[0] == 255 and pixel[1] == 255 and pixel[2] == 255:
continue
# 白色以外の書き込み
trans.putpixel( (x, y), pixel )
# output:sample2-5
trans.save('sample2-5.png')
内容説明
import文からoutput:sample2-2まで
これは、上記にも記載した、Pythonによる二値化画像処理の基本のコードのほぼそのままである。
画像上、閾値のみ変更。
ノイズ除去
# ノイズ除去
ksize=3
# 中央値フィルタ
img_mask = cv2.medianBlur(img,ksize)
この部分では、画像処理をする近傍の大きさ等を設定する場所である。
白黒反転処理
# 白黒反転画像
img2 = cv2.bitwise_not(img_mask)
opencvに反転処理が組み込まれており、この文のみで反転処理が可能。ちなみに今回では。白黒でしているが、本来はカラー画像でも実行可能である。
透過画像作成
# 画像の読み込み
org = Image.open( 'sample2-3.png' )
# サイズが同じ画像作成
trans = Image.new('RGBA', org.size, (0, 0, 0, 0))
# 縦横のサイズ
width = org.size[0]
height = org.size[1]
# for文で処理
for x in range(width):
for y in range(height):
pixel = org.getpixel( (x, y) )
# 白色処理なし
if pixel[0] == 255 and pixel[1] == 255 and pixel[2] == 255:
continue
# 白色以外の書き込み
trans.putpixel( (x, y), pixel )
上記の#の通りの処理であるので、説明は省略する。
これらの結果sample2-1~2-5までをのせる。
元の画像(sample2-1.png)
この画像は、画像処理でよくつかわれるので見覚えのある人も多いと思う。レナと呼ばれる女性のヌード画像の一部である。
[レナについての説明 from Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%AC%E3%83%8A_(%E7%94%BB%E5%83%8F%E3%83%87%E3%83%BC%E3%82%BF)
二値化画像処理(sample2-2.png)
ノイズ除去処理(sample2-3.png)
白黒反転処理(sample2-4.png)
白色以外透過処理(sample2-5.png)
この記事上ではわかりにくいので、コードのコピーなどで自分でやってみるとよい。
ソースコードの簡易化
先ほどのコードは一つ一つの処理を見やすくしていた。しかし、順番を変えることで、手順を減らすことができる。
import cv2
import numpy as np
from PIL import Image
# 画像の読み込み
img = cv2.imread('sample2-1.png')
# グレースケール変換
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# 閾値の設定
threshold_value = 110
# 配列の作成(output用)
threshold_img = gray.copy()
# 実装(numpy)
threshold_img[gray < threshold_value] = 0
threshold_img[gray >= threshold_value] = 255
# ノイズ除去処理
ksize=3
# 中央値フィルタ
img_mask = cv2.medianBlur(img,ksize)
# 白黒反転画像
img2 = cv2.bitwise_not(img_mask)
# 背景透過
# 画像の読み込み
org = Image.open('sample2-3.png')
# サイズが同じ画像作成
trans = Image.new('RGBA', org.size, (0, 0, 0, 0))
# 縦横のサイズ
width = org.size[0]
height = org.size[1]
# for文で処理
for x in range(width):
for y in range(height):
pixel = org.getpixel( (x, y) )
# 白色処理なし
if pixel[0] == 255 and pixel[1] == 255 and pixel[2] == 255:
continue
# 白色以外の書き込み
trans.putpixel( (x, y), pixel )
# Output:sample2-2~2-5
cv2.imwrite(f'C:\\Users\\[username]\\python\\project1\\sample2-2.png',threshold_img)
cv2.imwrite("C:\\Users\\[username]\\python\\project1\\sample2-3.png",img_mask)
cv2.imwrite("C:\\Users\\[username]\\python\\project1\\sample2-4.png",img2)
trans.save('sample2-5.png')
一括処理であるときには、Errorが起きる可能性があるが、jupyter notebookでは実行可能であった。読み込みをせずに処理内での画像を直接読み込めるので、これくらいであれば誤差に近いが早くなるだろう。