zoukankan      html  css  js  c++  java
  • python检测图片是否有马赛克内容

    首先是Canny边缘检测,将图片的边缘检测出来,参考博客https://www.cnblogs.com/techyan1990/p/7291771.html

    原理讲的很清晰,给原博主一个赞

    边缘检测之后按照正方形检索来判定是否是马赛克内容,参考博客https://blog.csdn.net/ZhanCF/article/details/49736823

    原理知晓了之后就很好做了

    话说MATLAB转化为python的过程还是很有趣的

    另外做完这些才发现其实还有更好的解决方法

    from PIL import Image
    import numpy as np
    import math
    import warnings
    
    #算法来源,博客https://www.cnblogs.com/techyan1990/p/7291771.html和https://blog.csdn.net/zhancf/article/details/49736823
    highhold=200#高阈值
    lowhold=40#低阈值
    warnings.filterwarnings("ignore")
    demo=Image.open("noise_check//23.jpg")
    im=np.array(demo.convert('L'))#灰度化矩阵
    print(im.shape)
    print(im.dtype)
    height=im.shape[0]#尺寸
    width=im.shape[1]
    gm=[[0 for i in range(width)]for j in range(height)]#梯度强度
    gx=[[0 for i in range(width)]for j in range(height)]#梯度x
    gy=[[0 for i in range(width)]for j in range(height)]#梯度y
    theta=0#梯度方向角度360度
    dirr=[[0 for i in range(width)]for j in range(height)]#0,1,2,3方位判定值
    highorlow=[[0 for i in range(width)]for j in range(height)]#强边缘、弱边缘、忽略判定值2,1,0
    rm=np.array([[0 for i in range(width)]for j in range(height)])#输出矩阵
    #高斯滤波平滑,3x3
    for i in range(1,height-1,1):
        for j in range(1,width-1,1):
            rm[i][j]=im[i-1][j-1]*0.0924+im[i-1][j]*0.1192+im[i-1][j+1]*0.0924+im[i][j-1]*0.1192+im[i][j]*0.1538+im[i][j+1]*0.1192+im[i+1][j-1]*0.0924+im[i+1][j]*0.1192+im[i+1][j+1]*0.0924
    for i in range(1,height-1,1):#梯度强度和方向
        for j in range(1,width-1,1):
            gx[i][j]=-rm[i-1][j-1]+rm[i-1][j+1]-2*rm[i][j-1]+2*rm[i][j+1]-rm[i+1][j-1]+rm[i+1][j+1]
            gy[i][j]=rm[i-1][j-1]+2*rm[i-1][j]+rm[i-1][j+1]-rm[i+1][j-1]-2*rm[i+1][j]-rm[i+1][j+1]
            gm[i][j]=pow(gx[i][j]*gx[i][j]+gy[i][j]*gy[i][j],0.5)
            theta=math.atan(gy[i][j]/gx[i][j])*180/3.1415926
            if theta>=0 and theta<45:
                dirr[i][j]=2
            elif theta>=45 and theta<90:
                dirr[i][j]=3
            elif theta>=90 and theta<135:
                dirr[i][j]=0
            else:
                dirr[i][j]=1
    for i in range(1,height-1,1):#非极大值抑制,双阈值监测
        for j in range(1,width-1,1):
            NW=gm[i-1][j-1]
            N=gm[i-1][j]
            NE=gm[i-1][j+1]
            W=gm[i][j-1]
            E=gm[i][j+1]
            SW=gm[i+1][j-1]
            S=gm[i+1][j]
            SE=gm[i+1][j+1]
            if dirr[i][j]==0:
                d=abs(gy[i][j]/gx[i][j])
                gp1=(1-d)*E+d*NE
                gp2=(1-d)*W+d*SW
            elif dirr[i][j]==1:
                d=abs(gx[i][j]/gy[i][j])
                gp1=(1-d)*N+d*NE
                gp2=(1-d)*S+d*SW
            elif dirr[i][j]==2:
                d=abs(gx[i][j]/gy[i][j])
                gp1=(1-d)*N+d*NW
                gp2=(1-d)*S+d*SE
            elif dirr[i][j]==3:
                d=abs(gy[i][j]/gx[i][j])
                gp1=(1-d)*W+d*NW
                gp2=(1-d)*E+d*SE
            if gm[i][j]>=gp1 and gm[i][j]>=gp2:
                if gm[i][j]>=highhold:
                    highorlow[i][j]=2
                    rm[i][j]=1
                elif gm[i][j]>=lowhold:
                    highorlow[i][j]=1
                else:
                    highorlow[i][j]=0
                    rm[i][j]=0
            else:
                highorlow[i][j]=0
                rm[i][j]=0
    for i in range(1,height-1,1):#抑制孤立低阈值点
        for j in range(1,width-1,1):
            if highorlow[i][j]==1 and (highorlow[i-1][j-1]==2 or highorlow[i-1][j]==2 or highorlow[i-1][j+1]==2 or highorlow[i][j-1]==2 or highorlow[i][j+1]==2 or highorlow[i+1][j-1]==2 or highorlow[i+1][j]==2 or highorlow[i+1][j+1]==2):
                #highorlow[i][j]=2
                rm[i][j]=1
    #img=Image.fromarray(rm)#矩阵化为图片
    #img.show()
    #正方形法判定是否有马赛克
    value=35
    lowvalue=16
    imgnumber=[0 for i in range(value)]
    for i in range(1,height-1,1):#性价比高的8点判定法
        for j in range(1,width-1,1):
            for k in range(lowvalue,value):
                count=0
                if i+k-1>=height or j+k-1>=continue
                if rm[i][j]!=0:count+=1#4个顶点
                if rm[i+k-1][j]!=0:count+=1
                if rm[i][j+k-1]!=0:count+=1
                if rm[i+k-1][j+k-1]!=0:count+=1
                e=(k-1)//2
                if rm[i+e][j]!=0:count+=1
                if rm[i][j+e]!=0:count+=1
                if rm[i+e][j+k-1]!=0:count+=1
                if rm[i+k-1][j+e]!=0:count+=1
                if count>=6:
                    imgnumber[k]+=1
    for i in range(lowvalue,value):
        print("length:{}  number:{}".format(i,imgnumber[i]))

    结果图可以上一下了

    可以看出在一定程度上能够检测出马赛克内容

    原图

    边缘图案

     正方形数量

  • 相关阅读:
    Java第九次作业
    Java第八次作业
    Java第七次作业
    Java第六次作业
    Java第五次作业
    Java第四次作业
    Java第三次作业
    Java第二次作业
    Java第一次作业
    高级工程师和初级工程师之间的一道坎
  • 原文地址:https://www.cnblogs.com/ljy1227476113/p/12171146.html
Copyright © 2011-2022 走看看