├── GLCMTestPattern.pptx ├── README.md ├── glcmAnalysis.py ├── glcmFeature.py ├── glcmFeatureExtend.py └── glcmTutorial.pptx /GLCMTestPattern.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffsouza/python_glcmFeature/f9ea70296bf77eed4b568f5e3c3814d60362463d/GLCMTestPattern.pptx -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # python_glcmFeature 2 | This .py file describe how to use GLCM (Gray level co-occurrence matrix) to analyze texture information of an image 3 | 4 | GLCM represents texture information of an image with six different parameters: 1: 'contrast', 2: 'dissimilarity', 3: ' homogeneity', 4: 'energy', 5: 'correlation', 6: 'ASM' 5 | 6 | 7 | For details follow this tutorial: 8 | http://www.fp.ucalgary.ca/mhallbey/tutorial.htm 9 | 10 | 11 | There is two way to use GLCM for mesuring texture: 12 | 1. to apply GLCM on the whole image. Here GLCM will give a single number for wach parameter which will reperesent the texture. 13 | 2. crete a window, apply glcm on the widow pixels and by this scan the entire image. Here GLCM will give a 2D matrix approximatly close to the size of input image based on how this window has been used. Here more detail changes of texture can be found. 14 | 15 | Both of these ways has been implemented in the .py file. 16 | 17 | glcmFeatureExtend.py -> addes chage of step size into 10 by 10 window with different angles 18 | 19 | 20 | glcmAnalysis.py-> presents codes for analyzing testPattern images. It will eventually help to naroow down how to inturprete the results of GLCM. 21 | A ppt presentation is also presented here to quantify the results of GLCM analysis. (glcmTestPattern) 22 | 23 | 24 | -------------------------------------------------------------------------------- /glcmAnalysis.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Tue Apr 18 16:52:47 2017 4 | 5 | @author: mimtiaz 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | from skimage.feature import greycomatrix, greycoprops 11 | import matplotlib.pyplot as plt 12 | import matplotlib.patches as mpatches 13 | 14 | 15 | with open('fileName.txt') as f: #save directories in 'fileName.txt' of all files 16 | content = f.readlines() 17 | 18 | #c = 0 19 | for i in xrange(10, 11): #len(content) 20 | img = cv2.imread((content[i])[:-1]) 21 | img = img[:,:,0] 22 | 23 | # ret,thresh1 = cv2.threshold(img,127,1,cv2.THRESH_BINARY) 24 | # cv2.imwrite('test1.bmp', thresh1) 25 | # resizedImg = cv2.resize(thresh1, (4,4)) 26 | # cv2.imwrite('test2.bmp', resizedImg) 27 | 28 | step = range(1,256) 29 | step = np.asarray(step) 30 | # step = [2] 31 | angle = [0,np.pi/2] 32 | coOccuranceMat = greycomatrix(img, step, angle, levels = 256, symmetric = True, normed = True ) 33 | # coOccuranceMat = greycomatrix(resizedImg, step, angle, levels = 2, symmetric = True) 34 | 35 | #print coOccuranceMat[:,:,1,0] 36 | ll = coOccuranceMat[:,:,4,0] 37 | contrast = greycoprops(coOccuranceMat, 'contrast') 38 | dissimilarity = greycoprops(coOccuranceMat, 'dissimilarity') 39 | homogeneity = greycoprops(coOccuranceMat, 'homogeneity') 40 | energy = greycoprops(coOccuranceMat, 'energy') 41 | correlation = greycoprops(coOccuranceMat, 'correlation') 42 | ASM = greycoprops(coOccuranceMat, 'ASM') 43 | 44 | texturelist = {0: 'contrast', 1: 'dissimilarity', 2: ' homogeneity', 3: 'energy', 4: 'correlation', 5: 'ASM'} 45 | marker = {0: 'b-o', 1: 'r-^'} 46 | 47 | for j in range(0,6): 48 | c = 1 49 | for k in range(0, len(angle)): #len(angle) 50 | plt.figure(j) 51 | plt.plot(step, eval(texturelist[j])[:,k], marker[k], alpha = 0.8) 52 | # plt.plot(step, eval(texturelist[j])[:,0], 'b-*') 53 | plt.xlabel('distance from 1 ro 255') 54 | plt.ylabel(texturelist[j]) 55 | plt.title(texturelist[j] + ' vs. distance') 56 | redPatch = mpatches.Patch(color = 'red', label = 'Angle at 90') 57 | bluePatch = mpatches.Patch(color = 'blue', label = 'Angle at 0') 58 | plt.legend(handles = [bluePatch, redPatch]) 59 | # plt.xlim(0,256) 60 | # plt.ylim(-1.5,1.5) 61 | plt.show(j) 62 | 63 | 64 | c = c +1 -------------------------------------------------------------------------------- /glcmFeature.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Tue Mar 28 16:26:18 2017 4 | 5 | @author: Mohammad Imtiaz 6 | """ 7 | 8 | import cv2 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | from skimage.feature import greycomatrix, greycoprops 12 | #from skimage import data 13 | 14 | 15 | 16 | def glcmXbyXWinScan(sarraster, windowSize): 17 | # sarfile = cv2.imread('8and1eyeDetect.jpg') 18 | # sarraster = sarfile[:,:,0] 19 | 20 | 21 | #Create rasters to receive texture and define filenames 22 | contrastraster = np.zeros((sarraster.shape[0], sarraster.shape[1]), dtype = float) 23 | contrastraster[:] = 0.0 24 | 25 | dissimilarityraster = np.zeros((sarraster.shape[0], sarraster.shape[1]), dtype = float) 26 | dissimilarityraster[:] = 0.0 27 | 28 | #homogeneityraster = np.copy(sarraster) 29 | homogeneityraster = np.zeros((sarraster.shape[0], sarraster.shape[1]), dtype = float) 30 | homogeneityraster[:] = 0.0 31 | 32 | #energyraster = np.copy(sarraster) 33 | energyraster = np.zeros((sarraster.shape[0], sarraster.shape[1]), dtype = float) 34 | energyraster[:] = 0.0 35 | 36 | #correlationraster = np.copy(sarraster) 37 | correlationraster = np.zeros((sarraster.shape[0], sarraster.shape[1]), dtype = float) 38 | correlationraster[:] = 0.0 39 | 40 | #ASMraster = np.copy(sarraster) 41 | ASMraster = np.zeros((sarraster.shape[0], sarraster.shape[1]), dtype = float) 42 | ASMraster[:] = 0.0 43 | 44 | 45 | for i in xrange(sarraster.shape[0]): 46 | print i, 47 | for j in xrange(sarraster.shape[1]): 48 | 49 | if i < windowSize or j (contrastraster.shape[0] - windowSize) or j > (contrastraster.shape[1] - windowSize): 53 | continue 54 | 55 | # Define size of moving window 56 | glcm_window = sarraster[i-windowSize: i+windowSize, j-windowSize : j+windowSize] 57 | # Calculate GLCM and textures 58 | glcm = greycomatrix(glcm_window, [1], [0], symmetric = True, normed = True ) 59 | 60 | # Calculate texture and write into raster where moving window is centered 61 | contrastraster[i,j] = greycoprops(glcm, 'contrast') 62 | dissimilarityraster[i,j] = greycoprops(glcm, 'dissimilarity') 63 | homogeneityraster[i,j] = greycoprops(glcm, 'homogeneity') 64 | energyraster[i,j] = greycoprops(glcm, 'energy') 65 | correlationraster[i,j] = greycoprops(glcm, 'correlation') 66 | ASMraster[i,j] = greycoprops(glcm, 'ASM') 67 | glcm = None 68 | glcm_window = None 69 | 70 | #Normalization use when only needed 71 | contrastraster = 255.0 * normalize(contrastraster) 72 | contrastraster = contrastraster.astype(int) 73 | 74 | dissimilarityraster = 255.0 * normalize(dissimilarityraster) 75 | dissimilarityraster = dissimilarityraster.astype(int) 76 | 77 | homogeneityraster = 255.0 * normalize(homogeneityraster) 78 | homogeneityraster = homogeneityraster.astype(int) 79 | 80 | energyraster = 255.0 * normalize(energyraster) 81 | energyraster = energyraster.astype(int) 82 | 83 | correlationraster = 255.0 * normalize(correlationraster) 84 | correlationraster = correlationraster.astype(int) 85 | 86 | ASMraster = 255.0 * normalize(ASMraster) 87 | ASMraster = ASMraster.astype(int) 88 | 89 | return contrastraster, dissimilarityraster, homogeneityraster, energyraster, correlationraster, ASMraster 90 | 91 | 92 | def normalize(arrayX): 93 | for i in xrange(arrayX.shape[0]): 94 | for j in xrange(arrayX.shape[1]): 95 | arrayX[i,j] = ((arrayX[i,j] - arrayX.min()) / (arrayX.max() - arrayX.min())) 96 | 97 | return arrayX 98 | 99 | 100 | img = cv2.imread('Strauss_GL (83)_FlatIris.pgm') 101 | imgM = cv2.imread('Strauss_GL (83)_FlatMask.pgm') 102 | 103 | img = img[:,:,0] 104 | imgM = imgM[:,:,0] 105 | 106 | glcm = greycomatrix(img, [1], [0], symmetric = True, normed = True ) 107 | contrast = greycoprops(glcm, 'contrast') 108 | dissimilarityraster = greycoprops(glcm, 'dissimilarity') 109 | homogeneityraster = greycoprops(glcm, 'homogeneity') 110 | energyraster = greycoprops(glcm, 'energy') 111 | correlationraster = greycoprops(glcm, 'correlation') 112 | ASMraster = greycoprops(glcm, 'ASM') 113 | 114 | windowSz = 15 # change the window size based on need 115 | contrastScan, dissimilarityScan, homogeneityScan, energyScan, correlationScan, ASMScan = glcmXbyXWinScan(img, windowSz) 116 | 117 | 118 | 119 | texturelist = {1: 'contrast', 2: 'dissimilarity', 3: ' homogeneity', 4: 'energy', 5: 'correlation', 6: 'ASM'} 120 | for key in texturelist: 121 | ax = plt.subplot(2,3,key) 122 | plt.axis('off') 123 | ax.set_title(texturelist[key]) 124 | plt.imshow(eval(texturelist[key] + "Scan"), cmap = 'gray') 125 | 126 | plt.show() 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /glcmFeatureExtend.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Apr 12 11:31:30 2017 4 | 5 | @author: mimtiaz 6 | """ 7 | import numpy as np 8 | import cv2 9 | from skimage.feature import greycomatrix, greycoprops 10 | import matplotlib.pyplot as plt 11 | 12 | 13 | 14 | def glcmXbyXWinScan(sarraster, windowSize, step, angle): 15 | # sarfile = cv2.imread('8and1eyeDetect.jpg') 16 | # sarraster = sarfile[:,:,0] 17 | 18 | 19 | #Create rasters to receive texture and define filenames 20 | contrastraster = np.zeros((sarraster.shape[0], sarraster.shape[1]), dtype = float) 21 | contrastraster[:] = 0.0 22 | 23 | dissimilarityraster = np.zeros((sarraster.shape[0], sarraster.shape[1]), dtype = float) 24 | dissimilarityraster[:] = 0.0 25 | 26 | #homogeneityraster = np.copy(sarraster) 27 | homogeneityraster = np.zeros((sarraster.shape[0], sarraster.shape[1]), dtype = float) 28 | homogeneityraster[:] = 0.0 29 | 30 | #energyraster = np.copy(sarraster) 31 | energyraster = np.zeros((sarraster.shape[0], sarraster.shape[1]), dtype = float) 32 | energyraster[:] = 0.0 33 | 34 | #correlationraster = np.copy(sarraster) 35 | correlationraster = np.zeros((sarraster.shape[0], sarraster.shape[1]), dtype = float) 36 | correlationraster[:] = 0.0 37 | 38 | #ASMraster = np.copy(sarraster) 39 | ASMraster = np.zeros((sarraster.shape[0], sarraster.shape[1]), dtype = float) 40 | ASMraster[:] = 0.0 41 | 42 | 43 | for i in xrange(sarraster.shape[0]): 44 | # print i, 45 | for j in xrange(sarraster.shape[1]): 46 | 47 | if i < windowSize or j (contrastraster.shape[0] - windowSize) or j > (contrastraster.shape[1] - windowSize): 51 | continue 52 | 53 | # Define size of moving window 54 | glcm_window = sarraster[i-windowSize: i+windowSize, j-windowSize : j+windowSize] 55 | # Calculate GLCM and textures 56 | glcm = greycomatrix(glcm_window, step, angle, symmetric = True, normed = True ) 57 | 58 | # Calculate texture and write into raster where moving window is centered 59 | contrastraster[i,j] = greycoprops(glcm, 'contrast') 60 | dissimilarityraster[i,j] = greycoprops(glcm, 'dissimilarity') 61 | homogeneityraster[i,j] = greycoprops(glcm, 'homogeneity') 62 | energyraster[i,j] = greycoprops(glcm, 'energy') 63 | correlationraster[i,j] = greycoprops(glcm, 'correlation') 64 | ASMraster[i,j] = greycoprops(glcm, 'ASM') 65 | glcm = None 66 | glcm_window = None 67 | 68 | #Normalization use when only needed 69 | contrastraster = 255.0 * normalize(contrastraster) 70 | contrastraster = contrastraster.astype(int) 71 | 72 | dissimilarityraster = 255.0 * normalize(dissimilarityraster) 73 | dissimilarityraster = dissimilarityraster.astype(int) 74 | 75 | homogeneityraster = 255.0 * normalize(homogeneityraster) 76 | homogeneityraster = homogeneityraster.astype(int) 77 | 78 | energyraster = 255.0 * normalize(energyraster) 79 | energyraster = energyraster.astype(int) 80 | 81 | correlationraster = 255.0 * normalize(correlationraster) 82 | correlationraster = correlationraster.astype(int) 83 | 84 | ASMraster = 255.0 * normalize(ASMraster) 85 | ASMraster = ASMraster.astype(int) 86 | 87 | return contrastraster, dissimilarityraster, homogeneityraster, energyraster, correlationraster, ASMraster 88 | 89 | 90 | 91 | 92 | def normalize(arrayX): 93 | for i in xrange(arrayX.shape[0]): 94 | for j in xrange(arrayX.shape[1]): 95 | arrayX[i,j] = ((arrayX[i,j] - arrayX.min()) / (arrayX.max() - arrayX.min())) 96 | 97 | return arrayX 98 | 99 | 100 | 101 | 102 | 103 | #fake 104 | image = cv2.imread('lena.png') 105 | image = image[:,:,0] 106 | #step = range(1,256) 107 | #step = np.asarray(step) 108 | 109 | 110 | 111 | #result = greycomatrix(image, step, [0,45,90,135], levels = 256, symmetric=True, normed=True) #, np.pi/4, np.pi/2, 3*np.pi/4 112 | #, symmetric=True, normed=True 113 | windowSz = 5 114 | step = [1] #step = range(1,10,2) 115 | 116 | for i in range(0,180,45): 117 | print i 118 | angle = [i] 119 | contrastScan, dissimilarityScan, homogeneityScan, energyScan, correlationScan, ASMScan = glcmXbyXWinScan(image, windowSz, step, angle) 120 | 121 | contrastScan = contrastScan[windowSz : contrastScan.shape[0] - windowSz + 1, windowSz : contrastScan.shape[1] - windowSz + 1] 122 | dissimilarityScan = dissimilarityScan[windowSz : dissimilarityScan.shape[0] - windowSz + 1, windowSz : dissimilarityScan.shape[1] - windowSz + 1] 123 | homogeneityScan = homogeneityScan[windowSz : homogeneityScan.shape[0] - windowSz + 1, windowSz : homogeneityScan.shape[1] - windowSz + 1] 124 | energyScan = energyScan[windowSz : energyScan.shape[0] - windowSz + 1, windowSz : energyScan.shape[1] - windowSz + 1] 125 | correlationScan = correlationScan[windowSz : correlationScan.shape[0] - windowSz + 1, windowSz : correlationScan.shape[1] - windowSz + 1] 126 | ASMScan = ASMScan[windowSz : ASMScan.shape[0] - windowSz + 1, windowSz : ASMScan.shape[1] - windowSz + 1] 127 | 128 | #%% 129 | 130 | texturelist = {1: 'contrast', 2: 'dissimilarity', 3: ' homogeneity', 4: 'energy', 5: 'correlation', 6: 'ASM'} 131 | plt.figure(0+i) 132 | for key in texturelist: 133 | ax = plt.subplot(2,3,key) 134 | plt.axis('off') 135 | ax.set_title(texturelist[key]) 136 | plt.imshow(eval(texturelist[key] + "Scan"), cmap = 'gray') 137 | 138 | plt.show(0+i) 139 | 140 | -------------------------------------------------------------------------------- /glcmTutorial.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ffsouza/python_glcmFeature/f9ea70296bf77eed4b568f5e3c3814d60362463d/glcmTutorial.pptx --------------------------------------------------------------------------------