【模糊检测】

模糊检测

模糊图像特点:边缘模糊,梯度变化小。

传统方法

更多方法模糊图像检测-无参考图像的清晰度评价 - 知乎 (zhihu.com)

拉普拉斯方差

从空间域出发,分析模糊图像的梯度比较小。拉普拉斯算子测量图像的二阶导数,突出显示包含快速强度变化的图像区域。如果方差低,表示图像边缘非常少。

使用OpenCV库,技巧是设置正确阈值,阈值太低会错误将图像标记为模糊,太高,模糊图像不会被标记。

缺点:阈值需要自己设置,光照环境会对效果有很大影响。对色彩很敏感,大色块就不算模糊。无法感知运动模糊。

	import cv2
    
    image = cv2.imread(imagePath)
	gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
	value =  cv2.Laplacian(image, cv2.CV_64F).var() # 大于value表示清晰图像

快速傅里叶变化

对频域进行处理分析,模糊图像频率低;

使用matplotlib和numpy库.

缺点:对彩色图片适应良好,暗一点的图片就g。针对有清晰局部的运动模糊照片判断不行。

import numpy as np
import cv2
import imutils

def detect_blur_fft(image, size=60, thresh=10, vis=False):
# 输入: image:我们用于模糊检测的输入图像
# size:围绕图像中心点的半径大小,我们将对其进行 FFT 移位归零
# 将与幅度的平均值进行比较的值,以确定图像是否被认为是模糊的
	(h, w) = image.shape 
	(cX, cY) = (int(w / 2.0), int(h / 2.0))  # 导出中心 (x, y) 坐标
	fft = np.fft.fft2(image)  #计算 FFT 以找到频率变换
	fftShift = np.fft.fftshift(fft) # 然后移位零频率分量(即直流分量位于左上角)到中心
	fftShift[cY - size:cY + size, cX - size:cX + size] = 0 #将 FFT 移位的中心区域清零(即,删除低频率)
	fftShift = np.fft.ifftshift(fftShift) # 应用逆移使得低频再次到左上角
	recon = np.fft.ifft2(fftShift) # 逆FFT
	magnitude = 20 * np.log(np.abs(recon)) # 计算重建图像的幅度值,
	mean = np.mean(magnitude)  # 计算幅度值的平均值
	return (mean, mean <= thresh) # 如果平均值小于阈值,图像将被视为“模糊”

image = cv2.imread("dataset/motion_blur2.jpg")
image = imutils.resize(image, width=500) 
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
(mean, blurry) = detect_blur_fft(gray)
# print(mean, blurry)

image = np.dstack([gray] * 3)
color = (0, 0, 255) if blurry else (0, 255, 0)
text = "Blurry ({:.4f})" if blurry else "Not Blurry ({:.4f})"
text = text.format(mean)
cv2.putText(image, text, (10, 25), cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2)
print("[INFO] {}".format(text))

# show the output image
# cv2.imshow("Output", image)
# cv2.waitKey(0)

检测视频

# import the necessary packages
from imutils.video import VideoStream
from pyimagesearch.blur_detector import detect_blur_fft
import argparse
import imutils
import time
import cv2
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-t", "--thresh", type=int, default=10,
	help="threshold for our blur detector to fire")
args = vars(ap.parse_args())

# initialize the video stream and allow the camera sensor to warm up
print("[INFO] starting video stream...")
vs = VideoStream(src=0).start()
time.sleep(2.0)
# loop over the frames from the video stream
while True:
	# grab the frame from the threaded video stream and resize it
	# to have a maximum width of 400 pixels
	frame = vs.read()
	frame = imutils.resize(frame, width=500)
	# convert the frame to grayscale and detect blur in it
	gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
	(mean, blurry) = detect_blur_fft(gray, size=60,
		thresh=args["thresh"], vis=False)
	color = (0, 0, 255) if blurry else (0, 255, 0)
	text = "Blurry ({:.4f})" if blurry else "Not Blurry ({:.4f})"
	text = text.format(mean)
	cv2.putText(frame, text, (10, 25), cv2.FONT_HERSHEY_SIMPLEX,
		0.7, color, 2)
	# show the output frame
	cv2.imshow("Frame", frame)
	key = cv2.waitKey(1) & 0xFF
	# if the `q` key was pressed, break from the loop
	if key == ord("q"):
		break
# do a bit of cleanup
cv2.destroyAllWindows()
vs.stop()

参考文档OpenCV Fast Fourier Transform (FFT) for blur detection in images and video streams - PyImageSearch

SVD

缺点:对色彩敏感,无法识别运动模糊。

def get_blur_degree(image_file, sv_num=10):
    img = cv2.imread(image_file,cv2.IMREAD_GRAYSCALE)
    u, s, v = np.linalg.svd(img)
    top_sv = np.sum(s[0:sv_num])
    total_sv = np.sum(s)
    return top_sv/total_sv

机器学习

SVM:0-1分类;先计算数据集的算子,svm在算子之间找一个界面作为模糊和清晰界限。

缺点:动态模糊无法识别,颜色暗淡图像识别为模糊,和传统方法相比,阈值不用自己找了,但是对暗度低的图片识别效果也不行。

python代码
from sklearn.metrics import accuracy_score
from sklearn import svm
import os
import cv2
import numpy as np
import pandas as pd
from tensorflow.keras.preprocessing import image
from sklearn.metrics import accuracy_score
from sklearn.utils import shuffle
from tqdm import tqdm

# loading train data


def get_features(path):
    input_size = (512, 512)

    images = os.listdir(path)
    features = []
    for i in tqdm(images):
        feature = []

        # gray = cv2.imread(path+img,0)
        # laplacian_var = cv2.Laplacian(gray, cv2.CV_64F).var()

        img = image.load_img(path+i, target_size=input_size)
        # img = image.load_img(path+i)

        gray = cv2.cvtColor(np.asarray(img), cv2.COLOR_BGR2GRAY)
        laplacian = cv2.Laplacian(gray, cv2.CV_64F)
        feature.extend([laplacian.var(), np.amax(laplacian)])

        features.append(feature)
    return pd.DataFrame(features)


path_undis = '../CERTH_ImageBlurDataset/TrainingSet/Undistorted/'
path_art_blur = '../CERTH_ImageBlurDataset/TrainingSet/Artificially-Blurred/'
path_nat_blur = '../CERTH_ImageBlurDataset/TrainingSet/Naturally-Blurred/'

feature_undis = get_features(path_undis)
print('Undistorted DONE')
feature_art_blur = get_features(path_art_blur)
print('Artificially-Blurred DONE')
feature_nat_blur = get_features(path_nat_blur)
print("Naturally-Blurred DONE")
feature_art_blur.to_csv('./data/art_blur.csv', index=False)
feature_nat_blur.to_csv('./data/nat_blur.csv', index=False)
feature_undis.to_csv('./data/undis.csv', index=False)

# uncomment below code if you have pre-calculated features

# feature_art_blur = pd.read_csv('./data/art_blur.csv')
# feature_nat_blur = pd.read_csv('./data/nat_blur.csv')
# feature_undis = pd.read_csv('./data/undis.csv')

images = pd.DataFrame()

images = pd.DataFrame()
images = images.append(feature_undis)
images = images.append(feature_art_blur)
images = images.append(feature_nat_blur)

x_train = np.array(images)

y_train = np.concatenate((np.zeros((feature_undis.shape[0], )), np.ones(
    (feature_art_blur.shape[0]+feature_nat_blur.shape[0], ))), axis=0)

x_train, y_train = shuffle(x_train, y_train)


# Training model
svm_model = svm.SVC(C=50, kernel='rbf')

svm_model.fit(x_train, y_train)

pred = svm_model.predict(x_train)
print('\nTraining Accuracy:', accuracy_score(y_train, pred))

CERTH数据集上87.57%准确率,我自己跑的精度87.56%。

代码链接im-vvk/Blur-Image-Detection: Classification of Blurred and Non-Blurred Images using opencv and SVM (github.com)

参考文档Mobile Image Blur Detection with Machine Learning | by Benedikt Brief | snapADDY Tech Blog — Tales from the Devs | Medium

深度学习

CNN:3层卷积。

缺点:相比支持向量机,没什么长进,可能因为层数太少了。

import numpy as np
import pandas as pd
import os
import pickle
from tensorflow.keras.preprocessing import image
import tensorflow as tf
from tensorflow.keras import utils
from sklearn.metrics import accuracy_score

input_size = (300, 300)

with open('./X_train_300.pkl', 'rb') as picklefile:
    X_train = pickle.load( picklefile)


with open('./y_train_300.pkl', 'rb') as picklefile:
    y_train = pickle.load( picklefile)


with open('./X_test_300.pkl', 'rb') as picklefile:
    X_test = pickle.load(picklefile)


with open('./y_test_300.pkl', 'rb') as picklefile:
    y_test = pickle.load(picklefile)

model = tf.keras.models.Sequential([
  tf.keras.layers.Conv2D(32, (3,3), activation = 'relu', input_shape=(input_size[0], input_size[1], 3)),
  tf.keras.layers.MaxPooling2D(2,2),
  tf.keras.layers.Conv2D(64, (5,5), activation = 'relu'),
  tf.keras.layers.MaxPooling2D(2,2),
  tf.keras.layers.Conv2D(128, (5,5), activation = 'relu'),
  tf.keras.layers.MaxPooling2D(2,2),
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(1024, activation='relu'),
  tf.keras.layers.Dropout(0.5),
  tf.keras.layers.Dense(512, activation='relu'),
  tf.keras.layers.Dropout(0.5),
  # tf.keras.layers.Dense(256, activation='relu'),
  # tf.keras.layers.Dropout(0.5),
  tf.keras.layers.Dense(2, activation='softmax')
])

model.summary()

model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

traindata = np.stack(X_train)
testdata = np.stack(X_test)
trainlabel = utils.to_categorical(y_train)
testlabel = utils.to_categorical(y_test)

# epochs = 10
# for i in range(epochs):
model.fit(traindata, trainlabel, batch_size=16, epochs=10, validation_data=(testdata, testlabel), verbose=1)
print("Model training complete...")
(loss, accuracy) = model.evaluate(testdata, testlabel, batch_size = 32, verbose = 1)
model.save(r'./model/model300.h5')

print("accuracy: {:.2f}%".format(accuracy * 100))


CERTH数据集上87.3%准确率,我自己跑的精度训练集73.51%。

代码链接akhileshkb/CERTH_ImageBlurDataset: model for CERTH image blur dataset challenge (github.com)

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小橘AI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值