Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用矩阵算法计算二值图像的Numpy矩阵的均方误差_Python_Arrays_Numpy_Image Processing_Image Segmentation - Fatal编程技术网

Python 用矩阵算法计算二值图像的Numpy矩阵的均方误差

Python 用矩阵算法计算二值图像的Numpy矩阵的均方误差,python,arrays,numpy,image-processing,image-segmentation,Python,Arrays,Numpy,Image Processing,Image Segmentation,我有两个二值图像,一个是地面真相,一个是我制作的图像分割 我正在计算均方距离 在两幅图像之间使用以下算法 def MSD(A,G): ''' Takes a thresholded binary image, and a ground truth img(binary), and computes the mean squared absolute difference :param A: The thresholded binary image :param

我有两个二值图像,一个是地面真相,一个是我制作的图像分割

我正在计算均方距离

在两幅图像之间使用以下算法

def MSD(A,G):
    '''
    Takes a thresholded binary image, and a ground truth img(binary), and computes the mean squared absolute difference
    :param A: The thresholded binary image
    :param G: The ground truth img
    :return:
    '''
    sim = np.bitwise_xor(A,G)
    sum = 0
    for i in range(0,sim.shape[0]):
        for j in range(0,sim.shape[1]):
            if (sim[i,j] == True):
                min = 9999999
                for k in range(0,sim.shape[0]):
                    for l in range(0,sim.shape[1]):
                        if (sim[k, l] == True):
                            e = abs(i-k) + abs(j-l)
                            if e < min:
                                min = e
                                mink = k
                                minl = l
                sum += min
    return sum/(sim.shape[0]*sim.shape[1])
def MSD(A、G):
'''
获取阈值化的二值图像和基本真值img(二进制),并计算均方绝对差
:param A:阈值化二值图像
:param G:地面真相img
:返回:
'''
sim=np.按位异或(A,G)
总和=0
对于范围内的i(0,模拟形状[0]):
对于范围(0,模拟形状[1])中的j:
如果(sim[i,j]==True):
最小值=9999999
对于范围内的k(0,模拟形状[0]):
对于范围内的l(0,模拟形状[1]):
如果(sim[k,l]==True):
e=abs(i-k)+abs(j-l)
如果e
不过,这个算法太慢,永远不会完成


这个和(答案3)可能展示了如何使用矩阵运算得到均方误差的方法,但我不明白这些例子有什么意义,也不明白它们为什么起作用

如果我正确理解了你的公式和代码,你有一个(二进制)图像
B
和一个(基本真理)图像
G
。“点”由像素位置定义,其中任一图像具有
True
(或至少非零)值。从您的
按位异或
中,我推断两个图像具有相同的形状
(M,N)

因此,数量
d^2(b,g)
最坏情况下是
(M*N,M*N)
大小的数组,将
b
的每个像素与
g
的每个像素相关联。它甚至更好:如果在
B
中有
m
非零,在
G
中有
n
非零,我们只需要一个形状
(m,n)
。除非你的图片很大,否则我们可以跟踪这一大数量的图片。这将消耗内存,但通过矢量化,我们将赢得大量CPU时间。因此,我们只需要找到每个
n
可能值的最小距离,对于每个
m
。然后把每个最小值加起来。请注意,下面的解决方案使用了极端的矢量化,如果图像很大,它很容易占用您的内存

假设曼哈顿距离(在
d^2
中有一个正方形,代码中似乎缺少该正方形):


如果上面使用了太多内存,我们可以在
nnz_B
的元素上引入一个循环,并且只在
nnz_G
的元素中进行矢量化。这将占用更多的CPU资源和更少的内存。这种折衷是典型的矢量化。

计算此距离的有效方法是使用距离变换。SciPy在ndimage包中有一个实现:

其思想是计算地面真实图像背景的距离变换
G
。这导致新图像
D
,对于
G
中非零的每个像素为0,对于
G
中的每个零像素,将有到最近非零像素的距离

接下来,对于
B
中的每个非零像素(或您发布的代码中的
A
),查看
D
中相应的像素。这是该像素到
G
的距离。因此,只需对
D
B
为非零的所有值求平均值即可获得结果

import numpy as np
import scipy.ndimage as nd
import matplotlib.pyplot as pp

# Create some test data
img = pp.imread('erika.tif')         # a random image
G = img > 120                        # the ground truth
img = img + np.random.normal(0, 20, img.shape)
B = img > 120                        # the other image

D = nd.morphology.distance_transform_edt(~G)
msd = np.mean(D[B]**2)

您的代码与等式不匹配。通过计算对称差分(xor),您的代码是对称的。如果我交换
A
G
我会得到相同的结果。这对于方程是不正确的,这不是对称的距离度量。
B
A
)中不在
G
中的像素会增加平均距离。
G
中的像素不在
B
中。@CrisLuengo它看起来可能是对称的,但它不是对称的。这正是公式所说的。
dist2
成对距离是“对称的”(就像
d^2(b,g)
),但最小化发生在第二维度,求和发生在第一维度。如果这还不够令人信服:
MSD(B,G)!=MSD(G,B)
如果我将度量值更改为欧几里德,我会得到与您完全相同的结果;)但你让我去了一秒钟!是的,我自己去了那里一分钟。:)对不起,我还在习惯Numpy的索引方式。实际上,您是沿着2D距离矩阵的一个维度取最小值,然后沿着另一个维度求和。完全有道理。
import numpy as np

# generate dummy data
M,N = 100,100
B = np.random.rand(M,N) > 0.5
G = np.random.rand(M,N) > 0.5

def MSD(B, G):
    # get indices of nonzero pixels
    nnz_B = B.nonzero() # (x_inds, y_inds) tuple, x_inds and y_inds are shape (m,)
    nnz_G = G.nonzero() # (x_inds', y_inds') each with shape (n,)

    # np.array(nnz_B) has shape (2,m)
    # compute squared Manhattan distance
    dist2 = abs(np.array(nnz_B)[...,None] - np.array(nnz_G)[:,None,:]).sum(axis=0)**2 # shape (m,n)
    # alternatively: Euclidean for comparison:
    #dist2 = ((np.array(nnz_B)[...,None] - np.array(nnz_G)[:,None,:])**2).sum(axis=0)

    mindist2 = dist2.min(axis=-1) # shape (m,) of minimum square distances

    return mindist2.mean() # sum divided by m, i.e. the MSD itself

print(MSD(B, G))
import numpy as np
import scipy.ndimage as nd
import matplotlib.pyplot as pp

# Create some test data
img = pp.imread('erika.tif')         # a random image
G = img > 120                        # the ground truth
img = img + np.random.normal(0, 20, img.shape)
B = img > 120                        # the other image

D = nd.morphology.distance_transform_edt(~G)
msd = np.mean(D[B]**2)