WxPython Resize an Image using GridBagSizer - user-interface

I am sorry if this is too simple... I tried to add a logo to my first GUI, however, I am not sure what is the best way to resize it. At this moment, I am using image.Scale to adjust the logo size and place GridBagSizer.
self.image = wx.Image("logo11w.png", wx.BITMAP_TYPE_ANY)
w = self.image.GetWidth()
h = self.image.GetHeight()
self.image = self.image.Scale(w/8, h/8)
self.sb1 = wx.StaticBitmap(self.panel, -1, wx.BitmapFromImage(self.image))
self.sizer.Add(self.sb1, pos=(0, 0), flag=wx.TOP|wx.LEFT|wx.BOTTOM, border=15)
.
I am wondering if there is an auto way to do this? Since I am using GridBagSizer, is it possible to leave one "grid" (e.g., 1 by 1 "box") for my logo? Thanks in advance!
Code:
import wx
class landing_frame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(800, 600), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.font1 = wx.Font(18, wx.DECORATIVE, wx.ITALIC, wx.BOLD)
self.InitUI()
self.Centre()
self.Show()
def InitUI(self):
self.panel = wx.Panel(self)
self.sizer = wx.GridBagSizer(5, 15)
self.image = wx.Image("logo11w.png", wx.BITMAP_TYPE_ANY)
w = self.image.GetWidth()
h = self.image.GetHeight()
self.image = self.image.Scale(w/8, h/8)
self.sb1 = wx.StaticBitmap(self.panel, -1, wx.BitmapFromImage(self.image))
self.sizer.Add(self.sb1, pos=(0, 0), flag=wx.TOP|wx.LEFT|wx.BOTTOM, border=15)
self.text1 = wx.StaticText(self.panel, label="Welcome!")
self.sizer.Add(self.text1, pos=(0, 2), flag=wx.TOP|wx.LEFT|wx.BOTTOM, border=15)
line = wx.StaticLine(self.panel)
self.sizer.Add(line, pos=(1, 0), span=(1, 5), flag=wx.EXPAND|wx.BOTTOM, border=10)
self.text2 = wx.StaticText(self.panel, label="Question 1?")
self.sizer.Add(self.text2, pos=(2, 0), flag=wx.ALL, border=10)
self.sampleList = ['Op1', 'Op2', 'Op3']
self.combo = wx.ComboBox(self.panel, 10, choices=self.sampleList)
self.sizer.Add(self.combo, pos=(2, 1), span=(1, 5), flag=wx.EXPAND|wx.ALL, border=10)
self.input1 = wx.StaticText(self.panel, 11, label="Please Enter Filepath")
self.sizer.Add(self.input1, pos=(3, 0), span=(1, 1), flag=wx.ALL , border=10)
self.input2 = wx.FilePickerCtrl(self.panel, 12, wx.EmptyString, u"Select a file", u"*.*", wx.DefaultPosition, wx.DefaultSize, wx.FLP_DEFAULT_STYLE )
self.sizer.Add(self.input2, pos=(3, 1), span=(1, 20), flag=wx.EXPAND|wx.ALL, border=10)
self.input3 = wx.StaticText(self.panel, 13, label="Additional inputs")
self.sizer.Add(self.input3, pos=(4, 0), flag=wx.ALL , border=10)
self.input4 = wx.TextCtrl(self.panel, 14, 'E.g. ...', wx.DefaultPosition, wx.DefaultSize, 0, wx.DefaultValidator )
self.sizer.Add(self.input4, pos=(4, 1), span=(1, 10), flag=wx.EXPAND|wx.ALL, border=10)
self.panel.SetSizer(self.sizer)
if __name__ == '__main__':
app = wx.App(redirect=False, filename="mylogfile.txt")
landing_frame(None, title="Test")
app.MainLoop()
Here is the logo

Related

VGG16 Custom Activation Function used in ResNet function

Here's my code:
import os
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
import tensorflow as tf
from tensorflow import keras
from keras import layers
from keras.datasets import cifar10
from sklearn.model_selection import train_test_split
import numpy as np
import matplotlib.pyplot as plt
def main():
#loading data and image augmentation
(X_train, Y_train), (X_test, Y_test) = keras.datasets.cifar10.load_data()
X_train, X_val, Y_train, Y_val = train_test_split(X_train, Y_train, test_size=0.20, random_state=42)
X_test, X_train, X_val = X_test.astype("float32"), X_train.astype("float32"), X_val.astype("float32")
Y_train, Y_test, Y_val = keras.utils.to_categorical(Y_train, 10), keras.utils.to_categorical(Y_test, 10), keras.utils.to_categorical(Y_val, 10)
datagen = keras.preprocessing.image.ImageDataGenerator(rotation_range=15, width_shift_range=0.1, height_shift_range=0.1, horizontal_flip=True)
datagen.fit(X_train)
X_train = X_train.reshape(X_train.shape[0], 32, 32, 3)
X_test = X_test.reshape(X_test.shape[0], 32, 32, 3)
X_val = X_val.reshape(X_val.shape[0], 32, 32, 3)
mean = np.mean(X_train)
std = np.std(X_train)
X_test = (X_test - mean) / std
X_val = (X_val - mean) / std
X_train = (X_train - mean) / std
#constructing ResNet function
def residual_module(layer_in, n_filters, kernel_size, padding, initializer, activation, regularizer, triple=False):
activation2 = 'linear'
filters2 = layer_in.shape[-1]
size2 = 1
conv1 = layers.Conv2D(n_filters, kernel_size, padding=padding, kernel_initializer=initializer, kernel_regularizer=regularizer)(layer_in)
conv1 = layers.Activation(activation)(conv1)
batch1 = layers.BatchNormalization()(conv1)
conv2 = layers.Conv2D(filters2, size2, padding='same', kernel_regularizer=regularizer)(batch1)
conv2 = layers.Activation(activation2)(conv2)
batch2 = layers.BatchNormalization()(conv2)
if triple == True:
activation2 = activation
filters2 = n_filters
size2 = kernel_size
conv3 = layers.Conv2D(layer_in.shape[-1], 1, padding='same', activation='linear', kernel_regularizer=regularizer)(batch2)
batch3 = layers.BatchNormalization()(conv3)
layer_out = layers.add([batch3, layer_in])
layer_out = layers.Activation(activation)(layer_out)
else:
layer_out = layers.add([batch2, layer_in])
layer_out = layers.Activation(activation)(layer_out)
return layer_out
#VGG16 model with SIREN
weight_decay = 0.0005
model = keras.Sequential()
input_layer = layers.Input(shape=(32,32,3))
model.add(residual_module(input_layer, n_filters=64, kernel_size=(3,3), padding='same', initializer="he_uniform", activation=tf.math.sin, regularizer=keras.regularizers.l2(weight_decay)))
first = model.add(layers.MaxPooling2D(pool_size=(2, 2), strides=2))
model.add(residual_module(first, 128, (3,3), 'same', None, tf.math.sin, keras.regularizers.l2(weight_decay)))
second = model.add(layers.MaxPooling2D(pool_size=(2, 2), strides=2))
model.add(residual_module(second, 256, (3,3), 'same', None, tf.math.sin, keras.regularizers.l2(weight_decay), triple=True))
third = model.add(layers.MaxPooling2D(pool_size=(2, 2), strides=2))
model.add(residual_module(third, 512, (3,3), 'same', None, tf.math.sin, keras.regularizers.l2(weight_decay), triple=True))
model.add(layers.MaxPooling2D(pool_size=(2, 2), strides=2))
model.add(layers.GlobalAveragePooling2D())
model.add(layers.Dense(4096, activation="relu"))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(4096, activation="relu"))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(10))
'''
model.add(layers.Conv2D(64, (3, 3), padding='same', kernel_initializer="he_uniform", activation=tf.math.sin, input_shape=(32,32,3), kernel_regularizer=keras.regularizers.l2(weight_decay)))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(64, (3, 3), padding='same', activation=math.sin, kernel_regularizer=keras.regularizers.l2(weight_decay)))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D(pool_size=(2, 2), strides=2))
model.add(layers.Conv2D(128, (3, 3), padding='same', activation=math.sin, kernel_regularizer=keras.regularizers.l2(weight_decay)))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(128, (3, 3), padding='same', activation=math.sin, kernel_regularizer=keras.regularizers.l2(weight_decay)))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D(pool_size=(2, 2), strides=2))
model.add(layers.Conv2D(256, (3, 3), padding='same', activation=math.sin, kernel_regularizer=keras.regularizers.l2(weight_decay)))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(256, (3, 3), padding='same', activation=math.sin, kernel_regularizer=keras.regularizers.l2(weight_decay)))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(256, (3, 3), padding='same', activation=math.sin, kernel_regularizer=keras.regularizers.l2(weight_decay)))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D(pool_size=(2, 2), strides=2))
model.add(layers.Conv2D(512, (3, 3), padding='same', activation=math.sin, kernel_regularizer=keras.regularizers.l2(weight_decay)))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(512, (3, 3), padding='same', activation=math.sin, kernel_regularizer=keras.regularizers.l2(weight_decay)))
model.add(layers.BatchNormalization())
model.add(layers.Conv2D(512, (3, 3), padding='same', activation=math.sin, kernel_regularizer=keras.regularizers.l2(weight_decay)))
model.add(layers.BatchNormalization())
model.add(layers.MaxPooling2D(pool_size=(2, 2), strides=2))
model.add(layers.GlobalAveragePooling2D())
model.add(layers.Dense(4096, activation="relu"))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(4096, activation="relu"))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(10))
'''
#training model
lr = 0.001
loss = keras.losses.CategoricalCrossentropy(from_logits=True)
decayed_lr = tf.keras.optimizers.schedules.ExponentialDecay(lr, 10000, 0.85, True)
optim = keras.optimizers.SGD(decayed_lr, momentum=0.9, nesterov=True)
batch_size = 128
#optim = keras.optimizers.Adam(decayed_lr, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
model.compile(loss=loss, optimizer=optim, metrics=["accuracy"])
checkpoint_filepath = '/Users/JamesRONewton/Documents/Programming/MachineLearning/SIREN_projects/BrainTumor/checkpoint.hdf5'
checkpoint = keras.callbacks.ModelCheckpoint(filepath = checkpoint_filepath, monitor='accuracy', verbose=2, save_best_only=True, save_weights_only=True, mode='auto', save_freq ="epoch")
try:
model.load_weights(checkpoint_filepath, custom_objects = {"sin": tf.math.sin})
except Exception as e:
pass
model.fit(datagen.flow(X_train, Y_train, batch_size=batch_size), steps_per_epoch = len(X_train) / batch_size, epochs=25, callbacks = [checkpoint], validation_data=(X_val, Y_val))
model.evaluate(X_test, Y_test, verbose=1)
#saving model
model.save("VGG16.h5")
if __name__ == '__main__':
main()
And here's the error I keep getting:
TypeError: The added layer must be an instance of class Layer. Received: layer=KerasTensor(type_spec=TensorSpec(shape=(None, 32, 32, 3), dtype=tf.float32, name=None), name='activation_2/Sin:0', description="created by layer 'activation_2'") of type <class 'keras.engine.keras_tensor.KerasTensor'>.
The errors so far have mostly been about inputting a custom activation function into the ResNet function I created. For example,
TypeError: The added layer must be an instance of class Layer. Received: layer=KerasTensor(type_spec=TensorSpec(shape=(None, 32, 32, 3), dtype=tf.float32, name=None), name='activation/Sin:0', description="created by layer 'activation'") of type <class 'keras.engine.keras_tensor.KerasTensor'>.
So I thought maybe using
layers.Activation(activation)
instead of just putting the activation in the Conv2D layer would fix it, but that clearly did not work, as you can see. I've also tried defining the custom activation function as a class inheriting from layers.Layer, but that also did not work. I used this code to try that:
class Sin(layers.Layer):
def __init__(self, **kwargs):
super(Sin, self).__init__(**kwargs)
def call(self, inputs):
return tf.math.sin(inputs)
But alas, it did not work.
-Update!
I tried using keras backend, but that failed. I also tried using a lambda layer in my ResNet function. Here's my most recent attempt, which combines both:
#custom sinusoidal activation function
def sin(x):
return K.sin(x)
#constructing ResNet function
def residual_module(layer_in, n_filters, kernel_size, padding, initializer, regularizer):
conv1 = layers.Conv2D(n_filters, kernel_size, padding=padding, kernel_initializer=initializer, kernel_regularizer=regularizer)(layer_in)
conv1 = layers.Lambda(lambda x: sin(x))(conv1)
batch1 = layers.BatchNormalization()(conv1)
conv2 = layers.Conv2D(layer_in.shape[-1], 1, padding='same', activation='linear', kernel_regularizer=regularizer)(batch1)
batch2 = layers.BatchNormalization()(conv2)
layer_out = layers.add([batch2, layer_in])
layer_out = layers.Lambda(lambda x: sin(x))(layer_out)
return layer_out
def residual_module_triple(layer_in, n_filters, kernel_size, padding, initializer, regularizer):
conv1 = layers.Conv2D(n_filters, kernel_size, padding=padding, kernel_initializer=initializer, kernel_regularizer=regularizer)(layer_in)
conv1 = layers.Lambda(lambda x: sin(x))(conv1)
batch1 = layers.BatchNormalization()(conv1)
conv2 = layers.Conv2D(n_filters, kernel_size, padding='same', kernel_regularizer=regularizer)(batch1)
conv2 = layers.Lambda(lambda x: sin(x))(conv2)
batch2 = layers.BatchNormalization()(conv2)
conv3 = layers.Conv2D(layer_in.shape[-1], 1, padding='same', activation='linear', kernel_regularizer=regularizer)(batch2)
batch3 = layers.BatchNormalization()(conv3)
layer_out = layers.add([batch3, layer_in])
layer_out = layers.Lambda(lambda x: sin(x))(layer_out)
return layer_out
I got it up and working so I can resume training!! Here's my fixed code:
def main():
import os
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
import tensorflow as tf
from tensorflow import keras
from keras import layers
from keras.datasets import cifar10
from sklearn.model_selection import train_test_split
import numpy as np
import matplotlib.pyplot as plt
from keras import backend as K
#loading data and image augmentation
(X_train, Y_train), (X_test, Y_test) = keras.datasets.cifar10.load_data()
X_train, X_val, Y_train, Y_val = train_test_split(X_train, Y_train, test_size=0.20, random_state=42)
X_test, X_train, X_val = X_test.astype("float32"), X_train.astype("float32"), X_val.astype("float32")
Y_train, Y_test, Y_val = keras.utils.to_categorical(Y_train, 10), keras.utils.to_categorical(Y_test, 10), keras.utils.to_categorical(Y_val, 10)
datagen = keras.preprocessing.image.ImageDataGenerator(rotation_range=15, width_shift_range=0.1, height_shift_range=0.1, horizontal_flip=True)
datagen.fit(X_train)
X_train = X_train.reshape(X_train.shape[0], 32, 32, 3)
X_test = X_test.reshape(X_test.shape[0], 32, 32, 3)
X_val = X_val.reshape(X_val.shape[0], 32, 32, 3)
mean = np.mean(X_train)
std = np.std(X_train)
X_test = (X_test - mean) / std
X_val = (X_val - mean) / std
X_train = (X_train - mean) / std
#custom sinusoidal activation function
class sin(layers.Layer):
def __init__(self, **kwargs):
super(sin, self).__init__(**kwargs)
def call(self, inputs, **kwargs):
return K.sin(inputs)
#constructing ResNet function
def residual_module(layer_in, n_filters, kernel_size, padding, initializer, regularizer):
inputs = layer_in
conv1 = layers.Conv2D(n_filters, kernel_size, padding=padding, kernel_initializer=initializer, kernel_regularizer=regularizer)(layer_in)
conv1 = layers.Lambda(lambda x: sin()(x))(conv1)
batch1 = layers.BatchNormalization()(conv1)
conv2 = layers.Conv2D(layer_in.shape[-1], 1, padding='same', activation='linear', kernel_regularizer=regularizer)(batch1)
batch2 = layers.BatchNormalization()(conv2)
layer_out = layers.add([batch2, inputs])
layer_out = layers.Lambda(lambda x: sin()(x))(layer_out)
return layer_out
def residual_module_triple(layer_in, n_filters, kernel_size, padding, initializer, regularizer):
inputs = layer_in
conv1 = layers.Conv2D(n_filters, kernel_size, padding=padding, kernel_initializer=initializer, kernel_regularizer=regularizer)(layer_in)
conv1 = layers.Lambda(lambda x: sin()(x))(conv1)
batch1 = layers.BatchNormalization()(conv1, training=True)
conv2 = layers.Conv2D(n_filters, kernel_size, padding='same', kernel_regularizer=regularizer)(batch1)
conv2 = layers.Lambda(lambda x: sin()(x))(conv2)
batch2 = layers.BatchNormalization()(conv2, training=True)
conv3 = layers.Conv2D(layer_in.shape[-1], 1, padding='same', activation='linear', kernel_regularizer=regularizer)(batch2)
batch3 = layers.BatchNormalization()(conv3, training=True)
layer_out = layers.add([batch3, inputs])
layer_out = layers.Lambda(lambda x: sin()(x))(layer_out)
return layer_out
#VGG16 model with SIREN
weight_decay = 0.0005
inputs = layers.Input(shape=(32,32,3))
x = residual_module(inputs, n_filters=64, kernel_size=(3,3), padding='same', initializer="he_uniform", regularizer=keras.regularizers.l2(weight_decay))
x = layers.MaxPooling2D(pool_size=(2, 2), strides=2)(x)
x = residual_module(x, 128, (3,3), 'same', None, keras.regularizers.l2(weight_decay))
x = layers.MaxPooling2D(pool_size=(2, 2), strides=2)(x)
x = residual_module_triple(x, 256, (3,3), 'same', None, keras.regularizers.l2(weight_decay))
x = layers.MaxPooling2D(pool_size=(2, 2), strides=2)(x)
x = residual_module_triple(x, 512, (3,3), 'same', None, keras.regularizers.l2(weight_decay))
x = layers.MaxPooling2D(pool_size=(2, 2), strides=2)(x)
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dense(4096, activation="relu")(x)
x = layers.Dropout(0.5)(x)
x = layers.Dense(4096, activation="relu")(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(10)(x)
model = keras.Model(inputs, outputs)
#training model
lr = 0.001
loss = keras.losses.CategoricalCrossentropy(from_logits=True)
decayed_lr = tf.keras.optimizers.schedules.ExponentialDecay(lr, 10000, 0.85, True)
optim = keras.optimizers.SGD(decayed_lr, momentum=0.9, nesterov=True)
batch_size = 128
model.compile(loss=loss, optimizer=optim, metrics=["accuracy"])
checkpoint_filepath = '/Users/JamesRONewton/Documents/Programming/MachineLearning/SIREN_projects/BrainTumor/checkpoint.hdf5'
checkpoint = keras.callbacks.ModelCheckpoint(filepath = checkpoint_filepath, monitor='accuracy', verbose=2, save_best_only=True, save_weights_only=True, mode='auto', save_freq ="epoch")
try:
model.load_weights(checkpoint_filepath, custom_objects = {"sin": tf.math.sin})
except Exception as e:
pass
model.fit(datagen.flow(X_train, Y_train, batch_size=batch_size), steps_per_epoch = len(X_train) / batch_size, epochs=25, callbacks = [checkpoint], validation_data=(X_val, Y_val))
model.evaluate(X_test, Y_test, verbose=1)
#saving model
model.save("VGG16.h5")
if __name__ == '__main__':
main()
Two issues with my code were causing the errors:
I found out that when I was adding a layer, it didn't return anything (e.g. "first" was just a NoneType), so I used "x" as the output of each variable and chained them together with the Model class.
I figured out how to modify the "sin" class I defined to accept multiple arguments. Also, I decided to pass a class function to the Lambda layer instead of a function because it kept passing the Tensor returned from function instead of the function itself.

Translate CNN from keras to pytorch

I need some help. I am trying to convert a CNN from keras to pytorch. I am reconstructing an MR image. The input is the image coming from the scanner in the fourier domain and the output is the reconstructed image. The input image has two channels (first channel: real part, second channel: imaginary part). Unfortunately, the results are quite different, so I believe I am doing something wrong. I just cannot find out myself what it is. Here is the keras code:
def AUTOMAP_Basic_Model(param):
fc_1 = keras.Input(shape=(64,64,2), name='input')
fc_2 = layers.Conv2D(64,(64,1),strides=1,padding='same',activation='relu')(fc_1)
fc_4 = layers.Conv2D(64,(1,64),strides=1,padding='same',activation='relu')(fc_2)
fc_4 = layers.Conv2D(64,(64,1),strides=1,padding='same',activation='relu')(fc_4)
fc_5 = layers.Conv2D(64,(1,64),strides=1,padding='same',activation='relu')(fc_4)
c_1 = layers.Conv2D(64,5,strides=1,padding='same',activation='relu')(fc_5)
c_2 = layers.Conv2D(64,5,strides=1,padding='same',activation='relu')(c_1)
c_3 = layers.Conv2DTranspose(1,7,strides=1,activation='sigmoid',padding='same')(c_2)
model = keras.Model(inputs = fc_1,outputs = c_3)
return model
And this is my translation to pytorch:
class AUTOMAP_Basic_Model(nn.Module):
def __init__(self, inputShape, nrFilters):
super(AUTOMAP_Basic_Model, self).__init__()
self.conv1 = nn.Conv2d(2, 64, (64,1), padding='same')
self.relu = nn.ReLU()
self.conv2 = nn.Conv2d(64, 64, (1,64), padding ='same')
self.conv3 = nn.Conv2d(64, 64, (64,1), padding='same')
self.conv4 = nn.Conv2d(64,64,5,padding='same')
self.conv5 = nn.Conv2d(64,64,5,padding='same')
self.convTranspose = nn.ConvTranspose2d(64,1,7,padding=3,output_padding=0)
self.sigmoid = nn.Sigmoid()
self.tan = nn.Tanh()
def forward(self, x):
batch_size = len(x)
out = self.conv1(x)
out = self.relu(out)
out = self.conv2(out)
out = self.relu(out)
out = self.conv3(out)
out = self.relu(out)
out = self.conv2(out)
out = self.relu(out)
out = self.conv4(out)
out = self.relu(out)
out = self.conv5(out)
out = self.relu(out)
out = self.convTranspose(out)
out=self.sigmoid(out)
return out
I am new to pytorch, thats why I do not know what could be wrong. While the keras model is converging to the right image, the pytorch model is giving me a constant value of 0.45 for every pixel in the image.
It seems like you have some strange ordering and naming in both Keras and PyTorch. In the first one fc_3 is missing, which might still be viable but I don't understand why.
In the PyTorch implementation, you need to have 4 conv layer (fc_2, fc_3, fc_4, fc_5), but you only implemented 3 (conv1, conv2, conv3).
I'd rewrite the model with something like:
class AUTOMAP_Basic_Model(nn.Module):
def __init__(self, inputShape, nrFilters):
super(AUTOMAP_Basic_Model, self).__init__()
self.conv1 = nn.Conv2d(2, 64, (64, 1), padding='same')
self.conv2 = nn.Conv2d(64, 64, (1, 64), padding='same')
self.conv3 = nn.Conv2d(64, 64, (64, 1), padding='same')
self.conv4 = nn.Conv2d(64, 64, (1, 64), padding='same')
self.conv5 = nn.Conv2d(64, 64, 5, padding='same')
self.conv6 = nn.Conv2d(64, 64, 5, padding='same')
self.relu = nn.ReLU(inplace=True)
self.convTranspose = nn.ConvTranspose2d(64, 1, 7, padding=3, output_padding=0)
self.sigmoid = nn.Sigmoid()
self.tan = nn.Tanh()
def forward(self, x):
batch_size = len(x)
out = self.relu(self.conv1(x))
out = self.relu(self.conv2(out))
out = self.relu(self.conv3(out))
out = self.relu(self.conv4(out))
out = self.relu(self.conv5(out))
out = self.relu(self.conv6(out))
out = self.convTranspose(out)
out = self.sigmoid(out)
return out
I'd also suggest using Conv+BN+Relu

wxPython - Fixing buttons to a given position in a image

I'm building a software where I need to display buttons over a image and make it stay somewhat in the same position (the best as possible) when the sizer the image is in gets resized.
The button-display-on-image is already done. I just need to get the math working now. I've tried a bunch of stuff with no luck yet. I guess the magic need to happen in the updateButtons function.
Thanks!
import wx
import wx.lib.platebtn as pb
class MainFrame(wx.Frame):
def __init__(self, parent):
super().__init__(parent)
self.bInfoSizerVisibility = False
self.images = []
self.initUI()
self.CenterOnScreen()
self.Bind(wx.EVT_SIZE, self.OnResizing)
def initUI(self):
self.imageSizer = wx.BoxSizer(wx.VERTICAL)
self.imageSizer.SetMinSize((800, 600))
self.bitmap = None
self.image = None
self.aspect = None
self.bmpImage = wx.StaticBitmap(self, wx.ID_ANY)
self.imageSizer.Add(self.bmpImage, 1, wx.EXPAND)
self.btn = pb.PlateButton(self.bmpImage, -1, 'Click Me!', style=pb.PB_STYLE_NOBG)
self.btn.Bind(wx.EVT_BUTTON, self.test)
self.btn.Position = 250, 250
self.SetSizerAndFit(self.imageSizer)
self.frameImage()
def test(self, event):
print('Button Pressed!')
def updateButtons(self):
w, h = self.bmpImage.GetSize()
u, v = 0.3, 0.7
self.btn.Position = int(u * w), int(v * h)
def frameImage(self, isJustResize=False):
if not isJustResize:
self.bitmap = wx.Bitmap('image.jpg', wx.BITMAP_TYPE_ANY)
self.image = wx.Bitmap.ConvertToImage(self.bitmap)
self.aspect = self.image.GetSize()[1] / self.image.GetSize()[0]
self.Layout()
sW, sH = self.imageSizer.GetSize()
newW = sW
newH = int(newW * self.aspect)
if newH > sH:
newH = sH
newW = int(newH / self.aspect)
image = self.image.Scale(newW, newH)
self.bmpImage.SetBitmap(image.ConvertToBitmap())
self.Layout()
self.Refresh()
self.updateButtons()
# print(f"Image New Size: ({newW}, {newH})")
# print(f"App Size: {self.GetSize()}")
# print(f"imageSizer Size: {self.imageSizer.GetSize()}\n")
def OnResizing(self, event):
self.frameImage(True)
event.Skip()
app = wx.App()
frame = MainFrame(None)
frame.Show()
app.MainLoop()
You need to take into account the fact that as you resize the image, white space appears, either to the left and right, or on top and bottom. Remember, the button position is relative to the frame and not the image.
I have rewritten your updateButtons method to implement this.
I have assumed that your button's position will be 0.3 * the width of the image from the left and 0.7 * the height of the image from the top
import wx
import wx.lib.platebtn as pb
IMAGE_MINIMUM_SIZE = (800, 600)
BUTTON_POSITION_RATIO = (0.3, 0.7)
class MainFrame(wx.Frame):
def __init__(self, parent):
super().__init__(parent)
self.bInfoSizerVisibility = False
self.images = []
self.initUI()
self.CenterOnScreen()
self.Bind(wx.EVT_SIZE, self.OnResizing)
def initUI(self):
self.imageSizer = wx.BoxSizer(wx.VERTICAL)
self.imageSizer.SetMinSize(IMAGE_MINIMUM_SIZE)
self.bitmap = None
self.image = None
self.image_aspect = None
self.bmpImage = wx.StaticBitmap(self, wx.ID_ANY)
self.imageSizer.Add(self.bmpImage, 1, wx.EXPAND)
self.btn = pb.PlateButton(self, -1, 'Click Me!', style=pb.PB_STYLE_NOBG)
self.btn.Bind(wx.EVT_BUTTON, self.test)
self.SetSizerAndFit(self.imageSizer)
self.frameImage()
def test(self, event):
print('Button Pressed!')
def updateButtons(self):
frame_aspect = self.Size[0] / self.Size[1]
button_horizontal = int(self.Size[0] * BUTTON_POSITION_RATIO[0])
button_vertical = int(self.Size[1] * BUTTON_POSITION_RATIO[1])
if self.image_aspect <= frame_aspect:
# Frame is wider than image so find the horizontal white space size to add
image_width = self.Size[1] * self.image_aspect
horizontal_offset = (self.Size[0] - image_width)/2
button_horizontal = int(horizontal_offset + image_width * BUTTON_POSITION_RATIO[0])
elif self.image_aspect > frame_aspect:
# Frame is higher than image so find the vertical white space size to add
image_height = self.Size[0] / self.image_aspect
vertical_offset = (self.Size[1] - image_height)/2
button_vertical = int(vertical_offset + image_height * BUTTON_POSITION_RATIO[1])
self.btn.Position = (button_horizontal, button_vertical)
def frameImage(self, isJustResize=False):
if not isJustResize:
self.bitmap = wx.Bitmap('image.jpg', wx.BITMAP_TYPE_ANY)
self.image = wx.Bitmap.ConvertToImage(self.bitmap)
self.image_aspect = self.image.GetSize()[0] / self.image.GetSize()[1]
image_width, image_height = self.imageSizer.GetSize()
new_image_width = image_width
new_image_height = int(new_image_width / self.image_aspect)
if new_image_height > image_height:
new_image_height = image_height
new_image_width = int(new_image_height * self.image_aspect)
image = self.image.Scale(new_image_width, new_image_height)
self.bmpImage.SetBitmap(image.ConvertToBitmap())
self.Layout()
self.Refresh()
self.updateButtons()
def OnResizing(self, event):
self.frameImage(True)
event.Skip()
app = wx.App()
frame = MainFrame(None)
frame.Show()
app.MainLoop()

Is there a way to pass a parameter to the button event function?

Is there a way to pass a parameter to the event function? When I press the submit button, I receive the following error:
NameError: global name 'filename' is not defined
Here is the full error:
raceback (most recent call last):
File "C:\Users\sbing\OneDrive\Documents\CNM\Spring2018\CIS1250_Python\Labs\Prgm11\geopoint.py", line 60, in submit
file = open(filename.GetValue(), 'r')
NameError: global name 'filename' is not defined
Here is my code:
# handle submit button
def submit(self, event):
file = open(filename.GetValue(), 'r')
contents.SetValue(file.read())
file.close()
def createForm(self):
# establish the wxPython App
app = wx.App()
# establish the wxPython frame
win = wx.Frame(None,title="Closes Neighbor", size = (610,535))
# define the screen widgets
# text controls
filename = wx.TextCtrl(win, pos = (100, 50), size = (210, 25))
latitude = wx.TextCtrl(win, pos = (100, 80), size = (210, 25))
longitude = wx.TextCtrl(win, pos = (100, 110), size = (210, 25))
description = wx.TextCtrl(win, pos = (100, 140), size = (210, 25))
answer = wx.TextCtrl(win, pos = (100, 250), size = (400, 50),
style=wx.TE_MULTILINE | wx.HSCROLL)
answer.SetEditable(False)
messages = wx.TextCtrl(win, pos = (100, 350), size = (400, 50),
style=wx.TE_MULTILINE | wx.HSCROLL)
messages.SetEditable(False)
# static labels
lblTitle = wx.StaticText (win, pos = (200, 25), size = (210,25),
label = "Closest Neighbor", style = wx.ALIGN_CENTER)
lblFilename = wx.StaticText (win, pos = (10, 50), size = (210,25),
label = "Filename:")
lblLatitude = wx.StaticText (win, pos = (10, 80), size = (210,25),
label = "Latitude:")
lblLongitude = wx.StaticText (win, pos = (10, 110), size = (210,25),
label = "Longitude:")
lblDescription = wx.StaticText (win, pos = (10, 140), size = (210,25),
label = "Description:")
lblAnswer = wx.StaticText (win, pos = (10, 250), size = (210,25),
label = "Answer:")
lblMessages = wx.StaticText (win, pos = (10, 350), size = (210,25),
label = "Messages:")
# buttons
submitButton = wx.Button(win, label='Find the Closest Point',
pos = (100, 180), size = (180, 25))
submitButton.Bind(wx.EVT_BUTTON, self.submit)
# get the ball roling
win.Show()
app.MainLoop()
As mentioned in my comment, the easiest way to achieve what you want is to change the reference to self.filename but in answer to the question asked, yes you can.
Use the lambda function.
import wx
class TestFrame(wx.Frame):
def __init__(self, *args):
wx.Frame.__init__(self, *args)
Button = wx.Button(self, -1, "Click me")
Button.Bind(wx.EVT_BUTTON, lambda event: self.OnButton(event, flag1="Parameter", flag2="Something else"))
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(Button,1,0,0)
self.SetSizerAndFit(sizer)
self.Show()
def OnButton(self, event, flag1, flag2):
print ("The Button was pressed")
print ("Flag1 was set to ", flag1)
print ("Flag2 was set to ", flag2)
if __name__ == "__main__":
app = wx.App()
myframe = TestFrame(None, -1, "Button Test")
app.MainLoop()

wxPython - Dynamically resize image when frame is maximized

I want two images placed side-by-side to increase in size when the frame is resize (maximized). How do I achieve that?
import wx
class MyFrame2 ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
bSizer11 = wx.BoxSizer( wx.HORIZONTAL )
self.m_bitmap3 = wx.StaticBitmap( self, wx.ID_ANY, wx.Bitmap( u"img/im1.jpg", wx.BITMAP_TYPE_ANY ), wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer11.Add( self.m_bitmap3, 1, wx.ALL|wx.EXPAND, 5 )
self.m_bitmap4 = wx.StaticBitmap( self, wx.ID_ANY, wx.Bitmap( u"img/im2.jpg", wx.BITMAP_TYPE_ANY ), wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer11.Add( self.m_bitmap4, 1, wx.ALL|wx.EXPAND, 5 )
self.SetSizer( bSizer11 )
self.Layout()
self.Centre( wx.BOTH )
def __del__( self ):
pass
app = wx.App(0)
MyFrame2(None).Show()
app.MainLoop()
Based on your pastebin code
import wx
class MyFrame2 ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
bSizer11 = wx.BoxSizer( wx.HORIZONTAL )
self.img1=wx.Image("1.bmp", wx.BITMAP_TYPE_ANY)
self.img2=wx.Image("1.bmp", wx.BITMAP_TYPE_ANY)
self.m_bitmap3 = wx.StaticBitmap( self, wx.ID_ANY, wx.BitmapFromImage(self.img1), wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer11.Add( self.m_bitmap3, 1, wx.EXPAND, 0 )
self.m_bitmap4 = wx.StaticBitmap( self, wx.ID_ANY, wx.BitmapFromImage(self.img2))
bSizer11.Add( self.m_bitmap4, 1, wx.EXPAND, 0 )
self.Bind(wx.EVT_SIZE, self.onResize)
self.SetSizer( bSizer11 )
self.Layout()
self.Centre(wx.BOTH)
def __del__( self ):
pass
def onResize(self, event):
# self.Layout()
frame_size = self.GetSize()
frame_h = (frame_size[0]-10) / 2
frame_w = (frame_size[1]-10) / 2
img1 = self.img1.Scale(frame_h,frame_w)
img2 = self.img2.Scale(frame_h,frame_w)
self.m_bitmap3.SetBitmap(wx.BitmapFromImage(img1))
self.m_bitmap4.SetBitmap(wx.BitmapFromImage(img2))
self.Refresh()
self.Layout()
app = wx.App(0)
MyFrame2(None).Show()
app.MainLoop()
Note: a single self.Bind
the size of the Scale is based on half of the frame size and the images are scaled from the original images each time, otherwise they slowly get more and more distorted.
You will need to bind to wx.EVT_SIZE since that is the event that is fired when you resize the frame. Then in that handler, you will want to update the image's size. You can use the Scale() method from wx.Image to change the image's size. Note that you will probably want to scale the image in such a way that you maintain it's aspect ratio or it will look weird when it gets stretched.
Here's an example based loosely on my tutorial for a Photo Viewer from a few years ago:
import os
import wx
class PhotoCtrl(wx.App):
def __init__(self, redirect=False, filename=None):
wx.App.__init__(self, redirect, filename)
self.frame = wx.Frame(None, title='Photo Control', size=(400, 400))
self.image_loaded = False
self.current_size = self.frame.GetSize()
self.filepath = None
self.panel = wx.Panel(self.frame)
self.Bind(wx.EVT_SIZE, self.onResize)
self.PhotoMaxSize = self.current_size.GetHeight() - 10
self.createWidgets()
self.frame.Show()
def createWidgets(self):
instructions = 'Browse for an image'
img = wx.EmptyImage(240,240)
self.imageCtrl = wx.StaticBitmap(self.panel, wx.ID_ANY,
wx.BitmapFromImage(img))
instructLbl = wx.StaticText(self.panel, label=instructions)
self.photoTxt = wx.TextCtrl(self.panel, size=(200,-1))
browseBtn = wx.Button(self.panel, label='Browse')
browseBtn.Bind(wx.EVT_BUTTON, self.onBrowse)
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
self.sizer = wx.BoxSizer(wx.HORIZONTAL)
self.mainSizer.Add(wx.StaticLine(self.panel, wx.ID_ANY),
0, wx.ALL|wx.EXPAND, 5)
self.mainSizer.Add(instructLbl, 0, wx.ALL, 5)
self.mainSizer.Add(self.imageCtrl, 0, wx.ALL, 5)
self.sizer.Add(self.photoTxt, 0, wx.ALL, 5)
self.sizer.Add(browseBtn, 0, wx.ALL, 5)
self.mainSizer.Add(self.sizer, 0, wx.ALL, 5)
self.panel.SetSizer(self.mainSizer)
self.panel.Layout()
def onBrowse(self, event):
"""
Browse for file
"""
wildcard = "JPG files (*.jpg)|*.jpg"
dialog = wx.FileDialog(None, "Choose a file",
wildcard=wildcard,
style=wx.OPEN)
if dialog.ShowModal() == wx.ID_OK:
self.photoTxt.SetValue(dialog.GetPath())
self.onView()
dialog.Destroy()
def scale_image(self):
if self.filepath:
img = wx.Image(self.filepath, wx.BITMAP_TYPE_ANY)
# scale the image, preserving the aspect ratio
W = img.GetWidth()
H = img.GetHeight()
if W > H:
NewW = self.PhotoMaxSize
NewH = self.PhotoMaxSize * H / W
else:
NewH = self.PhotoMaxSize
NewW = self.PhotoMaxSize * W / H
img = img.Scale(NewW,NewH)
return img
def onView(self):
self.filepath = self.photoTxt.GetValue()
img = self.scale_image()
self.imageCtrl.SetBitmap(wx.BitmapFromImage(img))
self.panel.Refresh()
self.image_loaded = True
def onResize(self, event):
print 'resizing'
if self.image_loaded:
if self.current_size != self.frame.GetSize():
self.current_size = self.frame.GetSize()
self.PhotoMaxSize = self.current_size.GetHeight() - 30
img = self.scale_image()
self.imageCtrl.SetBitmap(wx.BitmapFromImage(img))
self.panel.Refresh()
self.panel.Layout()
if __name__ == '__main__':
app = PhotoCtrl()
app.MainLoop()
Note that this seems to scale the image just fine, but the buttons on the bottom are getting chopped off. I'm not sure why and don't really have the time at the moment to diagnose that issue, but in general this is probably the way you want to do it.

Resources