我尝试使用此代码挤压图像:
:*:h::
SendInput, х
FingerPrint(22)
return
:*:s::
SendInput, с
FingerPrint(22)
return
:*:sh::
SendInput, ш
FingerPrint(22)
return
当我在图像上试一试时,它告诉我:
ValueError:无法将形状(512)的输入数组广播为形状(256)
出于某种原因,它仅在我仅用于行或仅用于列时才有效 像这样:
def squeeze_image(im,factor):
new_n = im.shape[0]/ factor
new_m = im.shape[1]/factor
new_mat = np.zeros((new_n,new_m))
for j in range(new_mat.shape[1]):
curr_range = range(j*factor,min((j+1)*factor,im.shape[1]))
new_mat[:,j] = im[:,curr_range].mean(axis=1)
for i in range(new_mat.shape[0]):
curr_range1 = range(i*factor,min((i+1)*factor,im.shape[0]))
new_mat[i,:] = im[curr_range1,:].mean(axis=0)
return new_mat
我怎样才能让它在两列上都有效?
答案 0 :(得分:1)
考虑数组的形状。
假设im
具有形状(factor*H, factor*W)
,那么
new_mat
的形状为(H, W)
。
现在考虑一下
行new_mat[:,j] = im[:,curr_range].mean(axis=1)
在右侧,im[:, curr_range]
的某些(factor*H, L)
的形状为L
,而im[:,curr_range].mean(axis=1)
的形状为(factor*H,)
。
在左侧,new_mat[:, j]
的形状为(H,)
。
除了factor = 1
时,作业左侧和右侧的形状不匹配,无法广播同意。
此问题会影响squeeze_image
的两个版本。
要解决此问题,您可以使用
new_mat[i, j] = im[i*factor:(i+1)*factor, j*factor:(j+1)*factor].mean()
一次切掉im
的2D矩形块,然后取2D维修的平均值。
import numpy as np
import itertools as IT
def squeeze_image(im,factor):
H, W = im.shape
H2, W2 = H/factor, W/factor
new_mat = np.zeros((H2, W2))
for i, j in IT.product(range(H2), range(W2)):
new_mat[i, j] = im[i*factor:(i+1)*factor, j*factor:(j+1)*factor].mean()
return new_mat
im = np.arange(100).reshape((10,10))
print(im)
# [[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
# [ 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.]
# [ 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.]
# [ 30. 31. 32. 33. 34. 35. 36. 37. 38. 39.]
# [ 40. 41. 42. 43. 44. 45. 46. 47. 48. 49.]
# [ 50. 51. 52. 53. 54. 55. 56. 57. 58. 59.]
# [ 60. 61. 62. 63. 64. 65. 66. 67. 68. 69.]
# [ 70. 71. 72. 73. 74. 75. 76. 77. 78. 79.]
# [ 80. 81. 82. 83. 84. 85. 86. 87. 88. 89.]
# [ 90. 91. 92. 93. 94. 95. 96. 97. 98. 99.]]
im2 = squeeze_image(im, 2)
print(im2)
产量
[[ 5.5 7.5 9.5 11.5 13.5]
[ 25.5 27.5 29.5 31.5 33.5]
[ 45.5 47.5 49.5 51.5 53.5]
[ 65.5 67.5 69.5 71.5 73.5]
[ 85.5 87.5 89.5 91.5 93.5]]
一位鸽友,但计算这一结果的效率要高得多
使用reshape/swapaxes
到形状(factor,factor)
的{{3}},
然后取每个块的平均值:
def downsample(im,factor):
H, W = im.shape
H2, W2 = H/factor, W/factor
im = im[:H2*factor, :W2*factor]
new_mat = (im.reshape(H2, factor, -1, factor)
.swapaxes(1, 2)).reshape(H2, W2, -1).mean(axis=-1)
return new_mat
对于小数组im
,这大约快17倍。
In [91]: %timeit squeeze_image(im, 2)
1000 loops, best of 3: 319 µs per loop
In [97]: %timeit downsample(im, 2)
100000 loops, best of 3: 17.2 µs per loop
速度优势随着squeeze_image
中for循环的迭代次数而增加,等于H2*W2
。
请注意,chop the array into blocks也可以挤压或缩放图像。它使用样条插值而不是采用手段。结果,即使使用样条order=1
,也会有所不同:
import scipy.ndimage as ndimage
print(ndimage.zoom(im, 0.5, order=1))
产量
[[ 0. 2.25 4.5 6.75 9. ]
[ 22.5 24.75 27. 29.25 31.5 ]
[ 45. 47.25 49.5 51.75 54. ]
[ 67.5 69.75 72. 74.25 76.5 ]
[ 90. 92.25 94.5 96.75 99. ]]