OpenCV
前回、PythonのOpenCVでfilter2Dを使って画像をアンシャープマスキング(鮮鋭化)する方法を紹介しました。
今回はOpenCVで画像に白黒、またはRGBのノイズを入れる方法、そして砂嵐ノイズを入れる方法を紹介します。
今回もこの画像を使いますが、ファイル名を「python-opencv15-1.jpg」とします。
ちなみに画像の読み込みまではこんな感じです。
import cv2
import numpy as np
import os
default_dirpath = os.getcwd()
filename = "python-opencv15-1.jpg"
filepath = os.path.join(default_dirpath, filename)
img = cv2.imread(filepath, cv2.IMREAD_COLOR)
height, width, channel = img.shape
print(height, width, channel)
実行結果
768 1024 3
今回は画像サイズも使いますので、「.shape」で画像の情報も取得しておきます。
それでは始めていきましょう。
白黒のノイズを入れる方法
最初に白色だけのノイズを入れる方法を紹介します。
そのためにはノイズを入れるX座標、Y座標のリストを作成します。
今回はNumPyのランダム値を取得するジェネレータを使用して作成しました。
ジェネレータを使ったランダム値の取得方法はこちらの記事で紹介していますので、よかったらどうぞ。
今回はノイズの数だけピクセル座標を取得したいので、「rng.integers(0, 画像サイズ-1, ノイズの数)」という形で値を取得します。
noise_num = 1000
rng = np.random.default_rng(0)
white_x = rng.integers(0, width-1, noise_num)
white_y = rng.integers(0, height-1, noise_num)
そしてこの2つのリストで指定されるピクセルの色(RGBの値)を白色に置き換えます。
白色は「(255, 255, 255)」ですので、こんな感じになります。
import cv2
import numpy as np
import os
default_dirpath = os.getcwd()
filename = "python-opencv15-1.jpg"
filepath = os.path.join(default_dirpath, filename)
img = cv2.imread(filepath, cv2.IMREAD_COLOR)
height, width, channel = img.shape
noise_num = 1000
rng = np.random.default_rng(0)
white_x = rng.integers(0, width-1, noise_num)
white_y = rng.integers(0, height-1, noise_num)
img[(white_y, white_x)] = (255, 255, 255)
output = os.path.join(default_dirpath, "python-opencv15-2.png")
cv2.imwrite(output, img)
実行結果
ちなみに1024 x 769 ピクセルの画像に1000個の白色ノイズを加えたものが上の画像になりますが、思ったより少なく感じます。
次に黒色ノイズも加えて、白黒ノイズとしますが、単純に先ほどの白色のノイズ追加の部分を黒色も増やすだけです。
黒色のRGBの値は「(0, 0, 0)」です。
import cv2
import numpy as np
import os
default_dirpath = os.getcwd()
filename = "python-opencv15-1.jpg"
filepath = os.path.join(default_dirpath, filename)
img = cv2.imread(filepath, cv2.IMREAD_COLOR)
height, width, channel = img.shape
noise_num = 1000
rng = np.random.default_rng(0)
white_x = rng.integers(0, width-1, noise_num)
white_y = rng.integers(0, height-1, noise_num)
img[(white_y, white_x)] = (255, 255, 255)
black_x = rng.integers(0, width-1, noise_num)
black_y = rng.integers(0, height-1, noise_num)
img[(black_y, black_x)] = (0, 0, 0)
output = os.path.join(default_dirpath, "python-opencv15-3.png")
cv2.imwrite(output, img)
実行結果
RGBのノイズを入れる方法
次にRGB3色のノイズを入れる方法ですが、これは先ほどの白黒の時と同様にノイズにする座標を作成し、その座標の色を赤色、青色、緑色にするだけです。
ただ気をつけることはOpenCVのRGBの順番は「BGR」です。
そのため赤色は「(0, 0, 255)」、青色は「(255, 0, 0)」、緑色は「(0, 255, 0)」です。
import cv2
import numpy as np
import os
default_dirpath = os.getcwd()
filename = "python-opencv15-1.jpg"
filepath = os.path.join(default_dirpath, filename)
img = cv2.imread(filepath, cv2.IMREAD_COLOR)
height, width, channel = img.shape
noise_num = 1000
rng = np.random.default_rng(0)
red_x = rng.integers(0, width-1, noise_num)
red_y = rng.integers(0, height-1, noise_num)
img[(red_y, red_x)] = (0, 0, 255)
blue_x = rng.integers(0, width-1, noise_num)
blue_y = rng.integers(0, height-1, noise_num)
img[(blue_y, blue_x)] = (255, 0, 0)
green_x = rng.integers(0, width-1, noise_num)
green_y = rng.integers(0, height-1, noise_num)
img[(green_y, green_x)] = (0, 255, 0)
output = os.path.join(default_dirpath, "python-opencv15-4.png")
cv2.imwrite(output, img)
実行結果
砂嵐ノイズを入れる方法
最後に砂嵐ノイズを入れる方法ですが、これまでの白、黒、赤、緑、青のノイズを大量に入れることで作成できます。
先ほどまではそれぞれの色のピクセルを1000個入れていましたが、砂嵐ノイズにするには100,000個ほど必要なようです(768 x 1024ピクセルの場合)。
ということでこんな感じです。
import cv2
import numpy as np
import os
default_dirpath = os.getcwd()
filename = "python-opencv15-1.jpg"
filepath = os.path.join(default_dirpath, filename)
img = cv2.imread(filepath, cv2.IMREAD_COLOR)
height, width, channel = img.shape
noise_num = 100000
rng = np.random.default_rng(0)
white_x = rng.integers(0, width-1, noise_num)
white_y = rng.integers(0, height-1, noise_num)
img[(white_y, white_x)] = (255, 255, 255)
black_x = rng.integers(0, width-1, noise_num)
black_y = rng.integers(0, height-1, noise_num)
img[(black_y, black_x)] = (0, 0, 0)
red_x = rng.integers(0, width-1, noise_num)
red_y = rng.integers(0, height-1, noise_num)
img[(red_y, red_x)] = (0, 0, 255)
blue_x = rng.integers(0, width-1, noise_num)
blue_y = rng.integers(0, height-1, noise_num)
img[(blue_y, blue_x)] = (255, 0, 0)
green_x = rng.integers(0, width-1, noise_num)
green_y = rng.integers(0, height-1, noise_num)
img[(green_y, green_x)] = (0, 255, 0)
output = os.path.join(default_dirpath, "python-opencv15-5.png")
cv2.imwrite(output, img)
実行結果
今回は1ピクセルごと色を変更しましたが、次回は画像にさらにもっと大きなノイズ(むしろ塗りつぶし)を追加する方法を紹介します。
ではでは今回はこんな感じで。
コメント