python - How to perform operations on every pixel of an image faster than using two for loops? -


i using following method perform operations on every pixel of image slow. takes around 110-120s on machine.

 i, j in product(xrange(15, width - 15), xrange(15, height - 15)):         # finding avg of 15x15 window         temp = image.crop((i - 7, j - 7, + 8, j + 8))         n = numpy.mean(list(temp.getdata()))          # calling 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 

what more efficient way this? keep in mind, operations require need coordinates of pixels because need pixel values of pixels @ position relative i,j

this simple solution can adapt problem. program loads, processes, , saves output series of files using multithreading. basically, split processing of images multiple threads would, ideally, process batches images in parallel. here split processing of .txt files named matrix_#.txt.

depending on details of problem may or may not speed code - may slow down, won't know until try it.

#!/usr/bin/python2.7  import time import math import numpy np import threading  def process_matrix(pathm, namem, n0, nf):     """ operations applied each thread         it's range of files """     # pathm path files ending in /     # or \ depending on os. files have     # common name namem .txt extension     # , numbers go 0 nf     in range(n0,nf+1):         # load numpy arrays         in_name = pathm + namem + str(i) + '.txt'         temp = np.loadtxt(in_name)         # initialize array results         res = np.zeros(3)         # send function processes data         res = processed(temp)         # save output         out_name =  pathm + 'out_' + namem + str(i) + '.txt'         np.savetxt(out_name, res)  def processed(m):     """ function example operations         on data """     # add simulate processing time     time.sleep(20)     # actual simple operations      res = np.zeros(3)     res[0] = np.mean(m)     res[1] = np.amax(m)     res[2] = np.amin(m)     return res  # time - @ least optimize thread number start = time.time()  # array thread objects threads = [] # number of threads num_threads = 10 # number of files process num_files = 10 # "increment" each thread dnth = math.floor(num_files/num_threads)  # distribute processing across threads ith in range(0,num_threads):     # lower limit file names given thread     low_lim = int(ith*dnth+1)     # upper limit file names (last thread gets until      # end)     up_lim = int(num_files) if (ith == num_threads-1) else int((ith+1)*dnth)     # start thread , append resulting thread object     # threads list     thread = threading.thread(target=process_matrix,              args=('/users/atru/research/stack/multi_matrix/', 'matrix_',              low_lim, up_lim))     threads.append(thread)     thread.start()  # allows program wait until # threads finish execution (i.e. reach point) t in threads:     t.join()  # measure execution time , print end = time.time() print(end - start) 

this strategy worked great me once, processing speed 10 times 14 threads (the system had 6-8 processors number ok). double checked performance today. particular program has 10 times speed 10 threads when ran on 10 relatively small files on 2 core, 4 thread processor. since program pausing instead of processing may not best scenario, when running should check how performs more reasonable number of threads 2 or 4.

it may not work intended, due various overheads , ram issues (if 1 file half of ram if 2 threads open 2 files ram getting full)- since processing takes 2 min seems similar problem, successful.

let me know if have questions.


Comments

Popular posts from this blog

What is happening when Matlab is starting a "parallel pool"? -

angular - DownloadURL return null in below code -

php - Cannot override Laravel Spark authentication with own implementation -