如何比使用两个for循环更快地对图像的每个像素执行操作?

时间:2017-08-18 18:49:31

标签: python image opencv iteration python-imaging-library

我使用以下方法对图像的每个像素执行操作,但速度太慢。在我的机器上大约需要110-120秒左右。

 for i, j in product(xrange(15, width - 15), xrange(15, height - 15)):
        # finding the avg of 15x15 window
        temp = image.crop((i - 7, j - 7, i + 8, j + 8))
        N = numpy.mean(list(temp.getdata()))

        # calling the functions
        avg0_3,avg0_5,avg0_7,avg0_9,avg0_11,avg0_13,avg0_15 = angle_0(7, 7, temp)
        avg15_3,avg15_5,avg15_7,avg15_9,avg15_11,avg15_13,avg15_15 = angle_15(7, 7, temp)
        avg30_3,avg30_5,avg30_7,avg30_9,avg30_11,avg30_13,avg30_15 = angle_30(7, 7, temp)
        avg45_3,avg45_5,avg45_7,avg45_9,avg45_11,avg45_13,avg45_15 = angle_45(7, 7, temp)
        avg60_3,avg60_5,avg60_7,avg60_9,avg60_11,avg60_13,avg60_15 = angle_60(7, 7, temp)
        avg75_3,avg75_5,avg75_7,avg75_9,avg75_11,avg75_13,avg75_15 = angle_75(7, 7, temp)
        avg90_3,avg90_5,avg90_7,avg90_9,avg90_11,avg90_13,avg90_15 = angle_90(7, 7, temp)

        avg105_3,avg105_5,avg105_7,avg105_9,avg105_11,avg105_13,avg105_15 = angle_105(7, 7, temp)
        avg120_3,avg120_5,avg120_7,avg120_9,avg120_11,avg120_13,avg120_15 = angle_120(7, 7, temp)
        avg135_3,avg135_5,avg135_7,avg135_9,avg135_11,avg135_13,avg135_15 = angle_135(7, 7, temp)
        avg150_3,avg150_5,avg150_7,avg150_9,avg150_11,avg150_13,avg150_15 = angle_150(7, 7, temp)
        avg165_3,avg165_5,avg165_7,avg165_9,avg165_11,avg165_13,avg165_15 = angle_165(7, 7, temp)

        # largest grey level lines (L3,L5,L7,L9,L11,L13,L15)
        L3 = max(avg0_3, avg15_3, avg30_3, avg45_3, avg60_3, avg75_3, avg90_3, avg105_3, avg120_3, avg135_3, avg150_3, avg165_3)
        L5 = max(avg0_5, avg15_5, avg30_5, avg45_5, avg60_5, avg75_5, avg90_5, avg105_5, avg120_5, avg135_5, avg150_5,avg165_5)
        L7 = max(avg0_7, avg15_7, avg30_7, avg45_7, avg60_7, avg75_7, avg90_7, avg105_7, avg120_7, avg135_7, avg150_7,avg165_7)
        L9 = max(avg0_9, avg15_9, avg30_9, avg45_9, avg60_9, avg75_9, avg90_9, avg105_9, avg120_9, avg135_9, avg150_9,avg165_9)
        L11 = max(avg0_11, avg15_11, avg30_11, avg45_11, avg60_11, avg75_11, avg90_11, avg105_11, avg120_11, avg135_11, avg150_11,avg165_11)
        L13 = max(avg0_13, avg15_13, avg30_13, avg45_13, avg60_13, avg75_13, avg90_13, avg105_13, avg120_13, avg135_13, avg150_13,avg165_13)
        L15 = max(avg0_15, avg15_15, avg30_15, avg45_15, avg60_15, avg75_15, avg90_15, avg105_15, avg120_15, avg135_15, avg150_15,avg165_15)

        '''
        # largest grey level orthognal line
        L2 = max(avgorth0, avgorth15, avgorth30, avgorth45, avgorth60, avgorth75, avgorth90, avgorth105, avgorth120,
             avgorth135, avgorth150, avgorth165)
        strength2 = L2 - N
        '''
        # line strengths of lines (L3,L5,L7,L9,L11,L13,L15)

        strength3 = L3 - N
        strength5 = L5 - N
        strength7 = L7 - N
        strength9 = L9 - N
        strength11 = L11 - N
        strength13 = L13 - N
        strength15 = L15 - N


        S3.append(strength3)
        S5.append(strength5)
        S7.append(strength7)
        S9.append(strength9)
        S11.append(strength11)
        S13.append(strength13)
        S15.append(strength15)
        #S2.append(strength2)
        p = image.getpixel((i,j))
        I.append(p)
        R = (strength3 + strength5 + strength7 + strength9 + strength11 + strength13 + strength15 + p) * 0.125
        R_comb.append(R)
        result.putpixel((i, j), R)

def angle_0(i, j, image):


sum3 = image.getpixel(((i - 1), j)) + image.getpixel((i, j)) + image.getpixel(((i + 1), j))
sum5 = image.getpixel(((i - 2), j)) + sum3 + image.getpixel(((i + 2), j))
sum7 = image.getpixel(((i - 3), j)) + sum5 + image.getpixel(((i + 3), j))
sum9 = image.getpixel(((i - 4), j)) + sum7 + image.getpixel(((i + 4), j))
sum11= image.getpixel(((i - 5), j)) + sum9 + image.getpixel(((i + 5), j))
sum13= image.getpixel(((i - 6), j)) + sum11+ image.getpixel(((i + 6), j))
sum15= image.getpixel(((i - 7), j)) + sum13+ image.getpixel(((i + 7), j))

avg_sum3 = sum3 / 3
avg_sum5 = sum5 / 5
avg_sum7 = sum7 / 7
avg_sum9 = sum9 / 9
avg_sum11 = sum11 / 11
avg_sum13 = sum13 / 13
avg_sum15 = sum15 / 15

return avg_sum3,avg_sum5,avg_sum7,avg_sum9,avg_sum11,avg_sum13,avg_sum15

更有效的方法是什么? 请记住,我的操作要求我需要像素的坐标,因为我还需要像素值,这些像素位于相对于i的位置,j

1 个答案:

答案 0 :(得分:0)

这是一个简单的解决方案,您可以适应您的问题。该程序使用多线程加载,处理和保存一系列文件的输出。基本上,您可以将图像处理拆分为多个线程,理想情况下,这些线程将并行处理批量图像。在这里,我分割了一些名为.txt的{​​{1}}文件的处理。

根据您的问题的详细信息,这可能会或可能不会加快您的代码速度 - 它甚至可能会降低速度,但在您尝试之前,您不会真正了解它。

Matrix_#.txt

这个策略对我来说很有用,处理速度提高了10倍,有14个线程(系统有6-8个处理器,所以数量还可以)。我今天再次检查了性能。当在2核4线程处理器上运行10个相对较小的文件时,这个特定程序的速度提高了近10倍,10个线程。由于程序暂停而不是处理,这可能不是最佳方案,在运行时,您还应该检查它如何使用更合理数量的线程(如2或4)执行。

由于各种开销和RAM问题(如果你的一个文件是RAM的一半,那么如果两个线程打开两个文件你的RAM已经满了)它也可能无法按预期工作 - 但是因为你的处理需要2分钟似乎与我的问题类似,这是成功的。

如果您有疑问,请告诉我。