文章目录
cv2图像异常检测
摄像头画面遮挡、模糊、偏色、亮度异常检测
import cv2
import numpy as np
import math
from PIL import Image, ImageDraw, ImageFont
import os
"""
def occlusion1(path_img, percent=0.5):
# 读取图像
img = cv2.imread(path_img)
# 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 找到轮廓
contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
#cv2.drawContours(img,contours,-1,(0,0,255),3)
#cv2.imshow("img", img)
#cv2.waitKey(0)
# 计算轮廓的总面积
total_area = 0
for c in contours:
total_area += cv2.contourArea(c)
# 计算图像的总面积
img_area = img.shape[0] * img.shape[1]
# 计算被遮挡的比例
percentage = total_area / img_area
#print(percentage)
# 如果超过50%,识别为被遮挡
if percentage > percent:
print(path_img,percentage,'被遮挡')
return True
else:
print(path_img,percentage,'未被遮挡')
return False
print("遮挡判断方法1")
occlusion1(r'occlusion\1.jpg')
occlusion1(r'occlusion\2.jpg')
occlusion1(r'occlusion\3.jpg')
occlusion1(r'occlusion\4.jpg')
occlusion1(r'occlusion\5.jpg')
def occlusion(path_img, threshold=500):
img = cv2.imread(path_img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#print(gray,gray.shape)
#方差
np_var = np.var(gray)
if np_var < threshold:
print(path_img,np_var,'被遮挡')
return True
else:
print(path_img,np_var,'未被遮挡')
return False
#print("遮挡判断方法2")
#occlusion(r'occlusion\1.jpg')
#occlusion(r'occlusion\2.jpg')
#occlusion(r'occlusion\3.jpg')
#occlusion(r'occlusion\4.jpg')
#occlusion(r'occlusion\5.jpg')
"""
# cut_size 图像切分的尺寸 (3*3)可以自己设置
def occlusion(path_img, cut_size = 3, std_grey_thres = 25, std_lap_thres=10, black_pct=0.9):
img = cv2.imread(path_img)
# 灰度图
grey_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 拉普拉斯变换
gray_lap = cv2.Laplacian(grey_img, cv2.CV_64F)
#cv2.imshow("grey_img", grey_img)
#cv2.waitKey(0)
#cv2.imshow("gray_lap", gray_lap)
#cv2.waitKey(0)
#cv2.destroyAllWindows()
grey_img_shape = grey_img.shape
height, width = grey_img_shape[0], grey_img_shape[1]
height_div = height // cut_size
width_div = width // cut_size
# 循环的尺寸,这样循环就不会取到边界
range_height_size = height_div * cut_size
range_width_size = width_div * cut_size
print("height, width", height, width)
print("range_height_size,range_width_size", range_height_size, range_width_size)
print("height_div,width_div",height_div,width_div)
print("grey_img shape",grey_img.shape)
print("np.var(gray)",np.var(grey_img))
flag = False
# 切分循环
for i in range(0, range_height_size, height_div):
for j in range(0, range_width_size, width_div):
# 获取当前区域的灰度图像素
subimg = grey_img[i: i+height_div, j: j+width_div]
# 获取当前区域 拉普拉斯算子 的边缘信息像素信息
sublap = gray_lap[i: i+height_div, j: j+width_div]
# 获取标准差
stddev_g = np.std(subimg)
stddev_l = np.std(sublap)
# 黑色白分比
dark_part = cv2.inRange(subimg, 0, 30)
dark_pixel = np.sum(dark_part > 0)
# 总的像素值
total_pixel = np.size(subimg)
# 占比
percentage = dark_pixel / total_pixel
print("subimg shape",subimg.shape)
print("i",i,"j",j,"stddev_g",stddev_g,"stddev_l",stddev_l,"percentage",percentage)
#cv2.imshow("subimg", subimg)
#cv2.imshow("sublap", sublap)
#cv2.waitKey(0)
#cv2.destroyAllWindows()
if stddev_g < std_grey_thres and stddev_l < std_lap_thres and percentage > black_pct:
print("图像遮挡")
flag = True
break
else:
print("图像未被遮挡")
if flag:
break
return flag
# occlusion(r'occlusion\2.jpg')
def variance_of_laplacian(path_img, thres=0.001):
image_gray = cv2.imread(path_img,cv2.IMREAD_GRAYSCALE)
height, width = image_gray.shape
#print(width, height)
laplacian = cv2.Laplacian(image_gray, cv2.CV_64F).var()
blurness = laplacian / (width * height)
print(path_img,blurness,laplacian)
if blurness < thres:
print("模糊")
return True
else:
print("不模糊")
return False
#print("摄像头画面模糊判断方法")
#variance_of_laplacian(r'blur\1_clear.jpg')
#variance_of_laplacian(r'blur\2_blur.jpg')
#variance_of_laplacian(r'blur\3_half_blur.jpg')
#variance_of_laplacian(r'blur\4_half_blur.jpg')
def color_deviation(path_img,thres=1):
img = cv2.imread(path_img)
img_lab = cv2.cvtColor(img, cv2.COLOR_BGR2Lab)
l, a, b = cv2.split(img_lab)
h, w, _ = img.shape
sum_a = np.sum(a)
sum_b = np.sum(b)
mn = w * h
da = sum_a / mn - 128
db = sum_b / mn - 128
# 求平均色度
D = math.sqrt(da * da + db * db)
# 求色度中心距
a = a.astype(np.int16)
a2 = a - 128 - da
a3 = np.maximum(a2, -a2)
b = b.astype(np.int16)
b2 = b - 128 - db
b3 = np.maximum(b2, -b2)
ma = np.sum(a3)
mb = np.sum(b3)
ma = ma / mn
mb = mb / mn
M = math.sqrt(ma * ma + mb * mb)
# 偏色因子K
M = M + 0.000000001
K = D / M
print(path_img,K)
if K > thres:
print("偏色")
return True
else:
print("不偏色")
return False
#print("摄像头画面偏色判断方法")
#color_deviation(r'deviation\1_1.jpg')
#color_deviation(r'deviation\1_2.jpg')
#color_deviation(r'deviation\2_1.jpg')
#color_deviation(r'deviation\2_2.jpg')
def backlighting(path_img,thres=0.5):
img = cv2.imread(path_img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
dark_part = cv2.inRange(gray, 0, 60)
bright_part = cv2.inRange(gray, 225, 256)
dark_pixel = np.sum(dark_part > 0) # 是一个true和false的数组
bright_pixel = np.sum(bright_part > 0)
# 总的像素值
total_pixel = np.size(gray)
# 占比
percentage = dark_pixel / total_pixel + bright_pixel / total_pixel
print(path_img,percentage)
if percentage > thres:
print("亮度异常")
return True
else:
print("亮度正常")
return False
#print("摄像头画面亮度异常判断方法")
#backlighting(r'backlighting\1.jpg')
#backlighting(r'backlighting\2.jpg')
#backlighting(r'backlighting\3.jpg')
#backlighting(r'backlighting\4.jpg')
#backlighting(r'backlighting\5.jpg')
def put_text(img, text, color="green"):
#font = cv2.FONT_HERSHEY_SIMPLEX
#color = (0, 0, 255) # BGR 格式颜色
#thickness = 2
#font_scale = 1
#text_size, _ = cv2.getTextSize(text, font, font_scale, thickness)
#text_x = int((img.shape[1] - text_size[0]) / 2)
#text_y = int((img.shape[0] + text_size[1]) / 2)
#cv2.putText(img, text, (text_x, text_y), font, font_scale, color, thickness)# 显示图片
#导入字体文件
fontpath = r'C:\Windows\Fonts\simsun.ttc'
#设置字体的颜色
b,g,r,a = 0,255,0,0
if color == "red":
b,g,r,a = 0,0,255,0
#设置字体大小
font = ImageFont.truetype(fontpath,24)
#将numpy array的图片格式转为PIL的图片格式
img_pil = Image.fromarray(img)
#创建画板
draw = ImageDraw.Draw(img_pil)
#text_x = int((img.shape[1] - 24) / 2)
text_y = int((img.shape[0]) / 2)
#在图片上绘制中文
draw.text((100,text_y),text,font=font,fill=(b,g,r,a))
#将图片转为numpy array的数据格式
img = np.array(img_pil)
#cv2.imshow('image', img)
#cv2.waitKey(0)
#cv2.destroyAllWindows()
return img
def abnormal(path_img, occlusion_cut_size = 3, occlusion_std_grey_thres = 25, occlusion_std_lap_thres=10, occlusion_black_pct=0.9, blur_thres=0.001, color_deviation_thres=1, backlighting_thres=0.5):
img1 = cv2.imread(path_img)
img1 = cv2.resize(img1, (400,300), interpolation=cv2.INTER_AREA)
img2 = img1.copy()
img3 = img1.copy()
img4 = img1.copy()
result_occlusion = False
result_blur = False
result_color_deviation = False
result_backlighting = False
result_all = False
if occlusion(path_img,cut_size = occlusion_cut_size, std_grey_thres = occlusion_std_grey_thres, std_lap_thres=occlusion_std_lap_thres, black_pct=occlusion_black_pct):
img1 = put_text(img1,'摄像头画面遮挡',color="red")
result_occlusion = True
else:
img1 = put_text(img1,'摄像头画面未遮挡',color="green")
result_occlusion = False
if variance_of_laplacian(path_img,blur_thres):
img2 = put_text(img2,'摄像头画面模糊',color="red")
result_blur = True
else:
img2 = put_text(img2,'摄像头画面清晰',color="green")
result_blur = False
if color_deviation(path_img,color_deviation_thres):
img3 = put_text(img3,'摄像头画面偏色',color="red")
result_color_deviation = True
else:
img3 = put_text(img3,'摄像头画面不偏色',color="green")
result_color_deviation = False
if backlighting(path_img,backlighting_thres):
img4 = put_text(img4,'摄像头画面亮度异常',color="red")
result_backlighting = True
else:
img4 = put_text(img4,'摄像头画面亮度正常',color="green")
result_backlighting = False
img_1_2 = np.hstack((img1,img2))
img_3_4 = np.hstack((img3,img4))
img = np.vstack([img_1_2,img_3_4])
cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
dirname = os.path.dirname(path_img)
dirname = dirname.replace('/', '_')
basename = os.path.basename(path_img)
split = os.path.splitext(basename)
name = split[0]
name = dirname + "_" + name + ".jpg"
#print("name",name)
cv2.imwrite(name, img)
if result_occlusion or result_blur or result_color_deviation or result_backlighting:
result_all = True
print(result_all)
return result_all,result_occlusion,result_blur,result_color_deviation,result_backlighting
"""
abnormal(r'backlighting\1.jpg')
abnormal(r'backlighting\2.jpg')
abnormal(r'backlighting\3.jpg')
abnormal(r'backlighting\4.jpg')
abnormal(r'backlighting\5.jpg')
abnormal(r'deviation\1_1.jpg')
abnormal(r'deviation\1_2.jpg')
abnormal(r'blur\1_clear.jpg')
abnormal(r'blur\2_blur.jpg')
"""
abnormal(r'occlusion\1.jpg')
abnormal(r'occlusion\2.jpg')
abnormal(r'occlusion\3.jpg')
abnormal(r'occlusion\4.jpg')
abnormal(r'occlusion\5.jpg')
abnormal(r'backlighting\6.jpg')
abnormal(r'backlighting\7.jpg')
abnormal(r'backlighting\8.jpg')
abnormal(r'deviation\3.jpg')
abnormal(r'deviation\4.jpg')
abnormal(r'deviation\5.jpg')
abnormal(r'blur\3_half_blur.jpg')
abnormal(r'blur\4_half_blur.jpg')
abnormal(r'blur\5.jpg',blur_thres=0.001)
abnormal(r'blur\6.jpg',blur_thres=0.001)
abnormal(r'blur\7.jpg')