图像特征提取

1.SIFT+BOW

提取每个图片的前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  

2.LBP

# 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=',') 

4.RGB & HSV(comment)

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

5.Descriptors based on Grey-level co-occurrence matrix

先算出每个图片的灰度共生矩阵,再依据此共生矩阵构建四条统计性描述子作为新的特征描述:
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()

你可能感兴趣的:(CV)