Tuple[float, bool]: """ FFTを使用してピンボケを検出 Args: image: 入力画像(グレースケール) Returns: score: ボケの度合いを示すスコア(低いほどボケている) "> Tuple[float, bool]: """ FFTを使用してピンボケを検出 Args: image: 入力画像(グレースケール) Returns: score: ボケの度合いを示すスコア(低いほどボケている) "> Tuple[float, bool]: """ FFTを使用してピンボケを検出 Args: image: 入力画像(グレースケール) Returns: score: ボケの度合いを示すスコア(低いほどボケている) ">
import sys
import cv2 # opencv-python
import numpy as np
from scipy.ndimage import variance
from typing import Tuple
class BlurDetector:
def __init__(self):
self.laplacian_threshold = 100 # ラプラシアンによるブレ検出の閾値
self.fft_threshold = 10 # FFTによるボケ検出の閾値
def detect_motion_blur(self, image: np.ndarray) -> Tuple[float, bool]:
"""
ラプラシアン変換を使用して動きブレを検出
Args:
image: 入力画像(グレースケール)
Returns:
score: ブレの度合いを示すスコア(低いほどブレている)
is_blurred: ブレているかどうかのブール値
"""
# ラプラシアン変換で輪郭を強調
laplacian = cv2.Laplacian(image, cv2.CV_64F)
# 分散を計算
score = variance(laplacian)
is_blurred = score < self.laplacian_threshold
return score, is_blurred
def detect_focus_blur(self, image: np.ndarray) -> Tuple[float, bool]:
"""
FFTを使用してピンボケを検出
Args:
image: 入力画像(グレースケール)
Returns:
score: ボケの度合いを示すスコア(低いほどボケている)
is_blurred: ボケているかどうかのブール値
"""
# 画像をフーリエ変換
f_transform = np.fft.fft2(image)
f_shift = np.fft.fftshift(f_transform)
# パワースペクトルを計算
magnitude_spectrum = 20 * np.log(np.abs(f_shift))
# 高周波成分の平均を計算
rows, cols = image.shape
center_row, center_col = rows // 2, cols // 2
mask = np.zeros_like(magnitude_spectrum)
mask[center_row-30:center_row+30, center_col-30:center_col+30] = 1
high_freq_mean = np.mean(magnitude_spectrum * (1 - mask))
score = high_freq_mean
is_blurred = score < self.fft_threshold
return score, is_blurred
def analyze_image(self, image_path: str) -> dict:
"""
画像を分析してブレとボケの両方を検出
Args:
image_path: 画像ファイルのパス
Returns:
dict: 分析結果を含む辞書
"""
# 画像を読み込んでグレースケールに変換
image = cv2.imread(image_path)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# モーションブレとピンボケを検出
motion_score, has_motion_blur = self.detect_motion_blur(gray)
focus_score, has_focus_blur = self.detect_focus_blur(gray)
return {
"motion_blur": {
"score": motion_score,
"detected": has_motion_blur
},
"focus_blur": {
"score": focus_score,
"detected": has_focus_blur
}
}
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python detect_blur.py <image_file>")
sys.exit(1)
image_file = sys.argv[1]
detector = BlurDetector()
result = detector.analyze_image(image_file)
print(result)

python detect_blur.py C:\Users\XXX\Pictures\Tz5-smqGODc_ZPXk.jpg {'motion_blur': {'score': 97.60005976340015, 'detected': True}, 'focus_blur': {'score': 137.49029206799617, 'detected': False}}