在python中将图像分成5x5块并为每个块计算直方图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22685274/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Divide an image into 5x5 blocks in python and compute histogram for each block
提问by Jonas
Using Python, I have to:
使用 Python,我必须:
- Divide a
Test_ImageandReference_imageinto 5x5 blocks, - Compute a histogram for each block, and compare it with the same block in the other image.
For Example:image1(1,1)withimage2(1,1). - Compare the similarity between two images (should be transform invariant).
- 将 a
Test_Image和Reference_image分成 5x5 块, - 为每个块计算直方图,并将其与另一个图像中的相同块进行比较。
例如:image1(1,1)与image2(1,1). - 比较两幅图像的相似度(应该是变换不变的)。
So far, I have calculated the histogram of the whole image using hist=numpy.histogram(image,bins=256)
到目前为止,我已经使用计算了整个图像的直方图 hist=numpy.histogram(image,bins=256)
I want to divide an image, and later compute the histogram for all those blocks . I also want to use Bhattacharya's coefficient to measure the similarity.
我想分割一个图像,然后计算所有这些块的直方图。我还想使用 Bhattacharya 的系数来衡量相似性。
Can anyone guide me with how to go through this one? Thanks in advance :)
谁能指导我如何通过这个?提前致谢 :)
采纳答案by kkuilla
Not sure if it is something like this you are looking for, This is the brute-force version.and it's probably quite slow.but it does the job You have to decide what to do with the boundaries though. This will not include the boundary unless the window fits exactly
不确定它是否是您正在寻找的类似内容,这是蛮力版本。它可能很慢。但它可以完成工作,但您必须决定如何处理边界。这将不包括边界,除非窗口完全适合
import numpy as numpy
grey_levels = 256
# Generate a test image
test_image = numpy.random.randint(0,grey_levels, size=(11,11))
# Define the window size
windowsize_r = 5
windowsize_c = 5
# Crop out the window and calculate the histogram
for r in range(0,test_image.shape[0] - windowsize_r, windowsize_r):
for c in range(0,test_image.shape[1] - windowsize_c, windowsize_c):
window = test_image[r:r+windowsize_r,c:c+windowsize_c]
hist = numpy.histogram(window,bins=grey_levels)
Below is the result and the full image is at the end. r,c represents the topleft corner of the window
下面是结果,完整的图像在最后。r,c 代表窗口的左上角
r=0,c=0
[[ 63 173 131 205 239]
[106 37 156 48 81]
[ 85 85 119 60 228]
[236 79 247 1 206]
[ 97 50 117 96 206]]
r=0,c=5
[[108 241 155 214 183]
[202 2 236 183 225]
[214 141 1 185 115]
[ 4 234 249 95 67]
[232 217 116 211 24]]
r=5,c=0
[[179 155 41 47 190]
[159 69 211 41 92]
[ 64 184 187 104 245]
[190 199 71 228 166]
[117 56 92 5 186]]
r=5,c=5
[[ 68 6 69 63 242]
[213 133 139 59 44]
[236 69 148 196 215]
[ 41 228 198 115 107]
[109 236 191 48 53]]
[[ 63 173 131 205 239 108 241 155 214 183 42]
[106 37 156 48 81 202 2 236 183 225 4]
[ 85 85 119 60 228 214 141 1 185 115 80]
[236 79 247 1 206 4 234 249 95 67 203]
[ 97 50 117 96 206 232 217 116 211 24 242]
[179 155 41 47 190 68 6 69 63 242 162]
[159 69 211 41 92 213 133 139 59 44 196]
[ 64 184 187 104 245 236 69 148 196 215 91]
[190 199 71 228 166 41 228 198 115 107 82]
[117 56 92 5 186 109 236 191 48 53 65]
[177 170 114 163 101 54 80 25 112 35 85]]
回答by wwii
If your images are large, you can improve performance by manipulating the array's strides to produce the windowsyou need. The following will use a generalized sliding window function found at Efficient Overlapping Windows with Numpy- I will include it at the end.
如果您的图像很大,您可以通过操纵数组的步幅来生成您需要的窗口来提高性能。下面将使用在Efficient Overlapping Windows with Numpy 中找到的通用滑动窗口函数- 我将在最后包含它。
import numpy as np
image1 = np.arange(100).reshape(10,10)
image2 = np.arange(100).reshape(10,10)
from itertools import izip
window_size = (5,5)
windows1 = sliding_window(image1, window_size)
windows2 = sliding_window(image2, window_size)
histograms = [(np.histogram(window1,bins=256),np.histogram(window2,bins=256))
for window1, window2 in izip(windows1, windows2)]
for h1, h2 in histograms:
print np.all(h1[0] == h2[0])
sliding window function(s):
滑动窗口函数:
from numpy.lib.stride_tricks import as_strided as ast
from itertools import product
def norm_shape(shape):
'''
Normalize numpy array shapes so they're always expressed as a tuple,
even for one-dimensional shapes.
Parameters
shape - an int, or a tuple of ints
Returns
a shape tuple
'''
try:
i = int(shape)
return (i,)
except TypeError:
# shape was not a number
pass
try:
t = tuple(shape)
return t
except TypeError:
# shape was not iterable
pass
raise TypeError('shape must be an int, or a tuple of ints')
def sliding_window(a,ws,ss = None,flatten = True):
'''
Return a sliding window over a in any number of dimensions
Parameters:
a - an n-dimensional numpy array
ws - an int (a is 1D) or tuple (a is 2D or greater) representing the size
of each dimension of the window
ss - an int (a is 1D) or tuple (a is 2D or greater) representing the
amount to slide the window in each dimension. If not specified, it
defaults to ws.
flatten - if True, all slices are flattened, otherwise, there is an
extra dimension for each dimension of the input.
Returns
an array containing each n-dimensional window from a
from http://www.johnvinyard.com/blog/?p=268
'''
if None is ss:
# ss was not provided. the windows will not overlap in any direction.
ss = ws
ws = norm_shape(ws)
ss = norm_shape(ss)
# convert ws, ss, and a.shape to numpy arrays so that we can do math in every
# dimension at once.
ws = np.array(ws)
ss = np.array(ss)
shape = np.array(a.shape)
# ensure that ws, ss, and a.shape all have the same number of dimensions
ls = [len(shape),len(ws),len(ss)]
if 1 != len(set(ls)):
raise ValueError(\
'a.shape, ws and ss must all have the same length. They were %s' % str(ls))
# ensure that ws is smaller than a in every dimension
if np.any(ws > shape):
raise ValueError('ws cannot be larger than a in any dimension. a.shape was %s and ws was %s' % (str(a.shape),str(ws)))
# how many slices will there be in each dimension?
newshape = norm_shape(((shape - ws) // ss) + 1)
# the shape of the strided array will be the number of slices in each dimension
# plus the shape of the window (tuple addition)
newshape += norm_shape(ws)
# the strides tuple will be the array's strides multiplied by step size, plus
# the array's strides (tuple addition)
newstrides = norm_shape(np.array(a.strides) * ss) + a.strides
strided = ast(a,shape = newshape,strides = newstrides)
if not flatten:
return strided
# Collapse strided so that it has one more dimension than the window. I.e.,
# the new array is a flat list of slices.
meat = len(ws) if ws.shape else 0
firstdim = (np.product(newshape[:-meat]),) if ws.shape else ()
dim = firstdim + (newshape[-meat:])
# remove any dimensions with size 1
dim = filter(lambda i : i != 1,dim)
return strided.reshape(dim)
If you want to divide an image into four parts, you need to calculate the wsand ssparamaters. If both dimensions are divisible by two then wsand ssare the same value (ssdefaults to wswhen not specified). Numpy has the ability to treat array dimensions as (column, row) or (row, column) - I haven't changed any defaults and mine is (row, column). For an 18x26 picture, ws = (26/2, 18/2)- each window will be 13x9 and the adjacentwindows are obtained by silidingthe window by an equal amount, no overlap. If a dimension is not divisable by two, sswill also need to be determined and there will be some overlap in the windows. For an 18x33 image:
如果要将图像分成四部分,则需要计算ws和ss参数。如果两个维度都可以被 2 整除ws并且ss是相同的值(未指定时ss默认为ws)。Numpy 能够将数组维度视为 (column, row) 或 (row, column) - 我没有更改任何默认值,我的是 (row, column)。对于 18x26 的图片,ws = (26/2, 18/2)- 每个窗口将是 13x9 并且相邻的窗口是通过将窗口等量滑动而获得的,没有重叠。如果一个维度不能被二整除,ss也需要确定,并且窗口中会有一些重叠。对于 18x33 图像:
>>>
>>> rows = 33
>>> columns = 18
>>> divisor = 2
>>> col_size, col_overlap = divmod(columns, divisor)
>>> row_size, row_overlap = divmod(rows, divisor)
>>> ws = (row_size, col_size)
>>> ss = (row_size - row_overlap, col_size - col_overlap)
>>> ws, ss
((16, 9), (15, 9))
>>>
For 3d windows (data from images with a color dimension) wsand ssneed to have three dimensions. A 15x15 image will have 9 5x5x3 windows
对于 3d 窗口(来自具有颜色维度的图像的数据)ws并且ss需要具有三个维度。一个 15x15 的图像将有 9 个 5x5x3 的窗口
from PIL import Image
import numpy as np
img = Image.open('15by15.bmp')
a = np.asarray(img)
window_size = (5,5,3)
windows = sliding_window(a, window_size)
print windows.shape
>>> (9, 5, 5, 3)
for window in windows:
print window.shape
>>> (5, 5, 3) (5, 5, 3) (5, 5, 3) (5, 5, 3) (5, 5, 3) (5, 5, 3) (5, 5, 3) (5, 5, 3) (5, 5, 3)
回答by Holomorphic Guy
This worked for me. It has the ability to divide into n*m chunks. Pad your image accordingly.
这对我有用。它具有分成 n*m 块的能力。相应地填充您的图像。
def chunkify(img, block_width=4, block_height=4):
shape = img.shape
x_len = shape[0]//block_width
y_len = shape[1]//block_height
chunks = []
x_indices = [i for i in range(0, shape[0]+1, block_width)]
y_indices = [i for i in range(0, shape[1]+1, block_height)]
shapes = list(zip(x_indices, y_indices))
for i in range(len(shapes)):
try:
start_x = shapes[i][0]
start_y = shapes[i][1]
end_x = shapes[i+1][0]
end_y = shapes[i+1][1]
chunks.append( shapes[start_x:end_x][start_y:end_y] )
except IndexError:
print('End of Array')
return chunks
https://github.com/QuantumNovice/ImageProcessing/blob/master/image_chunkify.py
https://github.com/QuantumNovice/ImageProcessing/blob/master/image_chunkify.py
回答by Seymur Mammadli
I have write this code two automatically split image into n rows and m columns. m and n are arguments and it is easily modifiable. After that it is easy compute histogram for each block which are also saving into the folder named patches.
我写了这段代码,两个自动将图像分成 n 行和 m 列。m 和 n 是参数,很容易修改。之后很容易计算每个块的直方图,这些块也保存到名为补丁的文件夹中。
# Image path, number of rows
# and number of columns
# should be provided as an arguments
import cv2
import sys
import os
if not os.path.exists('patches'):
os.makedirs('patches')
nRows = int(sys.argv[2])
# Number of columns
mCols = int(sys.argv[3])
# Reading image
img = cv2.imread(sys.argv[1])
#print img
#cv2.imshow('image',img)
# Dimensions of the image
sizeX = img.shape[1]
sizeY = img.shape[0]
print(img.shape)
for i in range(0,nRows):
for j in range(0, mCols):
roi = img[i*sizeY/nRows:i*sizeY/nRows + sizeY/nRows ,j*sizeX/mCols:j*sizeX/mCols + sizeX/mCols]
cv2.imshow('rois'+str(i)+str(j), roi)
cv2.imwrite('patches/patch_'+str(i)+str(j)+".jpg", roi)
cv2.waitKey()

