2015年11月13日金曜日

OpenCV Tutorial(2)〜画像の平滑化

Smoothing Images

画像の平滑化手法(Smoothing Images)に幾つかのやり方があり、それぞれ得意/不得意があるので簡単にでも理解した上で使い分けるのがベター。

大きくはノイズを減らすのが得意なlow-pass filters(LPF)と輪郭をシャープにするhigh-pass filters(HPF)に分けられる。

代表的な種類としてはこんなものがある。
  • 2D Convolution(2次元畳み込み)
  • Averaging(平均)
  • Gaussian Blurring(ガウシアンぼかし)
  • Median Blurring(中央値ぼかし)
  • Bilateral Filtering(バイラテラルフィルタ)
それぞれやってみる。画像は適当なものを取ってきた。

2D Convolution(2次元畳み込み)


import cv2
import numpy as np
from matplotlib import pyplot as plt
 
# 画像をそのまま読み込む
img = cv2.imread('G-symbol.png')
 
# すべての要素が浮動小数点1の5×5の行列を作成、平均を出すために25で割る
# このカーネルさえ自作できれば、いろいろなフィルターが自作できる
kernel = np.ones((5,5),np.float32)/25
# kernelをそのまま適用する。ビット深度はそのまま
dst = cv2.filter2D(img,-1,kernel)
 
# 横に1行で2つならべ、1つ目なので(1, 2, 1)
# subplot(121)はsubplot(1, 2, 1)と同じ
plt.subplot(121),plt.imshow(img),plt.title('Original')
# x,y軸のメモリなし
plt.xticks([]), plt.yticks([])
# 横に1行で2つならべ、2つ目なので(1, 2, 2)
plt.subplot(122),plt.imshow(dst),plt.title('Averaging')
# x,y軸のメモリなし
plt.xticks([]), plt.yticks([])
 
# 画像表示
plt.show()


Averaging(平均)


import cv2
from matplotlib import pyplot as plt
 
# 画像をそのまま読み込む
img = cv2.imread('G-symbol.png')
 
# 平均値ぼかし処理。今回の場合2Dフィルタと同じ処理になる。
blur = cv2.blur(img,(5,5))
 
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur),plt.title('Blurred')
plt.xticks([]), plt.yticks([])
plt.show()                                                                        


Gaussian Blurring(ガウシアンぼかし)


import cv2
from matplotlib import pyplot as plt
 
img = cv2.imread('G-symbol.png')
 
# ガウシアンぼかし(5, 5)は中心からの計算するピクセル範囲
# ガウシアンの場合は自動的に中心に近いほど近傍値としての重みが高くなり平滑化される
blur = cv2.GaussianBlur(img,(5,5),0)
 
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur),plt.title('Blurred')
plt.xticks([]), plt.yticks([])
plt.show()


Median Blurring(中央値ぼかし)


import cv2
from matplotlib import pyplot as plt
 
img = cv2.imread('ZebraWithAttachedShadow_noisy_Salt_and_Pepper.jpg')
 
# 指定した範囲内でのピクセル数の平均値をとる。
# 白、黒などの極端なノイズは無視されるため、ノイズ除去に強い
median = cv2.medianBlur(img,5)
 
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(median),plt.title('Median')
plt.xticks([]), plt.yticks([])
plt.show()


Bilateral Filtering(バイラテラルフィルタ)


import cv2
from matplotlib import pyplot as plt
 
img = cv2.imread('woos4.jpg')
 
# 入力画像、中心部からのピクセル範囲、カラーシグマ値、空間シグマ値
# カラーシグマが大きいとピクセル間での濃淡差が大きくないと効果がでない
# 空間シグマが大きいと輪郭意外のボケがおおきくなるが計算処理に時間がかかる
blur = cv2.bilateralFilter(img,9,75,75)
 
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur),plt.title('Bilateral')
plt.xticks([]), plt.yticks([])
plt.show()


今日の作業

スムージングの特徴をもう少し明確につかみたい。

EclipseからFedora23へRSEでサーバにSSH接続できない


いつもサーバへソースなどファイルをアップロードする時にはEclipseのRSE経由でSFTPで行っているのだが、今使っているFedora23へ同様にしようとすると下記のようなメッセージが出て接続できなかった。

"172.16.33.160:22" 上で sshd の接続に失敗しました
Session.connect: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)

その他のCentOS7などのサーバへは同様に接続できる。

クライアントの環境はこんな感じ。

OS:MacOS El Capitan
Java:1.7.0_67
Eclipse:Version: Mars.1 Release (4.5.1)、Build id 20150924-1200
RSE:3.7.0.201505221634

調べてみると「SunJCE の Diffie-Hellman アルゴリズムで 1024 ビットを超える素数が使えない」にJava8にアップデートしたらいけそうな感じだったのでしてみることに。

Java SDK8をダウンロードしてきてインストール。

インストールされたか今までのバージョンの確認をしてみる。
# java -version
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)
# /usr/libexec/java_home -V
Matching Java Virtual Machines (4):
    1.8.0_65, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home
    1.7.0_67, x86_64: "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_67.jdk/Contents/Home
    1.6.0_65-b14-468, x86_64: "Java SE 6" /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
    1.6.0_65-b14-468, i386: "Java SE 6" /Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
 
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home

Eclipseを再起動して、再度RSEで接続してみるといけた。

ちなみにJavaのバージョンを切り替える場合は下記のようにする。
# export JAVA_HOME=`/usr/libexec/java_home -v 1.7.0_67`
# java -version
java version "1.7.0_67"
Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
# export JAVA_HOME=`/usr/libexec/java_home -v 1.8.0_65`
# java -version
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)