快速分析图像中每个子窗口的方法?

2024-09-30 18:35:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图计算图像中子窗口的熵特征。下面是我写的代码:

  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

实际上,它是有效的。但问题是它的速度太慢了。 你有什么办法快点吗?在


Tags: imgsizereturndefnpresulthisthistogram
2条回答

{{{1}你应该用哪个函数来代替第一步:

import numpy as np
import math

x=abs(randn(1000000))

#unsing numpy
start = time.time()
for i in x:
    np.log2(i)
print "Runtime: %f s" % (time.time()-start)
>>> Runtime: 3.653858 s

#using math.log
start = time.time()
for i in x:
    math.log(i,2)        # use log with base 2
print "Runtime: %f s" % (time.time()-start)
>>> Runtime: 0.692702 s

问题是math.log将在遇到的每一个0时产生一个错误。您可以通过从直方图输出中删除所有0来绕过此问题。这有几个优点:1)数学。日志不会失败,2)根据您的映像,math.log将被调用更少,这将导致更快的代码。您可以删除零,因为0*log(0)变成{},即使log(0)将返回一个值。所以,乘积不会加到熵和上。在

我在一些音频处理方面也遇到了同样的问题。不幸的是,我不能改进它超过以上。如果你能找到更好的解决办法,我会很高兴你能把它贴在这里。在

你可以做一些修改使它更快。在

您的代码在我的笔记本电脑中需要以下时间:

IPython CPU timings (estimated):
  User   :      50.92 s.
  System :       0.01 s.
Wall time:      51.20 s.

我做了以下修改:

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倍以上的速度。在

代码:

def calcEntropy(img):
    #hist,_ = np.histogram(img, np.arange(0, 256), normed=True)
    hist = cv2.calcHist([img],[0],None,[256],[0,256])
    hist = hist.ravel()/hist.sum()
    #logs = np.nan_to_num(np.log2(hist))
    logs = np.log2(hist+0.00001)
    #hist_loghist = hist * logs
    entropy = -1 * (hist*logs).sum()
    return entropy  

img = cv2.imread("lena.jpg", 0)
result2 = 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(subwin)    # Calculate entropy
       result2.itemset(y,x,entropy)

现在的主要问题是two for loops。我认为它是Cython实现的最佳候选方案,它将产生非常好的结果。

相关问题 更多 >