Numpy-如何在OpenCV python中迭代创建ROI?

时间:2016-07-18 09:58:28

标签: python opencv numpy

我正在尝试将图像分割成较小图像的网格,以便我可以分别处理每个小图像。为此,我意识到我必须将每个小图像定义为ROI,我可以从那里轻松使用它。

现在,我的网格尺寸不固定。即,如果用户输入5,我必须制作5x5的网格。

逐个像素地迭代图像会很慢,所以我决定使用Numpy通过使用这个结构来创建ROI:

#Assuming user entered grid size =5
roiwidth=w/5
roiheight=h/5   
roi0=img[0:roiheight,0:roiwidth]

这将是我的第一片。 h和w分别是图像的高度和宽度。对于下一个切片,我必须这样做:

roi1=img[0:roiheight,roiwidth+1:2*roiwidth]   

虽然我的最后一次活动将是:

roi25=img[4*roiheight+1:5*roiheight, 4*roiwidth+1:5*roiwidth]

但我需要迭代地做,并且无法找出正确的方法来做到这一点。我不想逐个像素地迭代图像,需要它是动态的

编辑:我现在正在迭代:

import cv2
import numpy

img=cv2.imread('01.jpg')
h,w,chan=img.shape
rh=h/5
rw=w/5
z={}
count=0
for i in range (0,5):
    for j in range (0,5):
        yl=i*rh
        yh=(i+1)*rh
        xl=j*rw
        xh=(j+1)*rw
        z[count]=img[yl:yh,xl:xh]
        count=count+1

但我不知道这是否是最有效的方式。

2 个答案:

答案 0 :(得分:3)

如果您想使用Numpy功能分割图像,请查看numpy.array_split

在你的情况下你会写这样的东西:

z = {}
count = 0
split1 = np.array_split(img, rh)
for sub in split1:
    split2 = np.array_split(sub, rw, 1)
    for sub2 in split2:
        z[count] = sub2
        count++

答案 1 :(得分:2)

为了提高效率,下面列出的是使用重塑和置换维度的矢量化方法。

1)让我们定义输入参数和设置输入:

M = 5 # Number of patches along height and width
img_slice = img[:rh*M,:rw*M] # Slice out valid image data

2)主要处理部分来到这里。拆分切片图像的前两个轴,这样我们通过重新整形创建两个长度为M的新轴。因此,剩下的两个轴将代表窗口(rh x rw)。我们的最终目标是让它们彼此相邻,以便给我们(rh,rw)补丁,因此其他两个分裂轴也会彼此相邻。为此,我们需要使用np.transpose置换维度。在置换之后,我们重新整形以合并长度为(M,M)的两个维度,以便最终得到一个长度为M^2的轴,每个轴的元素将代表图像中的一个窗口。

所以,最后我们会:

z = img_slice.reshape(M,rh,M,rw,-1).transpose(0,2,1,3,4).reshape(M**2,rh,rw,-1)

这为我们提供了沿第一轴具有M^2个元素的NumPy数组。沿着该轴的每个切片将对应于每个窗口/贴片。因此,z[0]将是左上角的补丁,依此类推。