提取每个图片的前k个sift特征点,将所有图片的sift进行k-means聚类,得到n个聚类中心,再将每个图的k个特征点所属相应聚类中心进行直方图统计得到一个n维的图片特征描述。
import cv2
import numpy as np
from PIL import Image
import os
import pandas as pd
from sklearn.cluster import KMeans
num_fea=300
num_words=30
def calcSiftFeature(gray):
sift = cv2.xfeatures2d.SIFT_create(num_fea) # 最多提取200个特征点
kp, des = sift.detectAndCompute(gray, None)
return des
def calcFeatVec(features, centers):
featVec = np.zeros((1, num_words)) #构建30个词语的词典
for i in range(len(features)):
fi = features[i]
diffMat = np.tile(fi, (num_words, 1)) - centers
sqSum = (diffMat**2).sum(axis=1)
dist = sqSum**0.5
sortedIndices = dist.argsort()
idx = sortedIndices[0] # index of the nearest center
featVec[0][idx] += 1
return featVec
#初始sift集并且找到聚类中心
def initFeatureSet(train_path):
labels = []
featureSet = np.float32([]).reshape(0,128)
print ("Extract features from TrainSet------")
count=0
for train_file_name in os.listdir(train_path):
train_file_path=os.path.join(train_path,train_file_name)
for img_name in os.listdir(train_file_path):
img_path=os.path.join(train_file_path,img_name)
img=Image.open(img_path)
gray =img.convert('L')
labels.append(train_file_name)
des = calcSiftFeature(np.array(gray))
count+=1
pd.DataFrame(des).to_csv("temp/"+str(count)+".csv",index=False,header=0,sep=',')
featureSet= np.append(featureSet, des, axis=0)
featCnt = featureSet.shape[0]
print (str(featCnt) + " features in all the images\n")
wordCnt = 30
print ("Learn vocabulary-----")
kmeans = KMeans(n_clusters=wordCnt, random_state=0).fit(featureSet)
centers=kmeans.cluster_centers_
filename = "centers/centers.npy"
np.save(filename, (kmeans.labels_, centers))
print ("Done Learn vocabulary\n")
return featureSet,labels,centers
def learnVocabulary(featureSet):
wordCnt = 50
print ("Learn vocabulary-----")
filename = "Temp/vocabulary/centers.npy"
np.save(filename, (labels, centers))
print ("Done Learn vocabulary\n")
return centers
# import the necessary packages
from pyimagesearch.localbinarypatterns import LocalBinaryPatterns
from imutils import paths
import cv2
import os
import pandas as pd
from PIL import Image
desc = LocalBinaryPatterns(24, 8)
fea_lbp = []
labels = []
train_path='/home/mingsun/DIP2/mini/dataset'
# load the image, convert it to grayscale, and describe it
for train_file_name in os.listdir(train_path):
train_file_path=os.path.join(train_path,train_file_name)
for img_name in os.listdir(train_file_path):
img_path=os.path.join(train_file_path,img_name)
I=Image.open(img_path)
gray = I.convert('L')
#img = cv2.imread(img_path)
#gray =cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
hist = desc.describe(gray)
labels.append(train_file_name)
fea_lbp.append(hist)
results=pd.DataFrame( fea_lbp)
results['label']=labels
results.to_csv('fea_lbp.txt',index=False,sep=',')
3.RGB & HSV(HIST)
import cv2
import numpy as np
from imutils import paths
import os
import pandas as pd
train_path='/home/mingsun/DIP2/mini/dataset'
labels = []
fea_rgb=[]
featVecs=[]
def create_rgb_hist(image):
"""创建rgb 三通道直方图"""
h,w,c=image.shape
rHist=np.zeros([16],np.float32)
gHist=np.zeros([16],np.float32)
bHist=np.zeros([16],np.float32)
allHist=np.zeros([48],np.float32)
bsize=256/16
for row in range(h):
for col in range(w):
b = image[row,col,0]
g = image[row, col, 1]
r = image[row, col, 2]
index_r=np.int(r/bsize)
index_g=np.int(g/bsize)
index_b=np.int(b/bsize)
rHist[index_r]=rHist[index_r]+1
gHist[index_g]=gHist[index_g]+1
bHist[index_b]=bHist[index_b]+1
allHist=np.append(rHist,gHist)
allHist=np.append(allHist,bHist)
return allHist
for train_file_name in os.listdir(train_path):
train_file_path=train_path+'/'+train_file_name
for img_name in os.listdir(train_file_path):
img_path=train_file_path+'/'+img_name
img = cv2.imread(img_path)
fea_rgb=create_rgb_hist(img)
featVec_uni=np.array([x/fea_rgb.sum() for x in fea_rgb])
featVecs.append(featVec_uni)
labels.append(train_file_name)
results=pd.DataFrame(featVecs)
results['label']=labels
results.to_csv('fea_RGB.txt',index=False,sep=',')
import cv2
import numpy as np
from HSV import *
from imutils import paths
import os
import pandas as pd
from PIL import Image
from skimage import io,data,color
train_path='/home/mingsun/DIP2/dataset'
color_moments=[]
labels = []
# load the image, convert it to grayscale, and describe it
for train_file_name in os.listdir(train_path):
train_file_path=train_path+'/'+train_file_name
for img_name in os.listdir(train_file_path):
img_path=train_file_path+'/'+img_name
img = Image.open(img_path)
# Convert BGR to HSV colorspace
hsv = color.rgb2hsv(img)
# Split the channels - h,s,v
h, s, v = cv2.split(hsv)
# Initialize the color feature
color_feature = []
# The first central moment - average
h_mean = np.mean(h) # np.sum(h)/float(N)
s_mean = np.mean(s) # np.sum(s)/float(N)
v_mean = np.mean(v) # np.sum(v)/float(N)
color_feature.extend([h_mean, s_mean, v_mean])
# The second central moment - standard deviation
h_std = np.std(h) # np.sqrt(np.mean(abs(h - h.mean())**2))
s_std = np.std(s) # np.sqrt(np.mean(abs(s - s.mean())**2))
v_std = np.std(v) # np.sqrt(np.mean(abs(v - v.mean())**2))
color_feature.extend([h_std, s_std, v_std])
# The third central moment - the third root of the skewness
h_skewness = np.mean(abs(h - h.mean())**3)
s_skewness = np.mean(abs(s - s.mean())**3)
v_skewness = np.mean(abs(v - v.mean())**3)
h_thirdMoment = h_skewness**(1./3)
s_thirdMoment = s_skewness**(1./3)
v_thirdMoment = v_skewness**(1./3)
color_feature.extend([h_thirdMoment, s_thirdMoment, v_thirdMoment])
labels.append(train_file_name)
color_moments.append(color_feature)
print(train_file_name+"类的图片构建HSV_comment完成------\n")
results=pd.DataFrame( color_moments)
results['label']=labels
results.to_csv('fea_HSV.txt',index=False,sep=',')
先算出每个图片的灰度共生矩阵,再依据此共生矩阵构建四条统计性描述子作为新的特征描述:
1.ASM(能量):
是灰度共生矩阵元素值的平方和,所以也称能量,反映了图像灰度分布均匀程度和纹理粗细度。
2.CON(对比度):
其中 。反映了图像的清晰度和纹理沟纹深浅的程度。纹理沟纹越深,其对比度越大,视觉效果越清晰;反之,对比度小,则沟纹浅,效果模糊。灰度差即对比度大的象素对越多,这个值越大。灰度公生矩阵中远离对角线的元素值越大,CON越大。
3.IDM(相关度)(inverse different moment):
度量空间灰度共生矩阵元素在行或列方向上的相似程度,因此,相关值大小反映了图像中局部灰度相关性。当矩阵元素值均匀相等时,相关值就大;相反,如果矩阵像元值相差很大则相关值小。
4.Dng熵(entropy):
此处熵同样表示图像的信息量,当共生矩阵中所有元素有最大的随机性、空间共生矩阵中所有值几乎相等时,共生矩阵中元素分散分布时,熵较大。它表示了图像中纹理的非均匀程度或复杂程度。
import cv2
import math
import pandas as pd
import os
#定义最大灰度级数
gray_level = 16
def maxGrayLevel(img):
max_gray_level=0
(height,width)=img.shape
print (height,width)
for y in range(height):
for x in range(width):
if img[y][x] > max_gray_level:
max_gray_level = img[y][x]
return max_gray_level+1
def getGlcm(input,d_x,d_y):
srcdata=input.copy()
ret=[[0.0 for i in range(gray_level)] for j in range(gray_level)]
(height,width) = input.shape
max_gray_level=maxGrayLevel(input)
#若灰度级数大于gray_level,则将图像的灰度级缩小至gray_level,减小灰度共生矩阵的大小
if max_gray_level > gray_level:
for j in range(height):
for i in range(width):
srcdata[j][i] = srcdata[j][i]*gray_level / max_gray_level
for j in range(height-d_y):
for i in range(width-d_x):
rows = srcdata[j][i]
cols = srcdata[j + d_y][i+d_x]
ret[rows][cols]+=1.0
for i in range(gray_level):
for j in range(gray_level):
ret[i][j]/=float(height*width)
return ret
def feature_computer(p):
Con=0.0
Eng=0.0
Asm=0.0
Idm=0.0
for i in range(gray_level):
for j in range(gray_level):
Con+=(i-j)*(i-j)*p[i][j]
Asm+=p[i][j]*p[i][j]
Idm+=p[i][j]/(1+(i-j)*(i-j))
if p[i][j]>0.0:
Eng+=p[i][j]*math.log(p[i][j])
return Asm,Con,-Eng,Idm
def test():
#%%
GLCMs=[]
labels = []
train_path='/home/mingsun/DIP2/mini/dataset'
for train_file_name in os.listdir(train_path):
train_file_path=train_path+'/'+train_file_name
for img_name in os.listdir(train_file_path):
GLCM=[]
img_path=train_file_path+'/'+img_name
img = cv2.imread(img_path)
img_gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_shape=img_gray.shape
img=cv2.resize(img,(img_shape[1]//2,img_shape[0]//2),interpolation=cv2.INTER_CUBIC)
img_gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
glcm_0=getGlcm(img_gray, 1,0)
asm,con,eng,idm=feature_computer(glcm_0)
GLCM.extend([asm,con,eng,idm])
labels.append(train_file_name)
GLCMs.append(GLCM)
print (asm,con,eng,idm)
results=pd.DataFrame(GLCMs)
results['label']=labels
results.to_csv('fea_GLCM.txt',index=False,sep=',')
if __name__=='__main__':
test()