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
Post a Comment