3
\$\begingroup\$

I am learning Theano to accelerate my image processing functions. As a start, I am trying to reimplement the function to turn images from colors to black and white (with the same number of channels): http://www.marcogiordanotd.com/blog/python/image-processing-pycuda . The author wants to show how efficient it is to do it using CUDA.

I want to do the same using OpenCL and an AMDGPU. My installation worked fine and I passed the test from http://deeplearning.net/software/theano/tutorial/using_gpu.html# successfully.

However I am dumbfunded by the result: my numpy implementation of the black and white function is faster than Theano's. Note I couldn't help but vectorizing the "blackWhite" function from above-mentioned author: he was using for loops to do matrix calculations...

my code is as follows, if you want to test it you need to change inPath to the path of a colorful image under if __name__=='__main__':

from PIL import Image
import time
import os
#import pycuda.driver as cuda
#import pycuda.autoinit
#from pycuda.compiler import SourceModule
from theano import function, config, shared, tensor
import numpy as np

#
def blackWhite(inPath , outPath , mode = "luminosity",log = 0):

    if log == 1 :
        print ("----------> SERIAL CONVERSION")
    totalT0 = time.time()

    im = Image.open(inPath)
    px = np.array(im)

    getDataT1 = time.time()

    print ("-----> Opening path :" , inPath)

    processT0 =  time.time()
    if mode == 'luminosity':
        px=np.rollaxis(np.tile(np.dot(px,(0.21,0.71,0.07)).astype('uint8'),(3,1,1)),0,3)
    else:
        px=np.rollaxis(np.tile(np.dot(px,(1/3,1/3,1/3)).astype('uint8'),(3,1,1)),0,3)

    processT1= time.time()
    #px = np.array(im.getdata())
    im = Image.fromarray(px)
    im.save(outPath)

    print ("-----> Saving path :" , outPath)
    totalT1 = time.time()

    if log == 1 :
        print ("Image size : ",im.size)
        print ("get and convert Image data  : " ,getDataT1-totalT0 )
        print ("Processing data : " , processT1 - processT0 )
        print ("Save image time : " , totalT1-processT1)
        print ("total  Execution time : " ,totalT1-totalT0 )
        print ("\n")

def TheanoBlackWhite(inPath, outPath, mode = "luminosity" , log = 0):
    if log == 1 :
        print ("----------> THEANO CONVERSION")
    totalT0 = time.time()

    im = Image.open(inPath)
    px = np.array(im)

    getDataT1 = time.time()

    print ("-----> Opening path :" , inPath)

    processT0 =  time.time()
    x = shared(px)

    if mode == 'luminosity':
        weights = shared(np.array([0.21,0.71,0.07]))
    else:
        weights = shared(np.array([1/3,1/3,1/3]))
    f = function([], tensor.tile(tensor.dot(x,weights),(3,1,1)).dimshuffle((1,2,0)))

    px=f()

    processT1= time.time()
    im = Image.fromarray(px.astype('uint8'))
    im.save(outPath)

    print ("-----> Saving path :" , outPath)
    totalT1 = time.time()
    if np.any([isinstance(x.op, tensor.Elemwise) and
              ('Gpu' not in type(x.op).__name__)
              for x in f.maker.fgraph.toposort()]):
        print('Used the cpu')
    else:
        print('Used the gpu')
    if log == 1 :
        print ("Image size : ",im.size)
        print ("get and convert Image data  : " ,getDataT1-totalT0 )
        print ("Processing data : " , processT1 - processT0 )
        print ("Save image time : " , totalT1-processT1)
        print ("total  Execution time : " ,totalT1-totalT0 )
        print ("\n")

if __name__=='__main__':
    lim = os.listdir(path=r'./train_sample')
    inPath = os.path.join(r'./train_sample',lim[0])#just first image
    blackWhite(inPath, 'out_np.jpg', mode = "luminosity" , log = 1)
    TheanoBlackWhite(inPath, 'out_theano.jpg', mode = "luminosity" , log = 1)

result:

----------> SERIAL CONVERSION
-----> Opening path : ./train_sample/e04e300c909046d8.jpg
-----> Saving path : out_np.jpg
Image size :  (1600, 1200)
get and convert Image data  :  0.03160548210144043
Processing data :  0.06990170478820801
Save image time :  0.08301019668579102
total  Execution time :  0.18471074104309082


----------> THEANO CONVERSION
-----> Opening path : ./train_sample/e04e300c909046d8.jpg
-----> Saving path : out_theano.jpg
Used the cpu
Image size :  (1600, 1200)
get and convert Image data  :  0.03149127960205078
Processing data :  0.13131022453308105
Save image time :  0.06376218795776367
total  Execution time :  0.2267618179321289
\$\endgroup\$
2
  • \$\begingroup\$ (I was under the impression that CUDA run-times depend on driver quality and heavily on the hardware used.) \$\endgroup\$
    – greybeard
    Mar 10, 2018 at 14:00
  • \$\begingroup\$ You are certainly right. I believe for this particular task, my CPU was fast enough. It would be nice to try on 100 images at the same time but I have no idea how to do that. \$\endgroup\$
    – Wli
    Mar 10, 2018 at 18:44

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.