Python MATLAB 的 graycomatrix 和 graycoprops 的实现
Python Implementation of MATLAB's graycomatrix and graycoprops
image of cat used
来源:https://www.petfinder.com/cats/cat-grooming/
我试图在 Python 中接收函数 graycomatrix 和 graycoprops 的结果与 MATLAB 中完全相同的结果。但是结果不同,我无法编写将重复 MATLAB 结果的代码。
我需要 GLCM 特征,例如对比度、相关性、能量和均匀性。
非常感谢任何建议。
MATLAB 中的示例代码:
% GLCM feature extraction
offset_GLCM = [0 1; -1 1; -1 0; -1 -1];
offset = [1*offset_GLCM ; 2*offset_GLCM; 3*offset_GLCM];
img = rgb2gray(imread('cat.jpg'));
Grauwertmatrix = graycomatrix(img,'NumLevels', 12, 'GrayLimits', [], 'Offset',offset);
GrauwertStats = graycoprops(Grauwertmatrix);
GLCMFeatureVector = [mean(GrauwertStats.Contrast) mean(GrauwertStats.Correlation) mean(GrauwertStats.Energy) mean(GrauwertStats.Homogeneity)];
disp(GLCMFeatureVector);
和上面的代码returns:
1.6212 0.8862 0.0607 0.7546
现在我想在 Python 中收到完全相同的结果。我使用 Python 代码:
# GLCM feature extraction
import numpy as np
from skimage import feature, io
from sklearn import preprocessing
img = io.imread("cat.jpg", as_grey=True)
S = preprocessing.MinMaxScaler((0,11)).fit_transform(img).astype(int)
Grauwertmatrix = feature.greycomatrix(S, [1,2,3], [0, np.pi/4, np.pi/2, 3*np.pi/4], levels=12, symmetric=False, normed=True)
ContrastStats = feature.greycoprops(Grauwertmatrix, 'contrast')
CorrelationtStats = feature.greycoprops(Grauwertmatrix, 'correlation')
HomogeneityStats = feature.greycoprops(Grauwertmatrix, 'homogeneity')
ASMStats = feature.greycoprops(Grauwertmatrix, 'ASM')
print([np.mean(ContrastStats), np.mean(CorrelationtStats),\
np.mean(ASMStats), np.mean(HomogeneityStats)])
但我得到的结果是:
[1.7607, 0.8844, 0.0429, 0.7085]
再举个例子。原始图像的不同结果。原因是 MATLAB 默认处理图像,而 Python 不处理图像。如何在 Python 中获得与在 MATLAB 中相同的结果?:
MATLAB:
>> img = rgb2gray(imread('cat.png'));
>> [Grauwertmatrix, S] = graycomatrix(img,'NumLevels',12,'GrayLimits',[0,12],'Offset',[0,1]);
>> Grauwertmatrix(1:5,1:5)
ans =
4 7 4 8 0
9 33 22 13 10
5 18 16 10 10
2 16 11 22 13
4 12 11 14 14
Python:
>>> from skimage import io, feature
>>> img = io.imread("cat.png", as_grey=True)
>>> Grauwertmatrix = feature.greycomatrix(img, distances=[1], angles=[0], levels=12, symmetric=False, normed=False)
>>> Grauwertmatrix[0:5, 0:5, 0, 0]
array([[299720, 2, 0, 0, 0],
[ 2, 1, 0, 0, 0],
[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0]], dtype=uint32)
使用 Matlab 和 Python 计算的 GLCM 特征不同,因为使用您的 Matlab 代码对原始图像进行预处理(即转换为灰度、缩放和重新量化)的结果与您的 Python 代码(即数组 S
)。以下片段使其显而易见:
Matlab
>> offset_GLCM = [0 1; -1 1; -1 0; -1 -1];
>> offset = [1*offset_GLCM ; 2*offset_GLCM; 3*offset_GLCM];
>> img = rgb2gray(imread('cat.png'));
>> [Grauwertmatrix, S] = graycomatrix(img,'NumLevels', 12, 'GrayLimits', [], 'Offset',offset);
>> S(100:105, 100:105)
ans =
4 5 7 8 8 6
5 5 6 7 8 7
4 4 4 6 7 7
4 4 5 6 8 8
5 6 6 7 8 8
4 5 6 6 7 8
Python
In [36]: from skimage import io
In [37]: from sklearn import preprocessing
In [38]: img = io.imread("cat.png", as_grey=True)
In [39]: S = preprocessing.MinMaxScaler((0,11)).fit_transform(img).astype(int)
In [40]: S[99:105, 99:105]
Out[40]:
array([[2, 4, 6, 7, 5, 5],
[2, 3, 4, 5, 6, 5],
[2, 1, 1, 3, 5, 6],
[2, 2, 2, 4, 6, 7],
[3, 4, 4, 5, 6, 7],
[2, 3, 4, 4, 5, 7]])
最后,我建议您使用无损图像格式(例如 BMP 或 PNG)以避免由于 JPG 解压缩而导致的潜在差异。
解决方法
为了通过 Matlab 和 Python 获得相同的结果,您应该在这两种情况下使用相同的预处理图像。这样的图像可以像这样生成:
from skimage import io
from sklearn import preprocessing
img = io.imread("cat.png", as_grey=True)
S = preprocessing.MinMaxScaler((0,11)).fit_transform(img).astype(int)
io.imsave('cat_preprocessed.png', S)
请注意,resulting image 的对比度非常低,因为强度值的范围从 0 到 11。
为了让 Matlab 的 graycomatrix
正确缩放此图像,您需要传递 'NumLevels',12
和 'GrayLimits',[0,12]
(而不是 [0,11]
):
>> img = imread('cat_preprocessed.png');
>> [Grauwertmatrix, S] = graycomatrix(img,'NumLevels',12,'GrayLimits',[0,12],'Offset',[0,1]);
>> Grauwertmatrix(1:5,1:5)
ans =
21258 3250 452 186 91
3208 20119 5268 827 267
532 5242 40541 8508 1203
208 848 8616 26436 6324
102 285 1192 6216 14101
>> graycoprops(Grauwertmatrix,{'contrast'})
ans =
Contrast: 0.9681
Pythonreturns结果相同:
In [86]: from skimage import io, feature
In [87]: img = io.imread("cat_preprocessed.png")
In [88]: Grauwertmatrix = feature.greycomatrix(img, distances=[1], angles=[0], levels=12, symmetric=False, normed=False)
In [89]: Grauwertmatrix[0:5, 0:5, 0, 0]
Out[89]:
array([[21258, 3250, 452, 186, 91],
[ 3208, 20119, 5268, 827, 267],
[ 532, 5242, 40541, 8508, 1203],
[ 208, 848, 8616, 26436, 6324],
[ 102, 285, 1192, 6216, 14101]], dtype=uint32)
In [90]: feature.greycoprops(Grauwertmatrix, 'contrast')
Out[90]: array([[ 0.96812745]])
编辑
回复您的评论,我认为不可能通过 Matlab 和 Python 从原始 RGB 图像获得相同的结果,因为转换为灰度的执行方式不同。这在文档中有明确说明:
Matlab 的 rgb2gray
:
rgb2gray
converts RGB values to grayscale values by forming a weighted sum of the R, G, and B components:
0.2989 * R + 0.5870 * G + 0.1140 * B
scikit-image 的 rgb2gray
:
The weights used in this conversion are calibrated for contemporary CRT phosphors:
Y = 0.2125 R + 0.7154 G + 0.0721 B
image of cat used
来源:https://www.petfinder.com/cats/cat-grooming/
我试图在 Python 中接收函数 graycomatrix 和 graycoprops 的结果与 MATLAB 中完全相同的结果。但是结果不同,我无法编写将重复 MATLAB 结果的代码。
我需要 GLCM 特征,例如对比度、相关性、能量和均匀性。
非常感谢任何建议。
MATLAB 中的示例代码:
% GLCM feature extraction
offset_GLCM = [0 1; -1 1; -1 0; -1 -1];
offset = [1*offset_GLCM ; 2*offset_GLCM; 3*offset_GLCM];
img = rgb2gray(imread('cat.jpg'));
Grauwertmatrix = graycomatrix(img,'NumLevels', 12, 'GrayLimits', [], 'Offset',offset);
GrauwertStats = graycoprops(Grauwertmatrix);
GLCMFeatureVector = [mean(GrauwertStats.Contrast) mean(GrauwertStats.Correlation) mean(GrauwertStats.Energy) mean(GrauwertStats.Homogeneity)];
disp(GLCMFeatureVector);
和上面的代码returns:
1.6212 0.8862 0.0607 0.7546
现在我想在 Python 中收到完全相同的结果。我使用 Python 代码:
# GLCM feature extraction
import numpy as np
from skimage import feature, io
from sklearn import preprocessing
img = io.imread("cat.jpg", as_grey=True)
S = preprocessing.MinMaxScaler((0,11)).fit_transform(img).astype(int)
Grauwertmatrix = feature.greycomatrix(S, [1,2,3], [0, np.pi/4, np.pi/2, 3*np.pi/4], levels=12, symmetric=False, normed=True)
ContrastStats = feature.greycoprops(Grauwertmatrix, 'contrast')
CorrelationtStats = feature.greycoprops(Grauwertmatrix, 'correlation')
HomogeneityStats = feature.greycoprops(Grauwertmatrix, 'homogeneity')
ASMStats = feature.greycoprops(Grauwertmatrix, 'ASM')
print([np.mean(ContrastStats), np.mean(CorrelationtStats),\
np.mean(ASMStats), np.mean(HomogeneityStats)])
但我得到的结果是:
[1.7607, 0.8844, 0.0429, 0.7085]
再举个例子。原始图像的不同结果。原因是 MATLAB 默认处理图像,而 Python 不处理图像。如何在 Python 中获得与在 MATLAB 中相同的结果?:
MATLAB:
>> img = rgb2gray(imread('cat.png'));
>> [Grauwertmatrix, S] = graycomatrix(img,'NumLevels',12,'GrayLimits',[0,12],'Offset',[0,1]);
>> Grauwertmatrix(1:5,1:5)
ans =
4 7 4 8 0
9 33 22 13 10
5 18 16 10 10
2 16 11 22 13
4 12 11 14 14
Python:
>>> from skimage import io, feature
>>> img = io.imread("cat.png", as_grey=True)
>>> Grauwertmatrix = feature.greycomatrix(img, distances=[1], angles=[0], levels=12, symmetric=False, normed=False)
>>> Grauwertmatrix[0:5, 0:5, 0, 0]
array([[299720, 2, 0, 0, 0],
[ 2, 1, 0, 0, 0],
[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0]], dtype=uint32)
使用 Matlab 和 Python 计算的 GLCM 特征不同,因为使用您的 Matlab 代码对原始图像进行预处理(即转换为灰度、缩放和重新量化)的结果与您的 Python 代码(即数组 S
)。以下片段使其显而易见:
Matlab
>> offset_GLCM = [0 1; -1 1; -1 0; -1 -1];
>> offset = [1*offset_GLCM ; 2*offset_GLCM; 3*offset_GLCM];
>> img = rgb2gray(imread('cat.png'));
>> [Grauwertmatrix, S] = graycomatrix(img,'NumLevels', 12, 'GrayLimits', [], 'Offset',offset);
>> S(100:105, 100:105)
ans =
4 5 7 8 8 6
5 5 6 7 8 7
4 4 4 6 7 7
4 4 5 6 8 8
5 6 6 7 8 8
4 5 6 6 7 8
Python
In [36]: from skimage import io
In [37]: from sklearn import preprocessing
In [38]: img = io.imread("cat.png", as_grey=True)
In [39]: S = preprocessing.MinMaxScaler((0,11)).fit_transform(img).astype(int)
In [40]: S[99:105, 99:105]
Out[40]:
array([[2, 4, 6, 7, 5, 5],
[2, 3, 4, 5, 6, 5],
[2, 1, 1, 3, 5, 6],
[2, 2, 2, 4, 6, 7],
[3, 4, 4, 5, 6, 7],
[2, 3, 4, 4, 5, 7]])
最后,我建议您使用无损图像格式(例如 BMP 或 PNG)以避免由于 JPG 解压缩而导致的潜在差异。
解决方法
为了通过 Matlab 和 Python 获得相同的结果,您应该在这两种情况下使用相同的预处理图像。这样的图像可以像这样生成:
from skimage import io
from sklearn import preprocessing
img = io.imread("cat.png", as_grey=True)
S = preprocessing.MinMaxScaler((0,11)).fit_transform(img).astype(int)
io.imsave('cat_preprocessed.png', S)
请注意,resulting image 的对比度非常低,因为强度值的范围从 0 到 11。
为了让 Matlab 的 graycomatrix
正确缩放此图像,您需要传递 'NumLevels',12
和 'GrayLimits',[0,12]
(而不是 [0,11]
):
>> img = imread('cat_preprocessed.png');
>> [Grauwertmatrix, S] = graycomatrix(img,'NumLevels',12,'GrayLimits',[0,12],'Offset',[0,1]);
>> Grauwertmatrix(1:5,1:5)
ans =
21258 3250 452 186 91
3208 20119 5268 827 267
532 5242 40541 8508 1203
208 848 8616 26436 6324
102 285 1192 6216 14101
>> graycoprops(Grauwertmatrix,{'contrast'})
ans =
Contrast: 0.9681
Pythonreturns结果相同:
In [86]: from skimage import io, feature
In [87]: img = io.imread("cat_preprocessed.png")
In [88]: Grauwertmatrix = feature.greycomatrix(img, distances=[1], angles=[0], levels=12, symmetric=False, normed=False)
In [89]: Grauwertmatrix[0:5, 0:5, 0, 0]
Out[89]:
array([[21258, 3250, 452, 186, 91],
[ 3208, 20119, 5268, 827, 267],
[ 532, 5242, 40541, 8508, 1203],
[ 208, 848, 8616, 26436, 6324],
[ 102, 285, 1192, 6216, 14101]], dtype=uint32)
In [90]: feature.greycoprops(Grauwertmatrix, 'contrast')
Out[90]: array([[ 0.96812745]])
编辑
回复您的评论,我认为不可能通过 Matlab 和 Python 从原始 RGB 图像获得相同的结果,因为转换为灰度的执行方式不同。这在文档中有明确说明:
Matlab 的 rgb2gray
:
rgb2gray
converts RGB values to grayscale values by forming a weighted sum of the R, G, and B components:0.2989 * R + 0.5870 * G + 0.1140 * B
scikit-image 的 rgb2gray
:
The weights used in this conversion are calibrated for contemporary CRT phosphors:
Y = 0.2125 R + 0.7154 G + 0.0721 B