├── Image ├── GLCM.png ├── LBP.png ├── origin.png ├── histogram.png ├── RGB-histogram.png └── gray-histogram.png ├── 纹理特征 ├── GLCM │ ├── sample.py │ ├── plot.py │ └── fast_glcm.py └── LBP │ ├── get_uniform_map.py │ ├── get_resolve_map.py │ └── get_LBP_from_Image.py ├── 颜色特征 ├── Color Moment.py └── Color-Histograms.py ├── .gitignore ├── README.md └── LICENSE /Image/GLCM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1044197988/Python-Image-feature-extraction/HEAD/Image/GLCM.png -------------------------------------------------------------------------------- /Image/LBP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1044197988/Python-Image-feature-extraction/HEAD/Image/LBP.png -------------------------------------------------------------------------------- /Image/origin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1044197988/Python-Image-feature-extraction/HEAD/Image/origin.png -------------------------------------------------------------------------------- /Image/histogram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1044197988/Python-Image-feature-extraction/HEAD/Image/histogram.png -------------------------------------------------------------------------------- /Image/RGB-histogram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1044197988/Python-Image-feature-extraction/HEAD/Image/RGB-histogram.png -------------------------------------------------------------------------------- /Image/gray-histogram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1044197988/Python-Image-feature-extraction/HEAD/Image/gray-histogram.png -------------------------------------------------------------------------------- /纹理特征/GLCM/sample.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | import numpy as np 4 | from skimage import data 5 | from matplotlib import pyplot as plt 6 | import fast_glcm 7 | 8 | def main(): 9 | pass 10 | 11 | 12 | if __name__ == '__main__': 13 | main() 14 | 15 | img = data.camera() 16 | h,w = img.shape 17 | glcm_mean = fast_glcm.fast_glcm_mean(img) 18 | 19 | plt.imshow(glcm_mean) 20 | plt.tight_layout() 21 | plt.show() 22 | -------------------------------------------------------------------------------- /颜色特征/Color Moment.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | import numpy as np 3 | import os 4 | 5 | """ 6 | #r通道的一阶颜色矩 7 | rd_1 = rd.mean() 8 | 9 | #r通道的二阶颜色矩 10 | rd_2 = rd.std() 11 | """ 12 | 13 | #定义一个求三阶颜色矩的函数 14 | def var(x=None): 15 | mid = np.mean(((x - x.mean()) ** 3)) 16 | return np.sign(mid) * abs(mid) ** (1/3) 17 | 18 | #批量求一个文件夹下所有图片的各阶颜色矩: 19 | def getimagedata(path): 20 | filename = os.listdir(path) 21 | n = len(filename) 22 | data = np.zeros([n,9]) 23 | for i in range(n): 24 | img = Image.open(path +'\\'+ filename[i]) 25 | M,N = img.size 26 | r,g,b = img.split() 27 | rd = np.asarray(r) 28 | gd = np.asarray(g) 29 | bd = np.asarray(b) 30 | data[i,0] = rd.mean() 31 | data[i,1] = gd.mean() 32 | data[i,2] = bd.mean() 33 | data[i,3] = rd.std() 34 | data[i,4] = gd.std() 35 | data[i,5] = bd.std() 36 | data[i,6] = var(rd) 37 | data[i,7] = var(gd) 38 | data[i,8] = var(bd) 39 | return data 40 | 41 | if __name__=='__main__': 42 | a = getimagedata("C:\\Users\\Admin\\Desktop\\666\\Project\\segmention\\train") 43 | -------------------------------------------------------------------------------- /纹理特征/LBP/get_uniform_map.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # get_uniform_map.py 3 | # 2015-7-7 4 | # github: https://github.com/michael92ht 5 | #__author__ = 'huangtao' 6 | 7 | #求等价模式的58种特征值从小到大进行序列化编号得到的字典 8 | 9 | #求其二进制表示旋转一周的8个值 10 | def circle(arr,values): 11 | for i in range(0,8): 12 | b=0 13 | sum=0 14 | for j in range(i,8): 15 | sum+=arr[j]<1): #构造二进制表示的列表 36 | arr.append(string.atoi(b[j])) 37 | j-=1 38 | for s in range(0,8-len(arr)): 39 | arr.append(0) 40 | get_min_for_revolve(arr,values) 41 | 42 | values.sort() #构造字典 43 | map={} 44 | num=0 45 | f=open(r"d:/cv/test.txt",'w') 46 | for v in values: 47 | if not map.has_key(v): 48 | map[v]=num 49 | num+=1 50 | f.write(str(v)+':'+str(map[v])+',') 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python-Image-feature-extraction 2 | Python实现提取图像的纹理、颜色特征,包含快速灰度共现矩阵(GLCM)、LBP特征、颜色矩、颜色直方图。 3 | 4 | # 原始图片 5 | ![image](https://github.com/1044197988/Python-Image-feature-extraction/blob/master/Image/origin.png) 6 | 7 | ## 纹理特征 8 | ### GLCM 9 | numpy的快速灰度共现矩阵(GLCM)。该脚本在没有每个像素For循环的情况下计算GLCM,并且在scikit-image上比GLCM更快地工作。 10 | ```python 11 | import fast_glcm 12 | from skimage import data 13 | 14 | if __name__ == '__main__': 15 | img = data.camera() 16 | glcm_mean = fast_glcm.fast_glcm_mean(img) 17 | ``` 18 | ![GLCM](https://github.com/1044197988/Python-Image-feature-extraction/blob/master/Image/GLCM.png) 19 | 20 | ### LBP 21 | 获取图像的LBP特征:对图像的原始LBP模式、等价LBP模式、旋转不变LBP模式,以及等价旋转不变LBP模式的LBP特征进行提取以及显示。
22 | get_LBP_from_Image.py 主要文件 获取图像的LBP特征。
23 | get_resolve_map.py和get_uniform_map.py主要是做降维后新的像素值的映射。已经将求出的结果写入了get_LBP_from_Image.py中,这两个主要是帮助理解算法降维后新的像素值怎么得到的。 24 | ![LBP](https://github.com/1044197988/Python-Image-feature-extraction/blob/master/Image/LBP.png) 25 | ## 颜色特征 26 | ### 颜色矩 27 | 颜色是彩色图像最重要的内容之一,被广泛用于图像检索中。但从图像中提取颜色特征时,很多算法都先要对图像进行量化处理。量化处理容易导致误检,并且产生的图像特征维数较高,不利于检索。AMA Stricker和M Orengo提出了颜色矩的方法,颜色矩是一种简单有效的颜色特征表示方法,有一阶矩(均值,mean)、二阶矩(方差, variance)和三阶矩(斜度,skewness)等,由于颜色信息主要分布于低阶矩中,所以用一阶矩,二阶矩和三阶矩足以表达图像的颜色分布,颜色矩已证明可有效地表示图像中的颜色分布,该方法的优点在于:不需要颜色空间量化,特征向量维数低;但实验发现该方法的检索效率比较低,因而在实际应用中往往用来过滤图像以缩小检索范围。
28 | ### 颜色直方图 29 | ![RGB-histogram](https://github.com/1044197988/Python-Image-feature-extraction/blob/master/Image/RGB-histogram.png) 30 | ![gray-histogram](https://github.com/1044197988/Python-Image-feature-extraction/blob/master/Image/gray-histogram.png) 31 | ![histogram](https://github.com/1044197988/Python-Image-feature-extraction/blob/master/Image/histogram.png) 32 | # 参考 33 | * [michael92ht/LBP](https://github.com/michael92ht/LBP) 34 | * [tzm030329/GLCM](https://github.com/tzm030329/GLCM) 35 | 36 | -------------------------------------------------------------------------------- /纹理特征/GLCM/plot.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | import numpy as np 4 | from skimage import data 5 | from matplotlib import pyplot as plt 6 | import fast_glcm 7 | from PIL import Image 8 | 9 | def main(): 10 | pass 11 | 12 | 13 | if __name__ == '__main__': 14 | #main() 15 | image = r"C:\\Users\\Admin\\Desktop\\666\\Project\\segmention\\train\\4_3_0.tif"; 16 | img=np.array(Image.open(image).convert('L')) 17 | #img = data.camera() 18 | h,w = img.shape 19 | 20 | mean = fast_glcm.fast_glcm_mean(img) 21 | std = fast_glcm.fast_glcm_std(img) 22 | cont = fast_glcm.fast_glcm_contrast(img) 23 | diss = fast_glcm.fast_glcm_dissimilarity(img) 24 | homo = fast_glcm.fast_glcm_homogeneity(img) 25 | asm, ene = fast_glcm.fast_glcm_ASM(img) 26 | ma = fast_glcm.fast_glcm_max(img) 27 | ent = fast_glcm.fast_glcm_entropy(img) 28 | 29 | plt.figure(figsize=(10,4.5)) 30 | fs = 15 31 | plt.subplot(2,5,1) 32 | plt.tick_params(labelbottom=False, labelleft=False) 33 | plt.imshow(img) 34 | plt.title('original', fontsize=fs) 35 | 36 | plt.subplot(2,5,2) 37 | plt.tick_params(labelbottom=False, labelleft=False) 38 | plt.imshow(mean) 39 | plt.title('mean', fontsize=fs) 40 | 41 | plt.subplot(2,5,3) 42 | plt.tick_params(labelbottom=False, labelleft=False) 43 | plt.imshow(std) 44 | plt.title('std', fontsize=fs) 45 | 46 | plt.subplot(2,5,4) 47 | plt.tick_params(labelbottom=False, labelleft=False) 48 | plt.imshow(cont) 49 | plt.title('contrast', fontsize=fs) 50 | 51 | plt.subplot(2,5,5) 52 | plt.tick_params(labelbottom=False, labelleft=False) 53 | plt.imshow(diss) 54 | plt.title('dissimilarity', fontsize=fs) 55 | 56 | plt.subplot(2,5,6) 57 | plt.tick_params(labelbottom=False, labelleft=False) 58 | plt.imshow(homo) 59 | plt.title('homogeneity', fontsize=fs) 60 | 61 | plt.subplot(2,5,7) 62 | plt.tick_params(labelbottom=False, labelleft=False) 63 | plt.imshow(asm) 64 | plt.title('ASM', fontsize=fs) 65 | 66 | plt.subplot(2,5,8) 67 | plt.tick_params(labelbottom=False, labelleft=False) 68 | plt.imshow(ene) 69 | plt.title('energy', fontsize=fs) 70 | 71 | plt.subplot(2,5,9) 72 | plt.tick_params(labelbottom=False, labelleft=False) 73 | plt.imshow(ma) 74 | plt.title('max', fontsize=fs) 75 | 76 | plt.subplot(2,5,10) 77 | plt.tick_params(labelbottom=False, labelleft=False) 78 | plt.imshow(ent) 79 | plt.title('entropy', fontsize=fs) 80 | 81 | plt.tight_layout(pad=0.5) 82 | plt.savefig('img/output.jpg') 83 | plt.show() 84 | -------------------------------------------------------------------------------- /颜色特征/Color-Histograms.py: -------------------------------------------------------------------------------- 1 | # author: Adrian Rosebrock 2 | # date: 22 January 2014 3 | # website: http://www.pyimagesearch.com 4 | 5 | # USAGE 6 | # python histograms.py --image grant.jpg 7 | 8 | # import the necessary packages 9 | from matplotlib import pyplot as plt 10 | import numpy as np 11 | import argparse 12 | import cv2 13 | """ 14 | # construct the argument parser and parse the arguments 15 | ap = argparse.ArgumentParser() 16 | ap.add_argument("-i", "--image", required = True, help = "Path to the image") 17 | args = vars(ap.parse_args()) 18 | """ 19 | # load the image and show it args["image"] 20 | image = cv2.imread("C:\\Users\\Admin\\Desktop\\666\\Project\\segmention\\3_6_0.tif") 21 | cv2.imshow("image", image) 22 | 23 | # convert the image to grayscale and create a histogram 24 | gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 25 | cv2.imshow("gray", gray) 26 | hist = cv2.calcHist([gray], [0], None, [256], [0, 256]) 27 | plt.figure() 28 | plt.title("Grayscale Histogram") 29 | plt.xlabel("Bins") 30 | plt.ylabel("# of Pixels") 31 | plt.plot(hist) 32 | plt.xlim([0, 256]) 33 | 34 | # grab the image channels, initialize the tuple of colors, 35 | # the figure and the flattened feature vector 36 | chans = cv2.split(image) 37 | colors = ("b", "g", "r") 38 | plt.figure() 39 | plt.title("'Flattened' Color Histogram") 40 | plt.xlabel("Bins") 41 | plt.ylabel("# of Pixels") 42 | features = [] 43 | 44 | # loop over the image channels 45 | for (chan, color) in zip(chans, colors): 46 | # create a histogram for the current channel and 47 | # concatenate the resulting histograms for each 48 | # channel 49 | hist = cv2.calcHist([chan], [0], None, [256], [0, 256]) 50 | features.extend(hist) 51 | 52 | # plot the histogram 53 | plt.plot(hist, color = color) 54 | plt.xlim([0, 256]) 55 | 56 | # here we are simply showing the dimensionality of the 57 | # flattened color histogram 256 bins for each channel 58 | # x 3 channels = 768 total values -- in practice, we would 59 | # normally not use 256 bins for each channel, a choice 60 | # between 32-96 bins are normally used, but this tends 61 | # to be application dependent 62 | print("flattened feature vector size: %d" % (np.array(features).flatten().shape)) 63 | 64 | # let's move on to 2D histograms -- I am reducing the 65 | # number of bins in the histogram from 256 to 32 so we 66 | # can better visualize the results 67 | fig = plt.figure() 68 | 69 | # plot a 2D color histogram for green and blue 70 | ax = fig.add_subplot(131) 71 | hist = cv2.calcHist([chans[1], chans[0]], [0, 1], None, 72 | [32, 32], [0, 256, 0, 256]) 73 | p = ax.imshow(hist, interpolation = "nearest") 74 | ax.set_title("2D Color Histogram for Green and Blue") 75 | plt.colorbar(p) 76 | 77 | # plot a 2D color histogram for green and red 78 | ax = fig.add_subplot(132) 79 | hist = cv2.calcHist([chans[1], chans[2]], [0, 1], None, 80 | [32, 32], [0, 256, 0, 256]) 81 | p = ax.imshow(hist, interpolation = "nearest") 82 | ax.set_title("2D Color Histogram for Green and Red") 83 | plt.colorbar(p) 84 | 85 | # plot a 2D color histogram for blue and red 86 | ax = fig.add_subplot(133) 87 | hist = cv2.calcHist([chans[0], chans[2]], [0, 1], None, 88 | [32, 32], [0, 256, 0, 256]) 89 | p = ax.imshow(hist, interpolation = "nearest") 90 | ax.set_title("2D Color Histogram for Blue and Red") 91 | plt.colorbar(p) 92 | 93 | # finally, let's examine the dimensionality of one of 94 | # the 2D histograms 95 | print ("2D histogram shape: %s, with %d values" % ( 96 | hist.shape, hist.flatten().shape[0])) 97 | 98 | # our 2D histogram could only take into account 2 out 99 | # of the 3 channels in the image so now let's build a 100 | # 3D color histogram (utilizing all channels) with 8 bins 101 | # in each direction -- we can't plot the 3D histogram, but 102 | # the theory is exactly like that of a 2D histogram, so 103 | # we'll just show the shape of the histogram 104 | hist = cv2.calcHist([image], [0, 1, 2], 105 | None, [8, 8, 8], [0, 256, 0, 256, 0, 256]) 106 | print ("3D histogram shape: %s, with %d values" % ( 107 | hist.shape, hist.flatten().shape[0])) 108 | 109 | # show the figures and wait for a keypress 110 | plt.show() 111 | cv2.waitKey(0) 112 | -------------------------------------------------------------------------------- /纹理特征/GLCM/fast_glcm.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | import cv2 6 | from skimage import data 7 | 8 | 9 | def main(): 10 | pass 11 | 12 | 13 | def fast_glcm(img, vmin=0, vmax=255, nbit=8, kernel_size=5): 14 | mi, ma = vmin, vmax 15 | ks = kernel_size 16 | h,w = img.shape 17 | 18 | # digitize 19 | bins = np.linspace(mi, ma+1, nbit+1) 20 | gl1 = np.digitize(img, bins) - 1 21 | gl2 = np.append(gl1[:,1:], gl1[:,-1:], axis=1) 22 | 23 | # make glcm 24 | glcm = np.zeros((nbit, nbit, h, w), dtype=np.uint8) 25 | for i in range(nbit): 26 | for j in range(nbit): 27 | mask = ((gl1==i) & (gl2==j)) 28 | glcm[i,j, mask] = 1 29 | 30 | kernel = np.ones((ks, ks), dtype=np.uint8) 31 | for i in range(nbit): 32 | for j in range(nbit): 33 | glcm[i,j] = cv2.filter2D(glcm[i,j], -1, kernel) 34 | 35 | glcm = glcm.astype(np.float32) 36 | return glcm 37 | 38 | 39 | def fast_glcm_mean(img, vmin=0, vmax=255, nbit=8, ks=5): 40 | ''' 41 | calc glcm mean 42 | ''' 43 | h,w = img.shape 44 | glcm = fast_glcm(img, vmin, vmax, nbit, ks) 45 | mean = np.zeros((h,w), dtype=np.float32) 46 | for i in range(nbit): 47 | for j in range(nbit): 48 | mean += glcm[i,j] * i / (nbit)**2 49 | 50 | return mean 51 | 52 | 53 | def fast_glcm_std(img, vmin=0, vmax=255, nbit=8, ks=5): 54 | ''' 55 | calc glcm std 56 | ''' 57 | h,w = img.shape 58 | glcm = fast_glcm(img, vmin, vmax, nbit, ks) 59 | mean = np.zeros((h,w), dtype=np.float32) 60 | for i in range(nbit): 61 | for j in range(nbit): 62 | mean += glcm[i,j] * i / (nbit)**2 63 | 64 | std2 = np.zeros((h,w), dtype=np.float32) 65 | for i in range(nbit): 66 | for j in range(nbit): 67 | std2 += (glcm[i,j] * i - mean)**2 68 | 69 | std = np.sqrt(std2) 70 | return std 71 | 72 | 73 | def fast_glcm_contrast(img, vmin=0, vmax=255, nbit=8, ks=5): 74 | ''' 75 | calc glcm contrast 76 | ''' 77 | h,w = img.shape 78 | glcm = fast_glcm(img, vmin, vmax, nbit, ks) 79 | cont = np.zeros((h,w), dtype=np.float32) 80 | for i in range(nbit): 81 | for j in range(nbit): 82 | cont += glcm[i,j] * (i-j)**2 83 | 84 | return cont 85 | 86 | 87 | def fast_glcm_dissimilarity(img, vmin=0, vmax=255, nbit=8, ks=5): 88 | ''' 89 | calc glcm dissimilarity 90 | ''' 91 | h,w = img.shape 92 | glcm = fast_glcm(img, vmin, vmax, nbit, ks) 93 | diss = np.zeros((h,w), dtype=np.float32) 94 | for i in range(nbit): 95 | for j in range(nbit): 96 | diss += glcm[i,j] * np.abs(i-j) 97 | 98 | return diss 99 | 100 | 101 | def fast_glcm_homogeneity(img, vmin=0, vmax=255, nbit=8, ks=5): 102 | ''' 103 | calc glcm homogeneity 104 | ''' 105 | h,w = img.shape 106 | glcm = fast_glcm(img, vmin, vmax, nbit, ks) 107 | homo = np.zeros((h,w), dtype=np.float32) 108 | for i in range(nbit): 109 | for j in range(nbit): 110 | homo += glcm[i,j] / (1.+(i-j)**2) 111 | 112 | return homo 113 | 114 | 115 | def fast_glcm_ASM(img, vmin=0, vmax=255, nbit=8, ks=5): 116 | ''' 117 | calc glcm asm, energy 118 | ''' 119 | h,w = img.shape 120 | glcm = fast_glcm(img, vmin, vmax, nbit, ks) 121 | asm = np.zeros((h,w), dtype=np.float32) 122 | for i in range(nbit): 123 | for j in range(nbit): 124 | asm += glcm[i,j]**2 125 | 126 | ene = np.sqrt(asm) 127 | return asm, ene 128 | 129 | 130 | def fast_glcm_max(img, vmin=0, vmax=255, nbit=8, ks=5): 131 | ''' 132 | calc glcm max 133 | ''' 134 | glcm = fast_glcm(img, vmin, vmax, nbit, ks) 135 | max_ = np.max(glcm, axis=(0,1)) 136 | return max_ 137 | 138 | 139 | def fast_glcm_entropy(img, vmin=0, vmax=255, nbit=8, ks=5): 140 | ''' 141 | calc glcm entropy 142 | ''' 143 | glcm = fast_glcm(img, vmin, vmax, nbit, ks) 144 | pnorm = glcm / np.sum(glcm, axis=(0,1)) + 1./ks**2 145 | ent = np.sum(-pnorm * np.log(pnorm), axis=(0,1)) 146 | return ent 147 | 148 | 149 | if __name__ == '__main__': 150 | main() 151 | 152 | nbit = 8 153 | ks = 5 154 | mi, ma = 0, 255 155 | 156 | img = data.camera() 157 | h,w = img.shape 158 | 159 | img[:,:w//2] = img[:,:w//2]//2+127 160 | glcm_mean = fast_glcm_mean(img, mi, ma, nbit, ks) 161 | -------------------------------------------------------------------------------- /纹理特征/LBP/get_LBP_from_Image.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # get_LBP_from_Image.py 3 | # 2015-7-7 4 | # github: https://github.com/michael92ht 5 | #__author__ = 'huangtao' 6 | 7 | # import the necessary packages 8 | import numpy as np 9 | import cv2 10 | from PIL import Image 11 | from pylab import* 12 | 13 | class LBP: 14 | def __init__(self): 15 | #revolve_map为旋转不变模式的36种特征值从小到大进行序列化编号得到的字典 16 | 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, 17 | 25:13,27:14,29:15,31:16,37:17,39:18,43:19,45:20,47:21,51:22,53:23,55:24, 18 | 59:25,61:26,63:27,85:28,87:29,91:30,95:31,111:32,119:33,127:34,255:35} 19 | #uniform_map为等价模式的58种特征值从小到大进行序列化编号得到的字典 20 | self.uniform_map={0:0,1:1,2:2,3:3,4:4,6:5,7:6,8:7,12:8, 21 | 14:9,15:10,16:11,24:12,28:13,30:14,31:15,32:16, 22 | 48:17,56:18,60:19,62:20,63:21,64:22,96:23,112:24, 23 | 120:25,124:26,126:27,127:28,128:29,129:30,131:31,135:32, 24 | 143:33,159:34,191:35,192:36,193:37,195:38,199:39,207:40, 25 | 223:41,224:42,225:43,227:44,231:45,239:46,240:47,241:48, 26 | 243:49,247:50,248:51,249:52,251:53,252:54,253:55,254:56, 27 | 255:57} 28 | 29 | 30 | #将图像载入,并转化为灰度图,获取图像灰度图的像素信息 31 | def describe(self,image): 32 | image_array=np.array(Image.open(image).convert('L')) 33 | return image_array 34 | 35 | #图像的LBP原始特征计算算法:将图像指定位置的像素与周围8个像素比较 36 | #比中心像素大的点赋值为1,比中心像素小的赋值为0,返回得到的二进制序列 37 | def calute_basic_lbp(self,image_array,i,j): 38 | sum=[] 39 | if image_array[i-1,j-1]>image_array[i,j]: 40 | sum.append(1) 41 | else: 42 | sum.append(0) 43 | if image_array[i-1,j]>image_array[i,j]: 44 | sum.append(1) 45 | else: 46 | sum.append(0) 47 | if image_array[i-1,j+1]>image_array[i,j]: 48 | sum.append(1) 49 | else: 50 | sum.append(0) 51 | if image_array[i,j-1]>image_array[i,j]: 52 | sum.append(1) 53 | else: 54 | sum.append(0) 55 | if image_array[i,j+1]>image_array[i,j]: 56 | sum.append(1) 57 | else: 58 | sum.append(0) 59 | if image_array[i+1,j-1]>image_array[i,j]: 60 | sum.append(1) 61 | else: 62 | sum.append(0) 63 | if image_array[i+1,j]>image_array[i,j]: 64 | sum.append(1) 65 | else: 66 | sum.append(0) 67 | if image_array[i+1,j+1]>image_array[i,j]: 68 | sum.append(1) 69 | else: 70 | sum.append(0) 71 | return sum 72 | 73 | #获取二进制序列进行不断环形旋转得到新的二进制序列的最小十进制值 74 | def get_min_for_revolve(self,arr): 75 | values=[] 76 | circle=arr 77 | circle.extend(arr) 78 | for i in range(0,8): 79 | j=0 80 | sum=0 81 | bit_num=0 82 | while j<8: 83 | sum+=circle[i+j]<255: 136 | k=k-255 137 | xor=basic_array[i,j]^k 138 | num=self.calc_sum(xor) 139 | if num<=2: 140 | uniform_array[i,j]=self.uniform_map[basic_array[i,j]] 141 | else: 142 | uniform_array[i,j]=58 143 | return uniform_array 144 | 145 | #获取图像的LBP旋转不变等价模式特征 146 | def lbp_revolve_uniform(self,image_array): 147 | uniform_revolve_array=np.zeros(image_array.shape, np.uint8) 148 | basic_array=self.lbp_basic(image_array) 149 | width=image_array.shape[0] 150 | height=image_array.shape[1] 151 | for i in range(1,width-1): 152 | for j in range(1,height-1): 153 | k= basic_array[i,j]<<1 154 | if k>255: 155 | k=k-255 156 | xor=basic_array[i,j]^k 157 | num=self.calc_sum(xor) 158 | if num<=2: 159 | uniform_revolve_array[i,j]=self.calc_sum(basic_array[i,j]) 160 | else: 161 | uniform_revolve_array[i,j]=9 162 | return uniform_revolve_array 163 | 164 | #绘制指定维数和范围的图像灰度归一化统计直方图 165 | def show_hist(self,img_array,im_bins,im_range): 166 | hist = cv2.calcHist([img_array],[0],None,im_bins,im_range) 167 | hist = cv2.normalize(hist,None).flatten() 168 | plt.plot(hist,color = 'r') 169 | plt.xlim(im_range) 170 | plt.show() 171 | 172 | #绘制图像原始LBP特征的归一化统计直方图 173 | def show_basic_hist(self,img_array): 174 | self.show_hist(img_array,[256],[0,256]) 175 | 176 | #绘制图像旋转不变LBP特征的归一化统计直方图 177 | def show_revolve_hist(self,img_array): 178 | self.show_hist(img_array,[36],[0,36]) 179 | 180 | #绘制图像等价模式LBP特征的归一化统计直方图 181 | def show_uniform_hist(self,img_array): 182 | self.show_hist(img_array,[60],[0,60]) 183 | 184 | #绘制图像旋转不变等价模式LBP特征的归一化统计直方图 185 | def show_revolve_uniform_hist(self,img_array): 186 | self.show_hist(img_array,[10],[0,10]) 187 | 188 | #显示图像 189 | def show_image(self,image_array): 190 | cv2.imshow('Image',image_array) 191 | cv2.waitKey(0) 192 | 193 | if __name__ == '__main__': 194 | image = r"C:\\Users\\Admin\\Desktop\\666\\Project\\segmention\\train\\4_3_0.tif"; 195 | lbp=LBP() 196 | image_array=lbp.describe(image) 197 | 198 | #获取图像原始LBP特征,并显示其统计直方图与特征图像 199 | basic_array=lbp.lbp_basic(image_array) 200 | lbp.show_basic_hist(basic_array) 201 | lbp.show_image(basic_array) 202 | 203 | #获取图像旋转不变LBP特征,并显示其统计直方图与特征图像 204 | #revolve_array=lbp.lbp_revolve(image_array) 205 | #lbp.show_revolve_hist(revolve_array) 206 | #lbp.show_image(revolve_array) 207 | 208 | #获取图像等价模式LBP特征,并显示其统计直方图与特征图像 209 | #uniform_array=lbp.lbp_uniform(image_array) 210 | #lbp.show_uniform_hist(uniform_array) 211 | #lbp.show_image(uniform_array) 212 | 213 | #获取图像等价模式LBP特征,并显示其统计直方图与特征图像 214 | #resolve_uniform_array=lbp.lbp_revolve_uniform(image_array) 215 | #lbp.show_revolve_uniform_hist(resolve_uniform_array) 216 | #lbp.show_image(resolve_uniform_array) 217 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------