编辑numpy数组图像重新缩放、裁剪、分割成马赛克块(大小不同),然后重新连接

jc3wubiy  于 2021-08-25  发布在  Java
关注(0)|答案(0)|浏览(341)

背景资料:
我正在开发一个神经网络模型来增强大学项目的图像。由于我希望该模型能够处理任意大小的图像,并且需要像素级的细节(无压缩或重缩放)和输入大小=输出大小,因此我的解决方案是将图像分成nxn块,并逐个输入,完成后重新组合图像。我遇到的第一个问题是,当nxn没有完全分割图像,我有剩余时,如何管理。 Like an image 640x426 and chunks of 58x58. On one side I get 640 Mod 58 =2px and the other 426 Mod 58 =20px. 我可以用纯黑色填充行/列的最后一块,但我立即放弃了这个想法,因为只有2行或列(58个数据中的2个)的实际数据,我认为nn做得不好。我首先想到并已经部分实现的解决方案是:最后一块是 image[ sizeY-chunk_size: sizeY, sizeX-chunk_size: sizeX] 基本上是与前一块部分重叠。当图像需要从马赛克拼合在一起时,只需丢弃重叠数据并添加剩余部分。
区块的大小与nxn ai相同,我想稍后尝试不同的维度,这样我可以看到获得良好结果的最小大小,以及训练和正常执行的速度如何根据区块大小进行放大。
问题是:
将图像分割为块的实现可分为4个部分:
图像尺寸模块块的大小有剩余和尺寸>大小,需要分割图像
图像尺寸模块块的大小有剩余和尺寸>大小,需要重新组装马赛克
图像尺寸<区块大小,需要分割图像
图像尺寸<块的大小,需要重新组装马赛克
分析和可能的解决办法:
对于第一个问题,我将在这里报告我的有效解决方案。我使用了数组拆分符号“:”。因为我也在使用scikit图像库,所以裁剪函数对于区块内的连续布局是否更好?
第二个问题是什么让我大开眼界,事实上,我关于最后一块重叠的想法无法很好地发挥作用。环顾四周,我发现了许多简单而快速的解决方案来重新组装图像,但它们都需要相同大小的块,或者它们不允许定义重叠区域,例如在3d上进行蒙太奇和重塑。考虑到图像26x22和块10x10,将图像分割成块,从块中删除区域重叠,并将所有部分连接在一起,我最终将得到: image_from_chunks=[[[10x10],[10x10],[10x2]] , [[10,10],[10x10],[10x2]] , [[6x10],[6x10],[6x2]]] .
因此,块的大小并不完全相同。
因为我唯一一次把这些片段放在一起是在它处理完块的时候,我不关心最终阵列的连续布局,它会在硬盘上保存为图像。我仍然需要找到解决办法。
我需要解决的第三个问题是,图像太小,无法在至少一个维度上容纳一个块。为此,我想我必须用纯黑色值扩展数组来填充块。ReZead允许这样做,并且设置值以填充空白空间,但是它将2D图像视为一维数组,因此例如在2x3中调整2x2大小将类似于: 2x2=[[1,2],[3,4]] 3x3=[[1,2,3],[4,0,0], [0,0,0]] what I want: 3x3=[[1,2,0],[3,4,0],[0,0,0]]. 如果可能,在4x4上,我希望图像居中,而不是从角落开始。
如果只有一面太小,而另一面太大,无法容纳一个块,那么第三个和第一个问题的组合就可以了,比如正确调整图像大小,然后将其切割成块。我仍然需要找到解决办法。
第四个问题只需正确剪切第三个问题中已调整大小的图像。
图像[0:image.shape[0],0:image.shape1]

请注意,这仅在图像的两个维度都小于块的大小时才起作用。所以,如果一个问题太大,第二个和第四个问题的组合可能会起作用。就像把所有的部分连接起来,然后按照原来的尺寸切割。我仍然需要找到问题二的解决方案来完成这项工作。

奖金问题:
这种具有重叠区域的分块方法是使nn能够对所有大小的图像进行细化的正确解决方案吗?我可以使用10kx10k的输入和输出来制作nn,以确保几乎所有图像都能正常工作,但这将是一个痛苦的训练,并且在没有高端计算机的情况下作为最终产品运行。
我的代码只是为了剪切图像

def splitter(image, shape, size):

# image=ndarray image

# shape=image.shape tuple

# size=height and width of the square chunk

# return=list of chunks of the mosaic original image

# list where the chunks will be saved

clear_chunks=[]

if(shape[0]<size or shape[1]<size):
    print("image too small")
    #TODO: implement resize to expand image

else:
    #get number of chunks for each axis
    Y_quantity=int(shape[0]/size + (1 if (shape[0]%size) else 0))
    X_quantity=int(shape[1]/size + (1 if (shape[1]%size) else 0))

    #iterate
    for Y in range(Y_quantity):
        for X in range(X_quantity):

            #calculating the edges offset of the chunk Y*X_quantity+X th

            if (X<X_quantity-1 and Y<Y_quantity-1):
                #base condition inside the limits
                tupleX= [X*size,(X+1)*size]
                tupleY= [Y*size,(Y+1)*size]
                #debug line to get coordinates of every chunk 
                #print(str(X_quantity*Y+X)+" normal    "+ str(Y*size)+":"+ str((Y+1)*size)+" , "+ str(X*size)+":"+ str((X+1)*size))

            else:#if division has reminder it doesn't fit properly and last chunk on the edge
                #search for not perfect fitting in the last row / column and replace the normal chunk edges
                #with the edges from the image_dimension to image_dimension-size
                tupleY= [shape[0]-size,shape[0]] if (shape[0]%size and Y==Y_quantity-1) else [Y*size,(Y+1)*size]
                tupleX= [shape[1]-size,shape[1]] if (shape[1]%size and X==X_quantity-1) else [X*size,(X+1)*size]
                #debug line to get coordinates of every chunk 
                #print(str(X_quantity*Y+X)+" special    "+ str(tupleY[0])+":"+ str(tupleY[1]) +" , "+ str(tupleX[0])+":"+ str(tupleX[1]))

            #once we have the 
            #check numpy.ndarray.resize
            clear_chunks.append(image[tupleY[0]:tupleY[1],tupleX[0]:tupleX[1]])

return clear_chunks
    #normal split: split from base+offset to base+offset+size_chunk
    #special split: check if last chunk is full contained, else the chunk will be sized [Ysize-chunk_size : Ysize],[Xsize-chunk_size : Xsize]

总之:
您是否有一个好的实现或库,可以让代码运行得更快、更高效,而不是将每个块中的每一个值强制放入一个新的空数组中,以便第二次重建类似马赛克的问题或第三次调整图像大小?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题