python实现基于超像素距离的图像显著性检测

本文主要是借鉴了

基于超像素距离的图像显著性检测(Matlab2017a)

在此基础上改用python复现并加以注释,如有错误,欢迎指正。

'''导入一张图片,将图片压缩为300*300'''
img = cv2.imread("../image/ILSVRC2012_test_00000004.jpg")
print("原始尺寸:",img.shape)
size=(300,300)
img = cv2.resize(img,(300,300))
print("压缩后尺寸:",img.shape)
#原始尺寸: (366, 400, 3)
#压缩后尺寸: (300, 300, 3)
'''对压缩后的图片进行一次高斯平滑'''
kernel_size=(5,5)
sigma=1.5
IS=cv2.GaussianBlur(img,kernel_size,sigma)
'''对原始图片进行超像素分割'''
#初始化slic项,超像素平均尺寸20(默认为10),平滑因子20
slic = cv2.ximgproc.createSuperpixelSLIC(img,region_size=20,ruler = 20.0)
slic.iterate(10)     #迭代次数,越大效果越好
mask_slic = slic.getLabelContourMask() #获取Mask,超像素边缘Mask==1
label = slic.getLabels()        #获取超像素标签
number_slic = slic.getNumberOfSuperpixels()  #获取超像素数目
(m,n)=label.shape
print("超像素标签尺寸:",label.shape)
print("超像素数目:",number_slic)
#m= 300
#n= 300
#超像素标签尺寸: (300, 300)
#超像素数目: 218
'''在原图上绘制超像素边界'''
mask_inv_slic = cv2.bitwise_not(mask_slic)
img_slic = cv2.bitwise_and(img,img,mask =  mask_inv_slic) 
cv2.imshow("img_slic",img_slic)

python实现基于超像素距离的图像显著性检测_第1张图片
完整代码:

import cv2
import numpy as np
import math
np.set_printoptions(threshold=np.inf)

#导入一张图片,将图片压缩为300*300
img = cv2.imread("../image/ILSVRC2012_test_00000004.jpg")
cv2.imshow("img",img)
print("原始尺寸:",img.shape)



size=(300,300)
img = cv2.resize(img,(300,300))
#cv2.imshow("img2",img)
print("压缩后尺寸:",img.shape)



#对压缩后的图片进行一次高斯平滑
kernel_size=(5,5)
sigma=1.5
IS=cv2.GaussianBlur(img,kernel_size,sigma)
print("IS尺寸:",IS.shape)
cv2.imshow("gaussian",IS)



'''对原始图片进行超像素分割'''
#初始化slic项,超像素平均尺寸20(默认为10),平滑因子20
slic = cv2.ximgproc.createSuperpixelSLIC(img,region_size=20,ruler = 20.0)
slic.iterate(10)     #迭代次数,越大效果越好
mask_slic = slic.getLabelContourMask() #获取Mask,超像素边缘Mask==1
label = slic.getLabels()        #获取超像素标签
number_slic = slic.getNumberOfSuperpixels()  #获取超像素数目
(m,n)=label.shape
print("m=",m)
print("n=",n)
print("超像素标签尺寸:",label.shape)
print("超像素数目:",number_slic)

'''在原图上绘制超像素边界'''
mask_inv_slic = cv2.bitwise_not(mask_slic)
img_slic = cv2.bitwise_and(img,img,mask =  mask_inv_slic)
cv2.imshow("img_slic",img_slic)


'''建立一个n*5维的矩阵'''
supmean= np.zeros((number_slic,5),dtype=np.uint64)
minx=np.zeros((number_slic,2),dtype=np.uint64)
print("超像素矩阵的类型:",supmean.dtype)
print("超像素矩阵的尺寸:",supmean.shape)

labelnum=np.zeros(number_slic)

for i in range(0,m):
    for j in range(0,n):
        supmean[label[i][j],0]=supmean[label[i][j],0]+i
        supmean[label[i][j],1]=supmean[label[i][j],1]+j
        #后面为颜色信息
        supmean[label[i][j],2]=(supmean[label[i][j],2]+np.uint64(IS[i][j][0]))
        supmean[label[i][j],3]=(supmean[label[i][j],3]+np.uint64(IS[i][j][1]))
        supmean[label[i][j],4]=(supmean[label[i][j],4]+np.uint64(IS[i][j][2]))
        labelnum[label[i][j]]=labelnum[label[i][j]]+1

for i in range(0,number_slic):
    supmean[i][0]=np.uint16(supmean[i][0]/labelnum[i])
    supmean[i][1]=np.uint16(supmean[i][1]/labelnum[i])
    supmean[i][2]=np.uint16(supmean[i][2]/labelnum[i])
    supmean[i][3]=np.uint16(supmean[i][3]/labelnum[i])
    supmean[i][4]=np.uint16(supmean[i][4]/labelnum[i])

IM=np.zeros((3,300,300), dtype=np.uint8)
#3*300*300
for i in range(0,m):
    for j in range(0,n):
        IM[0][i][j]=np.uint8(supmean[label[i][j],2])
        IM[1][i][j]=np.uint8(supmean[label[i][j], 3])
        IM[2][i][j]=np.uint8(supmean[label[i][j], 4])

print(supmean[0][1])

#supim=uint8(cat(3,IM(:,:,1),IM(:,:,2),IM(:,:,3)));
#print(IM)


#全局
supmean=supmean.astype(np.float)
dist_all=np.zeros(number_slic)
print("dist_all的尺寸:",dist_all.shape)
w0=0.1
for i in range(0,number_slic):
    for j in range(0,number_slic):
        dist_all[i]=dist_all[i]+(w0*(supmean[i][0]-supmean[j][0])**2+
                                 w0*(supmean[i][1]-supmean[j][1])**2+
                                 (supmean[i][2]-supmean[j][2])**2+
                                 (supmean[i][3]-supmean[j][3])**2+
                                 (supmean[i][4]-supmean[j][4])**2)**0.5
#归一化
dist_min=np.min(dist_all)
dist_max=np.max(dist_all)
print("all最小值:",dist_min)
print("all最大值:",dist_max)
for i in range(0,number_slic):
    dist_all[i]=(dist_all[i]-dist_min)*255/(dist_max-dist_min)
dist_all=dist_all.astype(np.uint8)
im_all=np.zeros((300,300))
print("im_allchicun:",im_all.shape)
for i in range(0,m):
    for j in range(0,n):
        im_all[i][j]=dist_all[label[i][j]]
im_all=im_all.astype(np.uint8)

#边缘
dist_edge=np.zeros(number_slic)
w0=0.1
thre=70
for i in range(0,number_slic):
    for j in range(0,number_slic):
        if supmean[j][0]<=thre or supmean[j][0]>=m-thre or supmean[j][1] <=thre or supmean[j][1]>=m-thre:
            dist_edge[i]= dist_edge[i]+(w0*(supmean[i][0]-supmean[j][0])**2+
                                        w0*(supmean[i][1]-supmean[j][1])**2+
                                        (supmean[i][2]-supmean[j][2])**2+
                                        (supmean[i][3]-supmean[j][3])**2+
                                        (supmean[i][4]-supmean[j][4])**2)**0.5

#归一化
dist_min=np.min(dist_edge)
dist_max=np.max(dist_edge)
print("edge最小值:",dist_min)
print("edge最大值:",dist_max)
for i in range(0,number_slic):
    dist_edge[i]=(dist_edge[i]-dist_min)*255/(dist_max-dist_min)
dist_edge=dist_edge.astype(np.uint8)
print(dist_edge.shape)
im_edge=np.zeros((300,300))
for i in range(0,m):
    for j in range(0,n):
        im_edge[i][j]=dist_edge[label[i][j]]
im_edge=(im_edge).astype(np.uint8)
#局部
sa=np.ones(number_slic)
w0=0.12
w=0.18
radius=20
for i in range(0,number_slic):
    numerator=0
    denominator=0
    for j in range(0,number_slic):
        dist_ij=((supmean[i][0]-supmean[j][0])**2+(supmean[i][1]-supmean[j][1])**2)
        if i!=j:
            dist_local=(w0*dist_ij+(supmean[i][2]-supmean[j][2])**2+(supmean[i][3]-supmean[j][4])**2+(
                        supmean[i][4]-supmean[j][4])**2)**0.5
            numerator=numerator+math.exp(-w*dist_local)*dist_all[j]
            denominator=denominator+math.exp(-w*dist_local)
    sa[i]=numerator/denominator
sa_max=max(sa)
sa_min=min(sa)
for i in range(0,number_slic):
    sa[i]=(sa[i]-sa_min)*255/(sa_max-sa_min)
sa=sa.astype(np.uint8)
im_local=np.zeros((300,300))
for i in range(0,m):
    for j in range(0,n):
        im_local[i][j]=sa[label[i][j]]
im_local=im_local.astype(np.uint8)

'''对边缘显著性结果进行模糊'''
kernel_size=(5,5)
sigma=1.5
new_edge=cv2.GaussianBlur(im_edge,kernel_size,sigma)

cv2.imshow("im_dege",im_edge)
cv2.imshow("new_edge",new_edge)

cv2.waitKey(0)
cv2.destroyAllWindows()

这里只输出了边缘检测的结果
python实现基于超像素距离的图像显著性检测_第2张图片

你可能感兴趣的:(计算机视觉,opencv,python)