美文网首页
图像颜色、灰度共生矩阵、lbp和Hu特征提取

图像颜色、灰度共生矩阵、lbp和Hu特征提取

作者: 小小杨树 | 来源:发表于2021-09-29 09:06 被阅读0次
    插播广告

    图像颜色特征

    调用def color_moments函数提取图像颜色特征(hsv)

    程序流程:

    1.读取图像
    2.RGB空间转换为HSV空间
    3.初始化颜色特征
    4.获取一阶矩(均值 mean)并放置在特征数组
    5.获取二阶矩 (标准差 std)并放置在特征数组
    6.三阶矩 (斜度 skewness)并放置在特征数组

    import cv2
    import numpy as np
    
    
    def color_moments(img):   
        # img = cv2.imread(filename)   
        if img is None:
            return
        hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)   
        h, s, v = cv2.split(hsv)
        color_feature = []   
     
        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])   
     
        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])   
     
        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])   
        return color_feature
    
    
    if __name__ == '__main__':
        img = cv2.imread("2.jpg")
        color_data = color_moments(img)
        print(color_data)
    

    —————————————————————————————————————————————————————————————————

    —————————————————————————————————————————————————————————————————

    灰度共生矩阵

    1.定义灰度共生矩阵
    2.定义八小类灰度共生矩阵
    fast_glcm_mean(img)
    fast_glcm_std(img)
    fast_glcm_contrast(img)
    fast_glcm_dissimilarity(img)
    fast_glcm_homogeneity(img)
    fast_glcm_ASM(img)
    fast_glcm_max(img)
    fast_glcm_entropy(img)
    3.读取图像并获取H和W值
    4.计算八小类灰度共生矩阵
    import numpy as np
    import cv2
    from skimage import data
    
    
    
    def fast_glcm(img):
        vmin = 0
        vmax = 255
        nbit = 8
        kernel_size = 5
        mi, ma = vmin, vmax
        ks = kernel_size
        h,w = img.shape
    
        # digitize
        bins = np.linspace(mi, ma+1, nbit+1)
        gl1 = np.digitize(img, bins) - 1
        gl2 = np.append(gl1[:,1:], gl1[:,-1:], axis=1)
    
        # make glcm
        glcm = np.zeros((nbit, nbit, h, w), dtype=np.uint8)
        for i in range(nbit):
            for j in range(nbit):
                mask = ((gl1==i) & (gl2==j))
                glcm[i,j, mask] = 1
    
        kernel = np.ones((ks, ks), dtype=np.uint8)
        for i in range(nbit):
            for j in range(nbit):
                glcm[i,j] = cv2.filter2D(glcm[i,j], -1, kernel)
    
        glcm = glcm.astype(np.float32)
        return glcm
    
    
    def fast_glcm_mean(img):
        '''
        calc glcm mean
        '''
        nbit = 8
        h,w = img.shape
        glcm = fast_glcm(img)
        mean = np.zeros((h,w), dtype=np.float32)
        for i in range(nbit):
            for j in range(nbit):
                mean += glcm[i,j] * i / (nbit)**2
    
        return mean
    
    
    def fast_glcm_std(img):
        '''
        calc glcm std
        '''
        nbit = 8
        h,w = img.shape
        glcm = fast_glcm(img)
        mean = np.zeros((h,w), dtype=np.float32)
        for i in range(nbit):
            for j in range(nbit):
                mean += glcm[i,j] * i / (nbit)**2
    
        std2 = np.zeros((h,w), dtype=np.float32)
        for i in range(nbit):
            for j in range(nbit):
                std2 += (glcm[i,j] * i - mean)**2
    
        std = np.sqrt(std2)
        return std
    
    
    def fast_glcm_contrast(img):
        '''
        calc glcm contrast
        '''
        nbit = 8
        h,w = img.shape
        glcm = fast_glcm(img)
        cont = np.zeros((h,w), dtype=np.float32)
        for i in range(nbit):
            for j in range(nbit):
                cont += glcm[i,j] * (i-j)**2
    
        return cont
    
    
    def fast_glcm_dissimilarity(img):
        '''
        calc glcm dissimilarity
        '''
        nbit = 8
        h,w = img.shape
        glcm = fast_glcm(img)
        diss = np.zeros((h,w), dtype=np.float32)
        for i in range(nbit):
            for j in range(nbit):
                diss += glcm[i,j] * np.abs(i-j)
    
        return diss
    
    
    def fast_glcm_homogeneity(img):
        '''
        calc glcm homogeneity
        '''
        nbit = 8
        h,w = img.shape
        glcm = fast_glcm(img )
        homo = np.zeros((h,w), dtype=np.float32)
        for i in range(nbit):
            for j in range(nbit):
                homo += glcm[i,j] / (1.+(i-j)**2)
    
        return homo
    
    
    def fast_glcm_ASM(img):
        '''
        calc glcm asm, energy
        '''
    
        nbit = 8
    
        h,w = img.shape
        glcm = fast_glcm(img )
        asm = np.zeros((h,w), dtype=np.float32)
        for i in range(nbit):
            for j in range(nbit):
                asm  += glcm[i,j]**2
    
        ene = np.sqrt(asm)
        return asm, ene
    
    
    def fast_glcm_max(img):
        '''
        calc glcm max
        '''
        glcm = fast_glcm(img )
        max_  = np.max(glcm, axis=(0,1))
        return max_
    
    
    def fast_glcm_entropy(img):
        '''
        calc glcm entropy
        '''
        ks = 5
        glcm = fast_glcm(img )
        pnorm = glcm / np.sum(glcm, axis=(0,1)) + 1./ks**2
        ent  = np.sum(-pnorm * np.log(pnorm), axis=(0,1))
        return ent
    
    
    if __name__ == '__main__':
        img = data.camera() #
        h,w = img.shape
    
        glcm_mean = fast_glcm_mean(img)
        print(glcm_mean)
    
        glcm_std = fast_glcm_std(img)
        print(glcm_std)
    
        glcm_contrast = fast_glcm_contrast(img)
        print(glcm_contrast)
    
        glcm_dissimilarity = fast_glcm_dissimilarity(img)
        print(glcm_dissimilarity)
    
        glcm_homogeneity = fast_glcm_homogeneity(img)
        print(glcm_homogeneity)
    
        glcm_ASM = fast_glcm_ASM(img)
        print(glcm_ASM)
    
        glcm_max = fast_glcm_max(img)
        print(glcm_max)
    
        glcm_entropy = fast_glcm_entropy(img)
        print(glcm_entropy)
    

    —————————————————————————————————————————————————————————————————

    —————————————————————————————————————————————————————————————————

    LBP特征:

    1.revolve_map为旋转不变模式的36种特征值从小到大进行序列化编号得到的字典
    2.uniform_map为等价模式的58种特征值从小到大进行序列化编号得到的字典
    3.将图像载入,并转化为灰度图,获取图像灰度图的像素信息
    4.图像的LBP原始特征计算算法:将图像指定位置的像素与周围8个像素比较
    5.比中心像素大的点赋值为1,比中心像素小的赋值为0,返回得到的二进制序列
    6.获取值r的二进制中1的位数
    import cv2
    from PIL import Image
    from pylab import *
    
    
    class LBP:
        def __init__(self):
            
            self.revolve_map = {0: 0, 1: 1, 3: 2, 5: 3, 7: 4, 9: 5, 11: 6, 13: 7, 15: 8, 17: 9, 19: 10, 21: 11, 23: 12,
                                25: 13, 27: 14, 29: 15, 31: 16, 37: 17, 39: 18, 43: 19, 45: 20, 47: 21, 51: 22, 53: 23,
                                55: 24,
                                59: 25, 61: 26, 63: 27, 85: 28, 87: 29, 91: 30, 95: 31, 111: 32, 119: 33, 127: 34, 255: 35}
            
            self.uniform_map = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 6: 5, 7: 6, 8: 7, 12: 8,
                                14: 9, 15: 10, 16: 11, 24: 12, 28: 13, 30: 14, 31: 15, 32: 16,
                                48: 17, 56: 18, 60: 19, 62: 20, 63: 21, 64: 22, 96: 23, 112: 24,
                                120: 25, 124: 26, 126: 27, 127: 28, 128: 29, 129: 30, 131: 31, 135: 32,
                                143: 33, 159: 34, 191: 35, 192: 36, 193: 37, 195: 38, 199: 39, 207: 40,
                                223: 41, 224: 42, 225: 43, 227: 44, 231: 45, 239: 46, 240: 47, 241: 48,
                                243: 49, 247: 50, 248: 51, 249: 52, 251: 53, 252: 54, 253: 55, 254: 56,
                                255: 57}
    
       
        def describe(self, image):
            image_array = np.array(Image.open(image).convert('L'))
            return image_array
    
        def calute_basic_lbp(self, image_array, i, j):
            sum = []
            if image_array[i - 1, j - 1] > image_array[i, j]:
                sum.append(1)
            else:
                sum.append(0)
            if image_array[i - 1, j] > image_array[i, j]:
                sum.append(1)
            else:
                sum.append(0)
            if image_array[i - 1, j + 1] > image_array[i, j]:
                sum.append(1)
            else:
                sum.append(0)
            if image_array[i, j - 1] > image_array[i, j]:
                sum.append(1)
            else:
                sum.append(0)
            if image_array[i, j + 1] > image_array[i, j]:
                sum.append(1)
            else:
                sum.append(0)
            if image_array[i + 1, j - 1] > image_array[i, j]:
                sum.append(1)
            else:
                sum.append(0)
            if image_array[i + 1, j] > image_array[i, j]:
                sum.append(1)
            else:
                sum.append(0)
            if image_array[i + 1, j + 1] > image_array[i, j]:
                sum.append(1)
            else:
                sum.append(0)
            return sum
    
    
        def get_min_for_revolve(self, arr):
            values = []
            circle = arr
            circle.extend(arr)
            for i in range(0, 8):
                j = 0
                sum = 0
                bit_num = 0
                while j < 8:
                    sum += circle[i + j] << bit_num
                    bit_num += 1
                    j += 1
                values.append(sum)
            return min(values)
    
        
        def calc_sum(self, r):
            num = 0
            while (r):
                r &= (r - 1)
                num += 1
            return num
    
        # 获取图像的LBP原始模式特征
        def lbp_basic(self, image_array):
            basic_array = np.zeros(image_array.shape, np.uint8)
            width = image_array.shape[0]
            height = image_array.shape[1]
            for i in range(1, width - 1):
                for j in range(1, height - 1):
                    sum = self.calute_basic_lbp(image_array, i, j)
                    bit_num = 0
                    result = 0
                    for s in sum:
                        result += s << bit_num
                        bit_num += 1
                    basic_array[i, j] = result
            return basic_array
    
        # 获取图像的LBP旋转不变模式特征
        def lbp_revolve(self, image_array):
            revolve_array = np.zeros(image_array.shape, np.uint8)
            width = image_array.shape[0]
            height = image_array.shape[1]
            for i in range(1, width - 1):
                for j in range(1, height - 1):
                    sum = self.calute_basic_lbp(image_array, i, j)
                    revolve_key = self.get_min_for_revolve(sum)
                    revolve_array[i, j] = self.revolve_map[revolve_key]
            return revolve_array
    
        # 获取图像的LBP等价模式特征
        def lbp_uniform(self, image_array):
            uniform_array = np.zeros(image_array.shape, np.uint8)
            basic_array = self.lbp_basic(image_array)
            width = image_array.shape[0]
            height = image_array.shape[1]
    
            for i in range(1, width - 1):
                for j in range(1, height - 1):
                    k = basic_array[i, j] << 1
                    if k > 255:
                        k = k - 255
                    xor = basic_array[i, j] ^ k
                    num = self.calc_sum(xor)
                    if num <= 2:
                        uniform_array[i, j] = self.uniform_map[basic_array[i, j]]
                    else:
                        uniform_array[i, j] = 58
            return uniform_array
    
        # 获取图像的LBP旋转不变等价模式特征
        def lbp_revolve_uniform(self, image_array):
            uniform_revolve_array = np.zeros(image_array.shape, np.uint8)
            basic_array = self.lbp_basic(image_array)
            width = image_array.shape[0]
            height = image_array.shape[1]
            for i in range(1, width - 1):
                for j in range(1, height - 1):
                    k = basic_array[i, j] << 1
                    if k > 255:
                        k = k - 255
                    xor = basic_array[i, j] ^ k
                    num = self.calc_sum(xor)
                    if num <= 2:
                        uniform_revolve_array[i, j] = self.calc_sum(basic_array[i, j])
                    else:
                        uniform_revolve_array[i, j] = 9
            return uniform_revolve_array
    
        # 绘制指定维数和范围的图像灰度归一化统计直方图
        def show_hist(self, img_array, im_bins, im_range):
            hist = cv2.calcHist([img_array], [0], None, im_bins, im_range)
            hist = cv2.normalize(hist, None).flatten()
            plt.plot(hist, color='r')
            plt.xlim(im_range)
            plt.show()
    
        # 绘制图像原始LBP特征的归一化统计直方图
        def show_basic_hist(self, img_array):
            self.show_hist(img_array, [256], [0, 256])
    
        # 绘制图像旋转不变LBP特征的归一化统计直方图
        def show_revolve_hist(self, img_array):
            self.show_hist(img_array, [36], [0, 36])
    
        # 绘制图像等价模式LBP特征的归一化统计直方图
        def show_uniform_hist(self, img_array):
            self.show_hist(img_array, [60], [0, 60])
    
        # 绘制图像旋转不变等价模式LBP特征的归一化统计直方图
        def show_revolve_uniform_hist(self, img_array):
            self.show_hist(img_array, [10], [0, 10])
    
        # 显示图像
        def show_image(self, image_array):
            cv2.imshow('Image', image_array)
            cv2.waitKey(0)
    
    
    if __name__ == '__main__':
        image = "2.jpg"
        lbp = LBP()
        image_array = lbp.describe(image)
    
        # 获取图像原始LBP特征,并显示其统计直方图与特征图像
        basic_array = lbp.lbp_basic(image_array)
        basic_data = basic_array
        print(basic_data)
    

    —————————————————————————————————————————————————————————————————

    —————————————————————————————————————————————————————————————————

    Hu特征提取

    自定义求矩函数,主要是根据公式将一个个参数求出

    param img_gray: 灰度图像,对于二值图像来说就只有两个灰度0和255
    return: 返回以10为底对数化后的hu不变矩

    由于7个不变矩的变化范围很大,为了便于比较,可利用取对数的方法进行数据压缩;
    同时考虑到不变矩有可能出现负值的情况,因此,在取对数之前先取绝对值
    经修正后的不变矩特征具有平移 、旋转和比例不变性

    import cv2
    import numpy as np
    
    
    def def_moments(img_gray):
    
        # 标准矩定义为m_pq = sumsum(x^p * y^q * f(x, y))其中f(x,y)为像素点处的灰度值
        row, col = img_gray.shape
        # 计算图像的0阶几何矩
        m00 = 0.0
        ##初始化一到三阶几何矩
        # 计算一阶矩阵
        m10 = m01 = 0.0
        # 计算图像的二阶、三阶几何矩
        m11 = m20 = m02 = m12 = m21 = m30 = m03 = 0.0
        for i in range(row):
            for j in range(col):
                m00 += img_gray[i][j]
                m10 += i * img_gray[i][j]
                m20 += i ** 2 * img_gray[i][j]
                m30 += i ** 3 * img_gray[i][j]
                m11 += i * j * img_gray[i][j]
                m12 += i * j ** 2 * img_gray[i][j]
                m21 += i ** 2 * j * img_gray[i][j]
        for j in range(col):
            for i in range(row):
                m01 += (j * img_gray[i, j])
                m02 += (j ** 2 * img_gray[i, j])
                m03 += (j ** 3 * img_gray[i, j])
        # 由标准矩我们可以得到图像的"重心"
        u10 = m10 / m00
        u01 = m01 / m00
        # 计算图像的二阶中心矩、三阶中心矩
        y00 = y10 = y01 = y11 = y20 = y02 = y30 = y12 = y21 = y03 = 0.0
        for x in range(row):
            for y in range(col):
                x_ = x - u10
                y_ = y - u01
                y00 += img_gray[x][y]
                y10 += x_ * img_gray[x][y]
                y01 += y_ * img_gray[x][y]
                y11 += x_ * y_ * img_gray[x][y]
                y02 += y_ ** 2 * img_gray[x][y]
                y20 += x_ ** 2 * img_gray[x][y]
                y03 += y_ ** 3 * img_gray[x][y]
                y30 += x_ ** 3 * img_gray[x][y]
                y12 += x_ * y_ ** 2 * img_gray[x][y]
                y21 += x_ ** 2 * y_ * img_gray[x][y]
        # 计算图像的归一化中心矩
        n20 = y20 / (y00 ** 2)
        n02 = y02 / (y00 ** 2)
        n11 = y11 / (y00 ** 2)
        n30 = y30 / (y00 ** 2.5)
        n03 = y03 / (y00 ** 2.5)
        n12 = y12 / (y00 ** 2.5)
        n21 = y21 / (y00 ** 2.5)
        # 计算图像的七个不变矩
        h1 = n20 + n02
        h2 = (n20 - n02) ** 2 + 4 * (n11 ** 2)
        h3 = (n30 - 3 * n12) ** 2 + (3 * n21 - n03) ** 2
        h4 = (n30 + n12) ** 2 + (n21 + n03) ** 2
        h5 = (n30 - 3 * n12) * (n30 + n12) * ((n30 + n12) ** 2 - 3 * (n21 + n03) ** 2) + (3 * n21 - n03) * (n21 + n03) \
             * (3 * (n30 + n12) ** 2 - (
                n21 + n03) ** 2)
        h6 = (n20 - n02) * ((n30 + n12) ** 2 - (n21 + n03) ** 2) + 4 * n11 * (n30 + n12) * (n21 + n03)
        h7 = (3 * n21 - n03) * (n30 + n12) * ((n30 + n12) ** 2 - 3 * (n21 + n03) ** 2) + (3 * n12 - n30) * (n21 + n03) \
             * (3 * (n30 + n12) ** 2 - (
                n21 + n03) ** 2)
        inv_m7 = [h1, h2, h3, h4, h5, h6, h7]
        humoments = np.log(np.abs(inv_m7))
        return humoments
    
    if __name__ == '__main__':
        img = cv2.imread("2.jpg")
        img_gary = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        color_data = def_moments(img_gary)
        print(color_data)
    

    转自:https://blog.csdn.net/qq_45769063/article/details/107405546

    相关文章

      网友评论

          本文标题:图像颜色、灰度共生矩阵、lbp和Hu特征提取

          本文链接:https://www.haomeiwen.com/subject/olodnltx.html