OpenCVを使用して画像をシャープにする方法は?スムージングまたはぼかしの方法は多数ありますが、シャープにする方法はありません。
一般的な手順の1つは、 アンシャープマスキングに関するウィキペディアの記事 :ガウス平滑化フィルターを使用し、元の画像から平滑化されたバージョンを減算します(一定の面積の値が一定になるように重み付けされます) )。
frame
のシャープバージョンをimage
にするには:(両方cv::Mat
)
cv::GaussianBlur(frame, image, cv::Size(0, 0), 3);
cv::addWeighted(frame, 1.5, image, -0.5, 0, image);
パラメータは、自分で調整する必要があるものです。
ラプラシアンのシャープ化もあります。グーグルで検索すると、その上に何かが見つかるはずです。
シンプルなkernelとfilter2D関数、例えばPythonの場合:
kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
im = cv2.filter2D(im, -1, kernel)
ウィキペディアにはカーネルの概要があり、さらにいくつかの例があります- https://en.wikipedia.org/wiki/Kernel_(image_processing)
画像処理では、カーネル、畳み込み行列、またはマスクは小さな行列です。ぼかし、シャープ、エンボス、エッジ検出などに使用されます。これは、カーネルとイメージの間で畳み込みを行うことで実現されます。
OpenCV Documentation で、「アンシャープマスク」アルゴリズムを使用して画像をシャープにするに関するサンプルコードを見つけることができます。
sigma
、threshold
、amount
の値を変更すると、異なる結果が得られます。
// sharpen image using "unsharp mask" algorithm
Mat blurred; double sigma = 1, threshold = 5, amount = 1;
GaussianBlur(img, blurred, Size(), sigma, sigma);
Mat lowContrastMask = abs(img - blurred) < threshold;
Mat sharpened = img*(1+amount) + blurred*(-amount);
img.copyTo(sharpened, lowContrastMask);
任意の画像は、さまざまな周波数の信号の集まりです。高い周波数はエッジを制御し、低い周波数は画像コンテンツを制御します。隣接セルの0や255のように、あるピクセル値から別のピクセル値への急激な変化がある場合、エッジが形成されます。明らかに急激な変化があり、したがってエッジと高周波があります。画像を鮮明にするために、これらの遷移をさらに強化できます。
1つの方法は、自作のフィルターカーネルと画像を畳み込むことです。
import cv2
import numpy as np
image = cv2.imread('images/input.jpg')
kernel = np.array([[-1,-1,-1],
[-1, 9,-1],
[-1,-1,-1]])
sharpened = cv2.filter2D(image, -1, kernel) # applying the sharpening kernel to the input image & displaying it.
cv2.imshow('Image Sharpening', sharpened)
cv2.waitKey(0)
cv2.destroyAllWindows()
明るいバージョンからぼやけたバージョンの画像を差し引く別の方法があります。これは、画像をシャープにするのに役立ちます。ただし、ピクセル値を増やしているだけなので、注意して行う必要があります。グレースケールのピクセル値190を想像してください。これは、380の場合、2の重みで乗算されますが、最大許容ピクセル範囲のために255でトリミングされます。これは情報の損失であり、画像の色あせにつながります。
addWeighted(frame, 1.5, image, -0.5, 0, image);
nsharp mask を使用して画像をシャープにすることができます。アンシャープマスキングの詳細については、 here を参照してください。 OpenCVを使用したPython実装は次のとおりです。
import cv2 as cv
import numpy as np
def unsharp_mask(image, kernel_size=(5, 5), sigma=1.0, amount=1.0, threshold=0):
"""Return a sharpened version of the image, using an unsharp mask."""
blurred = cv.GaussianBlur(image, kernel_size, sigma)
sharpened = float(amount + 1) * image - float(amount) * blurred
sharpened = np.maximum(sharpened, np.zeros(sharpened.shape))
sharpened = np.minimum(sharpened, 255 * np.ones(sharpened.shape))
sharpened = sharpened.round().astype(np.uint8)
if threshold > 0:
low_contrast_mask = np.absolute(image - blurred) < threshold
np.copyto(sharpened, image, where=low_contrast_mask)
return sharpened
def example():
image = cv.imread('my-image.jpg')
sharpened_image = unsharp_mask(image)
cv.imwrite('my-sharpened-image.jpg', sharpened_image)
このトピックを明確にするために、いくつかのポイントを実際に作成する必要があります。
画像の鮮明化は不適切な問題です。言い換えれば、ぼかしは損失の多い操作であり、それから戻ることは一般的に不可能です。
単一の画像をシャープにするには、どのような画像が必要か、どのように画像がぼやけているかの制約(仮定)を何らかの方法で追加する必要があります。これは、自然画像統計の領域です。シャープニングを行うアプローチは、これらの統計をアルゴリズムで明示的または暗黙的に保持します(深層学習は最も暗黙的にコード化されたものです)。 DOGまたはラプラシアンピラミッド分解 のいくつかのレベルをアップウェイトする一般的なアプローチは、ブライアンバーンズの答えの一般化であり、ガウスぼかしが画像を破損し、ウェイトがどのように行われるかを想定していますは、最初にイメージに含まれていたものに関する仮定に関連しています。
他の情報源により、問題を明確にすることができます。このような一般的な情報ソースは、動いているオブジェクトのビデオ、またはマルチビュー設定です。その設定でのシャープ化は、通常 super-resolution と呼ばれます(これは非常に悪い名前ですが、学界で立ち往生しています)。 OpenCVの超解像メソッド が長い間ありました。しかし、実際の問題に対しては通常うまく機能しませんが、最後にチェックアウトしました。ここでもディープラーニングが素晴らしい結果をもたらすと期待しています。たぶん、誰かがそこに価値のあるものについてのコメントを投稿するでしょう。
画像をシャープにするために、フィルターを使用できます(上記の多くの回答のように)
kernel = np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, 0]], np.float32)
kernel/=denominator*kernel
it will the most when the denominator is 1 and will decrease as increased(2.3..)
the most used one is when the denominator is 3.
以下は実装です。
kernel = np.array([[-1、-1、-1]、[-1、8、-1]、[-1、-1、0]]、np.float32)
kernel = 1/3 * kernel
dst = cv2.filter2D(image、-1、kernel)