我试图计算图像中子窗口的熵特征。下面是我写的代码:
def genHist(img):
hist = np.histogram(img, np.arange(0, 256), normed=True)
return hist[0]
def calcEntropy(hist):
logs = np.nan_to_num(np.log2(hist))
hist_loghist = hist * logs
entropy = -1 * hist_loghist.sum()
return entropy
img = cv2.imread("lena.jpg", 0)
result = np.zeros(img.shape, dtype=np.float16)
h, w = img.shape
subwin_size = 5
for y in xrange(subwin_size, h-subwin_size):
for x in xrange(subwin_size, w-subwin_size):
subwin = img[y-subwin_size:y+subwin_size, x-subwin_size:x+subwin_size]
hist = genHist(subwin) # Generate histogram
entropy = calcEntropy(hist) # Calculate entropy
result[y, x] = entropy
实际上,它是有效的。但问题是它的速度太慢了。 你有什么办法快点吗?在
{{{1}你应该用哪个函数来代替第一步:
问题是},即使
math.log
将在遇到的每一个0
时产生一个错误。您可以通过从直方图输出中删除所有0
来绕过此问题。这有几个优点:1)数学。日志不会失败,2)根据您的映像,math.log
将被调用更少,这将导致更快的代码。您可以删除零,因为0*log(0)
变成{log(0)
将返回一个值。所以,乘积不会加到熵和上。在我在一些音频处理方面也遇到了同样的问题。不幸的是,我不能改进它超过以上。如果你能找到更好的解决办法,我会很高兴你能把它贴在这里。在
你可以做一些修改使它更快。在
您的代码在我的笔记本电脑中需要以下时间:
我做了以下修改:
1-删除了函数
genHist
,并在calcEntropy()
中实现了它。它将节省,可能是1或2秒。在2-在查找日志之前,我只简单地将一个小值0.00001添加到hist,而不是
logs = np.nan_to_num(np.log2(hist))
。logs = np.log2(hist+0.00001)
。它将保存3-4 seconds
,但它会稍微改变您的输出。两个结果之间的最大误差是0.0039062
。(所以这取决于你是否想要这个)3-将
np.histogram
更改为cv2.calcHist()
。它将节省多于25 seconds
。现在,代码在我的笔记本电脑上花费了以下时间:
^{pr2}$它是3倍以上的速度。在
代码:
现在的主要问题是
two for loops
。我认为它是Cython
实现的最佳候选方案,它将产生非常好的结果。相关问题 更多 >
编程相关推荐