## Bradley-Roth自适应阈值算法 - 如何获得更好的性能？内容来源于 Stack Overflow，并遵循CC BY-SA 3.0许可协议进行翻译与使用

• 回答 (2)
• 关注 (0)
• 查看 (167)

``````from PIL import Image
import copy
import time
ws = windowsize
image2 = copy.copy(image).convert('L')
w, h = image.size
threshold /= 100.0
for y in xrange(h):
for x in xrange(w):
#find neighboring pixels
neighbors =[(x+x2,y+y2) for x2 in xrange(-ws,ws) for y2 in xrange(-ws, ws) if x+x2>0 and x+x2<w and y+y2>0 and y+y2<h]
#mean of all neighboring pixels
mean = sum([l[a,b] for a,b in neighbors])/len(neighbors)
if l[x, y] < threshold*mean:
l2[x,y] = 0
else:
l2[x,y] = 255
return image2

i = Image.open('test.jpg')
windowsize = 5
``````

`windowsize`小而图像小时，这可以正常工作。我一直在使用这个图像进行测试：

### 2 个回答

``````import numpy as np
from PIL import Image

# Convert image to numpy array
img = np.array(image).astype(np.float)

# Default window size is round(cols/8)
if s is None:
s = np.round(img.shape[1]/8)

# Default threshold is 15% of the total
# area in the window
if t is None:
t = 15.0

# Compute integral image
intImage = np.cumsum(np.cumsum(img, axis=1), axis=0)

# Define grid of points
(rows,cols) = img.shape[:2]
(X,Y) = np.meshgrid(np.arange(cols), np.arange(rows))

# Make into 1D grid of coordinates for easier access
X = X.ravel()
Y = Y.ravel()

# Ensure s is even so that we are able to index into the image
# properly
s = s + np.mod(s,2)

# Access the four corners of each neighbourhood
x1 = X - s/2
x2 = X + s/2
y1 = Y - s/2
y2 = Y + s/2

# Ensure no coordinates are out of bounds
x1[x1 < 0] = 0
x2[x2 >= cols] = cols-1
y1[y1 < 0] = 0
y2[y2 >= rows] = rows-1

# Ensures coordinates are integer
x1 = x1.astype(np.int)
x2 = x2.astype(np.int)
y1 = y1.astype(np.int)
y2 = y2.astype(np.int)

# Count how many pixels are in each neighbourhood
count = (x2 - x1) * (y2 - y1)

# Compute the row and column coordinates to access
# each corner of the neighbourhood for the integral image
f1_x = x2
f1_y = y2
f2_x = x2
f2_y = y1 - 1
f2_y[f2_y < 0] = 0
f3_x = x1-1
f3_x[f3_x < 0] = 0
f3_y = y2
f4_x = f3_x
f4_y = f2_y

# Compute areas of each window
sums = intImage[f1_y, f1_x] - intImage[f2_y, f2_x] - intImage[f3_y, f3_x] + intImage[f4_y, f4_x]

# Compute thresholded image and reshape into a 2D grid
out = np.ones(rows*cols, dtype=np.bool)
out[img.ravel()*count <= sums*(100.0 - t)/100.0] = False

# Also convert back to uint8
out = 255*np.reshape(out, (rows, cols)).astype(np.uint8)

# Return PIL image back to user
return Image.fromarray(out)

if __name__ == '__main__':
img = Image.open('test.jpg').convert('L')
out.show()
out.save('output.jpg')
``````

``````out = bradley_roth_numpy(img, windowsize, threshold)
``````

``````In [16]: %timeit bradley_roth_numpy(img)
100 loops, best of 3: 7.68 ms per loop
``````

``````   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
50246    2.009    0.000    2.009    0.000 <ipython-input-78-b628a43d294b>:15(<listcomp>)
50246    0.587    0.000    0.587    0.000 <ipython-input-78-b628a43d294b>:17(<listcomp>)
1    0.170    0.170    2.829    2.829 <ipython-input-78-b628a43d294b>:5(bradley_threshold)
50246    0.058    0.000    0.058    0.000 {built-in method sum}
50257    0.004    0.000    0.004    0.000 {built-in method len}
``````