I have the following source code in main.py
main.py
import data_utils as du
X_train1, Y_train1, groundtruth_train1= du.loaddata(train_file, "adjust_gamma", 0.8)
X_train2, Y_train2, groundtruth_train2= du.loaddata(train_file, "adjust_gamma", 1.2)
X_train3, Y_train3, groundtruth_train3= du.loaddata(train_file, "scale_image", 0.5)
X_train4, Y_train4, groundtruth_train4= du.loaddata(train_file, "scale_image", 0.8)
X_train5, Y_train5, groundtruth_train5= du.loaddata(train_file, "scale_image", 1.5)
X_train6, Y_train6, groundtruth_train6= du.loaddata(train_file, "scale_image", 2.0)
X_train7, Y_train7, groundtruth_train7= du.loaddata(train_file, "compress_jpeg", 70)
X_train8, Y_train8, groundtruth_train8= du.loaddata(train_file, "compress_jpeg", 90)
main.py will read several images, apply image transformations, divide them into blocks (these are my X_train outputs) and get the images labels (Y_train and groundtruth_train). The image transform is defined by a string with parameters (e.g., "adjust_gamma", etc.).
Now, load_data.py was built inspired on this answer about how to pass functions with arguments to another function
data_utils.py
def loaddata(file_images, function_name, parameter):
x = []
y = []
with open(file_images) as f:
images_names = f.readlines()
images_names = [a.strip() for a in images_names]
j=0
for line in images_names:
j=j+1
line='image_folder/' + line
img = cv2.imread(img_path)
img=perform(eval(function_name)(img,parameter))
...
The function performs will receive the function name (as string as you can see in the main.py) and its parameters (image in numpy array and parameters). The function performed is detailed below:
def perform(fun, *args):
fun(*args)
def adjust_gamma(image, gamma):
invGamma = 1.0 / gamma
table = np.array([((i / 255.0) ** invGamma) * 255
for i in np.arange(0, 256)]).astype("uint8")
return cv2.LUT(image, table)
def compress_jpeg(image, compression_factor):
encode_param=[int(cv2.IMWRITE_JPEG_QUALITY), compression_factor]
result, encimg=cv2.imencode('.jpg', image, encode_param)
decimg=cv2.imdecode(encimg, 1)
return decimg
def scale_image(image, scaling_factor):
resized_image=cv2.resize(image, (scaling_factor, scaling_factor))
return resized_image
I tried to use eval function so the string passed could be regarded as a function name(This answer inspired me to do that). However, when I run the code I get the following error:
File "main.py", line 32, in do_experiment
X_train1, Y_train1, groundtruth_train1= du.loaddata(train_file, "adjust_gamma", 0.8)
File "data_utils.py", line 29, in loaddata
img=perform(eval(function_name)(img,parameter)) File "data_utils.py",
line 171, in perform fun(**args) TypeError: 'numpy.ndarray' object is not callable
So, how can I solve my problem? how can I pass a function as arguments to another function by using the function name as a string?