图像异常检测

文章目录

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')

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

绯虹剑心

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

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

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

打赏作者

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

抵扣说明:

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

余额充值