I would like to place a .png image file on a QLabel. But doesn't show up (PyQt6/PyQt5) - pyqt5

I building an application and let's say it will have its logo placed in the middle. I would like to know how I can paste the image into the label.
For context, I'm not using the QT designer and hard-coding the entire application. So, I won't be able to generate any resource file (heard people talk about it in other forums).
class mainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
self.setFixedSize(1000, 550)
self.displayImage()
def displayImage(self):
aWidgetForFun = QWidget(self)
aWidgetForFun.setFixedSize(100, 100)
#Let's assume the image is of size 50 x 50
theImageLabel = QLabel(aWidgetForFun)
theImageItself = QPixmap('Images\aLogo.png')
#That was the location of the image (I'm using Windows, not Linux env)
#I'm not placing the entire path as I thought it pay cause problem while converting it to an executable using pyinstaller
#If I only wanted to paste the location form currentdirectory, how do I do it?
theImageLabel.setPixmap(theImageItself)
theImageLabel.resize(70, 70) #I wanted to resize the image (This one might be wrong)
application = QApplication()
applicationInitializer = mainWindow()
applicationInitializer.show()
exit(application.exec())
This code displays the 'aWidgetForFun' widget as well, but doesn't display the image. There were no errors as well.
I would also like help in pasting an SVG image in place of the .png image.

Related

LICENSE.txt when loading data into tensorflow transfer learning

I am using code provided by tensorflow to load data: https://www.tensorflow.org/beta/tutorials/load_data/text
When I put in my own photos, it sends to a different directory. The code wants attributions from my LICENSE.txt, but I am not sure what the purpose of this code segment is.
I made my own LICENSE.txt file by just making a text file with each line being a title of an image. When I do this, it makes attributions a dictionary in which each key is the filename and each corresponding value is ''. When I run another method, I get a key error for every file.
import os
attributions = (data_root/"LICENSE.txt").open(encoding='utf- 8').readlines()
attributions = [line.split('\n') for line in attributions]
print(attributions)
attributions = dict(attributions)
import IPython.display as display
def caption_image(image_path):
image_rel = pathlib.Path(image_path).relative_to(data_root)
return "Image (CC BY 2.0) " + ' -'.join(attributions[str(image_rel)].split(' - ')[:-1])
for n in range(3):
image_path = random.choice(all_image_paths)
display.display(display.Image(image_path))
print(caption_image(image_path))
print()
I do not really know what to expect when I run the for loop in jupyter notebook, but it gives me a key error, the key being the file name.
I wrote that tutorial. The license lookup is only there so we can directly arttribute the individual photographers when we publish it. If you're working with your own images you don't need that part of the code at all.
All it's really doing is choosing a random image and displaying it. You can simplify it to:
import os
import IPython.display as display
for n in range(3):
image_path = random.choice(all_image_paths)
display.display(display.Image(image_path))

Alternative to QHBoxLayout for non-equally sized children

I'd like to be able to have a fixed size bar on the left of my window where I keep my buttons, labels, etc. and a QPlainTextEdit (as a log) on the right, which should be resized dynamically when changing the overall window size.
Ideally I would like the left side to be fixed and the right to by dynamically resized.
I just googled for hours without any luck and hope that I am just too inexperienced to find a simple solution.
You can use QHBoxLayout.setStretch() for this, e.g.
from PyQt5.QtWidgets import QWidget,QHBoxLayout, QLabel, QApplication
from PyQt5.QtCore import Qt
class MyWidget(QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
layout = QHBoxLayout(self)
label1 = QLabel('This one is fixed', self)
label1.setAutoFillBackground(True)
label1.setStyleSheet('background:green')
label2 = QLabel('This one is flexible', self)
label2.setAlignment(Qt.AlignCenter)
label2.setAutoFillBackground(True)
label2.setStyleSheet('background:red')
layout.addWidget(label1)
layout.addWidget(label2)
# set stretch factor of first item in layout to 0 and of second item to 1
layout.setStretch(0,0)
layout.setStretch(1,1)
self.resize(500,350)
if __name__=="__main__":
app = QApplication([])
w = MyWidget()
w.show()
app.exec()
Screenshot:
As the other answer suggests you can simply use Stretch BUT... you can also use that in combination with different types of boxes as such:
VCntnr-1 = QVBoxLayout()
VCntnr-1.addWidget(Button1)
VCntnr-1.addWidget(Button2)
VCntnr-1.addStretch(1)
HCntnr-1 = QHBoxLayout()
HCntnr-1.addLayout(VCntnr-1)
HCntnr-1.addWidget(TextBox)
HCntnr-1.addStretch(1)
This would result in your buttons and such being statically contained in the upper left corner. Of course depending on how you want the left-side arranged perhaps it might contain 2 QVBoxLayouts with some buttons in the first one Stretch and some buttons in the second one
VCntnr-1 = QVBoxLayout()
VCntnr-1.addWidget(Button1)
VCntnr-1.addWidget(Button2)
VCntnr-2 = QVBoxLayout()
VCntnr-2.addWidget(Button3)
VCntnr-2.addWidget(Button4)
VCntnr-3 = QVBoxLayout()
HCntnr-3.addLayout(VCntnr-1)
HCntnr-3.addStretch(1)
HCntnr-3.addLayout(VCntnr-2)
HCntnr-1 = QHBoxLayout()
HCntnr-1.addLayout(VCntnr-1)
HCntnr-1.addWidget(TextBox)
HCntnr-1.addStretch(1)
Thus the containers along with Stretches are what are used to dynamically and statically arrange the layout you are trying to achieve so don't get stuck in a single box layout use boxes judiciously to achieve your ends. There is also a GridLayout that can be used.
Now I have placed a single Button within a QHBoxLayout along with a Stretch to place it on the left or right side of its immediate container and I have used Blank labels as Spacers (although I think pyqt5 has something called a Spacer?) to put some hard space between a Label and its associated object. So it is all about using all the bits and pieces in a creative manner to render the aesthetics you are trying to achieve.
Note the above indentations are for ease of readability and would need to be removed in code.

How to get chosen class images from Imagenet?

Background
I have been playing around with Deep Dream and Inceptionism, using the Caffe framework to visualize layers of GoogLeNet, an architecture built for the Imagenet project, a large visual database designed for use in visual object recognition.
You can find Imagenet here: Imagenet 1000 Classes.
To probe into the architecture and generate 'dreams', I am using three notebooks:
https://github.com/google/deepdream/blob/master/dream.ipynb
https://github.com/kylemcdonald/deepdream/blob/master/dream.ipynb
https://github.com/auduno/deepdraw/blob/master/deepdraw.ipynb
The basic idea here is to extract some features from each channel in a specified layer from the model or a 'guide' image.
Then we input an image we wish to modify into the model and extract the features in the same layer specified (for each octave),
enhancing the best matching features, i.e., the largest dot product of the two feature vectors.
So far I've managed to modify input images and control dreams using the following approaches:
(a) applying layers as 'end' objectives for the input image optimization. (see Feature Visualization)
(b) using a second image to guide de optimization objective on the input image.
(c) visualize Googlenet model classes generated from noise.
However, the effect I want to achieve sits in-between these techniques, of which I haven't found any documentation, paper, or code.
Desired result (not part of the question to be answered)
To have one single class or unit belonging to a given 'end' layer (a) guide the optimization objective (b) and have this class visualized (c) on the input image:
An example where class = 'face' and input_image = 'clouds.jpg':
please note: the image above was generated using a model for face recognition, which was not trained on the Imagenet dataset. For demonstration purposes only.
Working code
Approach (a)
from cStringIO import StringIO
import numpy as np
import scipy.ndimage as nd
import PIL.Image
from IPython.display import clear_output, Image, display
from google.protobuf import text_format
import matplotlib as plt
import caffe
model_name = 'GoogLeNet'
model_path = 'models/dream/bvlc_googlenet/' # substitute your path here
net_fn = model_path + 'deploy.prototxt'
param_fn = model_path + 'bvlc_googlenet.caffemodel'
model = caffe.io.caffe_pb2.NetParameter()
text_format.Merge(open(net_fn).read(), model)
model.force_backward = True
open('models/dream/bvlc_googlenet/tmp.prototxt', 'w').write(str(model))
net = caffe.Classifier('models/dream/bvlc_googlenet/tmp.prototxt', param_fn,
mean = np.float32([104.0, 116.0, 122.0]), # ImageNet mean, training set dependent
channel_swap = (2,1,0)) # the reference model has channels in BGR order instead of RGB
def showarray(a, fmt='jpeg'):
a = np.uint8(np.clip(a, 0, 255))
f = StringIO()
PIL.Image.fromarray(a).save(f, fmt)
display(Image(data=f.getvalue()))
# a couple of utility functions for converting to and from Caffe's input image layout
def preprocess(net, img):
return np.float32(np.rollaxis(img, 2)[::-1]) - net.transformer.mean['data']
def deprocess(net, img):
return np.dstack((img + net.transformer.mean['data'])[::-1])
def objective_L2(dst):
dst.diff[:] = dst.data
def make_step(net, step_size=1.5, end='inception_4c/output',
jitter=32, clip=True, objective=objective_L2):
'''Basic gradient ascent step.'''
src = net.blobs['data'] # input image is stored in Net's 'data' blob
dst = net.blobs[end]
ox, oy = np.random.randint(-jitter, jitter+1, 2)
src.data[0] = np.roll(np.roll(src.data[0], ox, -1), oy, -2) # apply jitter shift
net.forward(end=end)
objective(dst) # specify the optimization objective
net.backward(start=end)
g = src.diff[0]
# apply normalized ascent step to the input image
src.data[:] += step_size/np.abs(g).mean() * g
src.data[0] = np.roll(np.roll(src.data[0], -ox, -1), -oy, -2) # unshift image
if clip:
bias = net.transformer.mean['data']
src.data[:] = np.clip(src.data, -bias, 255-bias)
def deepdream(net, base_img, iter_n=20, octave_n=4, octave_scale=1.4,
end='inception_4c/output', clip=True, **step_params):
# prepare base images for all octaves
octaves = [preprocess(net, base_img)]
for i in xrange(octave_n-1):
octaves.append(nd.zoom(octaves[-1], (1, 1.0/octave_scale,1.0/octave_scale), order=1))
src = net.blobs['data']
detail = np.zeros_like(octaves[-1]) # allocate image for network-produced details
for octave, octave_base in enumerate(octaves[::-1]):
h, w = octave_base.shape[-2:]
if octave > 0:
# upscale details from the previous octave
h1, w1 = detail.shape[-2:]
detail = nd.zoom(detail, (1, 1.0*h/h1,1.0*w/w1), order=1)
src.reshape(1,3,h,w) # resize the network's input image size
src.data[0] = octave_base+detail
for i in xrange(iter_n):
make_step(net, end=end, clip=clip, **step_params)
# visualization
vis = deprocess(net, src.data[0])
if not clip: # adjust image contrast if clipping is disabled
vis = vis*(255.0/np.percentile(vis, 99.98))
showarray(vis)
print octave, i, end, vis.shape
clear_output(wait=True)
# extract details produced on the current octave
detail = src.data[0]-octave_base
# returning the resulting image
return deprocess(net, src.data[0])
I run the code above with:
end = 'inception_4c/output'
img = np.float32(PIL.Image.open('clouds.jpg'))
_=deepdream(net, img)
Approach (b)
"""
Use one single image to guide
the optimization process.
This affects the style of generated images
without using a different training set.
"""
def dream_control_by_image(optimization_objective, end):
# this image will shape input img
guide = np.float32(PIL.Image.open(optimization_objective))
showarray(guide)
h, w = guide.shape[:2]
src, dst = net.blobs['data'], net.blobs[end]
src.reshape(1,3,h,w)
src.data[0] = preprocess(net, guide)
net.forward(end=end)
guide_features = dst.data[0].copy()
def objective_guide(dst):
x = dst.data[0].copy()
y = guide_features
ch = x.shape[0]
x = x.reshape(ch,-1)
y = y.reshape(ch,-1)
A = x.T.dot(y) # compute the matrix of dot-products with guide features
dst.diff[0].reshape(ch,-1)[:] = y[:,A.argmax(1)] # select ones that match best
_=deepdream(net, img, end=end, objective=objective_guide)
and I run the code above with:
end = 'inception_4c/output'
# image to be modified
img = np.float32(PIL.Image.open('img/clouds.jpg'))
guide_image = 'img/guide.jpg'
dream_control_by_image(guide_image, end)
Question
Now the failed approach how I tried to access individual classes, hot encoding the matrix of classes and focusing on one (so far to no avail):
def objective_class(dst, class=50):
# according to imagenet classes
#50: 'American alligator, Alligator mississipiensis',
one_hot = np.zeros_like(dst.data)
one_hot.flat[class] = 1.
dst.diff[:] = one_hot.flat[class]
To make this clear: the question is not about the dream code, which is the interesting background and which is already working code, but it is about this last paragraph's question only: Could someone please guide me on how to get images of a chosen class (take class #50: 'American alligator, Alligator mississipiensis') from ImageNet (so that I can use them as input - together with the cloud image - to create a dream image)?
The question is how to get images of the chosen class #50: 'American alligator, Alligator mississipiensis' from ImageNet.
Go to image-net.org.
Go to "Download".
Follow the instructions for "Download Image URLs":
How to download the URLs of a synset from your Brower?
1. Type a query in the Search box and click "Search" button
The alligator is not shown. ImageNet is under maintenance. Only ILSVRC synsets are included in the search results. No problem, we are fine with the similar animal "alligator lizard", since this search is about getting to the right branch of the WordNet treemap. I do not know whether you will get the direct ImageNet images here even if there were no maintenance.
2. Open a synset papge
Scrolling down:
Scrolling down:
Searching for the American alligator, which happens to be a saurian diapsid reptile as well, as a near neighbour:
3. You will find the "Download URLs" button under the left-bottom corner of the image browsing window.
You will get all of the URLs with the chosen class. A text file pops up in the browser:
http://image-net.org/api/text/imagenet.synset.geturls?wnid=n01698640
We see here that it is just about knowing the right WordNet id that needs to be put at the end of the URL.
Manual image download
The text file looks as follows:
http://farm1.static.flickr.com/136/326907154_d975d0c944.jpg
http://weeksbay.org/photo_gallery/reptiles/American20Alligator.jpg
...
till image number 1261.
As an example, the first URL links to:
And the second is a dead link:
The third link is dead, but the fourth is working.
The images of these URLs are publicly available, but many links are dead, and the pictures are of lower resolution.
Automated image download
From the ImageNet guide again:
How to download by HTTP protocol? To download a synset by HTTP
request, you need to obtain the "WordNet ID" (wnid) of a synset first.
When you use the explorer to browse a synset, you can find the WordNet
ID below the image window.(Click Here and search "Synset WordNet ID"
to find out the wnid of "Dog, domestic dog, Canis familiaris" synset).
To learn more about the "WordNet ID", please refer to
Mapping between ImageNet and WordNet
Given the wnid of a synset, the URLs of its images can be obtained at
http://www.image-net.org/api/text/imagenet.synset.geturls?wnid=[wnid]
You can also get the hyponym synsets given wnid, please refer to API
documentation to learn more.
So what is in that API documentation?
There is everything needed to get all of the WordNet IDs (so called "synset IDs") and their words for all synsets, that is, it has any class name and its WordNet ID at hand, for free.
Obtain the words of a synset
Given the wnid of a synset, the words of
the synset can be obtained at
http://www.image-net.org/api/text/wordnet.synset.getwords?wnid=[wnid]
You can also Click Here to
download the mapping between WordNet ID and words for all synsets,
Click Here to download the
mapping between WordNet ID and glosses for all synsets.
If you know the WordNet ids of choice and their class names, you can use the nltk.corpus.wordnet of "nltk" (natural language toolkit), see the WordNet interface.
In our case, we just need the images of class #50: 'American alligator, Alligator mississipiensis', we already know what we need, thus we can leave the nltk.corpus.wordnet aside (see tutorials or Stack Exchange questions for more). We can automate the download of all alligator images by looping through the URLs that are still alive. We could also widen this to the full WordNet with a loop over all WordNet IDs, of course, though this would take far too much time for the whole treemap - and is also not recommended since the images will stop being there if 1000s of people download them daily.
I am afraid I will not take the time to write this Python code that accepts the ImageNet class number "#50" as the argument, though that should be possible as well, using mapping tables from WordNet to ImageNet. Class name and WordNet ID should be enough.
For a single WordNet ID, the code could be as follows:
import urllib.request
import csv
wnid = "n01698640"
url = "http://image-net.org/api/text/imagenet.synset.geturls?wnid=" + str(wnid)
# From https://stackoverflow.com/a/45358832/6064933
req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
with open(wnid + ".csv", "wb") as f:
with urllib.request.urlopen(req) as r:
f.write(r.read())
with open(wnid + ".csv", "r") as f:
counter = 1
for line in f.readlines():
print(line.strip("\n"))
failed = []
try:
with urllib.request.urlopen(line) as r2:
with open(f'''{wnid}_{counter:05}.jpg''', "wb") as f2:
f2.write(r2.read())
except:
failed.append(f'''{counter:05}, {line}'''.strip("\n"))
counter += 1
if counter == 10:
break
with open(wnid + "_failed.csv", "w", newline="") as f3:
writer = csv.writer(f3)
writer.writerow(failed)
Result:
If you need the images even behind the dead links and in original quality, and if your project is non-commercial, you can sign in, see "How do I get a copy of the images?" at the Download FAQ.
In the URL above, you see the wnid=n01698640 at the end of the URL which is the WordNet id that is mapped to ImageNet.
Or in the "Images of the Synset" tab, just click on "Wordnet IDs".
To get to:
or right-click -- save as:
You can use the WordNet id to get the original images.
If you are commercial, I would say contact the ImageNet team.
Add-on
Taking up the idea of a comment: If you do not want many images, but just the "one single class image" that represents the class as much as possible, have a look at Visualizing GoogLeNet Classes and try to use this method with the images of ImageNet instead. Which is using the deepdream code as well.
Visualizing GoogLeNet Classes
July 2015
Ever wondered what a deep neural network thinks a Dalmatian should
look like? Well, wonder no more.
Recently Google published a post describing how they managed to use
deep neural networks to generate class visualizations and modify
images through the so called “inceptionism” method. They later
published the code to modify images via the inceptionism method
yourself, however, they didn’t publish code to generate the class
visualizations they show in the same post.
While I never figured out exactly how Google generated their class
visualizations, after butchering the deepdream code and this ipython
notebook from Kyle McDonald, I managed to coach GoogLeNet into drawing
these:
... [with many other example images to follow]

Best way to interactively draw a line on a 2D matplotlib plot

I'm a novice using matplotlib as an embedded control in my PyQt4 application to display image data. I'd like to be able to allow the user to interactively draw a line on the image by clicking and dragging. I have it working but it is so slow as to be unusable, leading me to believe I'm not going about it the correct way. The only way I can get the line to appear is by forcing the canvas to redraw each time the mouse moves (I suspect this is the cause of the slowdown).
For example, on the mouse down event I store the current coordinates and add a Line2D object to the plot as follows:
def onMouseMove(self, event):
if self.drawingLine:
self.lineStartX = event.xdata
self.lineStopX = event.xdata
self.lineStartY = event.ydata
self.lineStopY = event.ydata
self.line = Line2D([self.lineStartX, self.lineStopX], [self.lineStartY, self.lineStopY], linewidth = 1.5, color = 'r')
self.axes.add_line(self.line)
Then, in my mouse move event I redraw the line as follows:
def onMouseMove(self, event):
if self.drawingLine:
self.lineStopX = event.xdata
self.lineStopY = event.ydata
# Adjust the line to the new endpoint:
self.line.set_data([self.lineStartX, self.lineStopX], [self.lineStartY, self.lineStopY])
# Force a redraw otherwise you don't see any changes:
self.fig.canvas.draw()
As I've stated this approach is unusably slow and hence probably wrong. Can somebody please clue me in to what the proper approach is here? Thank you all in advance.
First off, you will already gain a little by using
self.fig.canvas.draw_idle()
instead of draw(). This redraws the canvas only when it's not currently beeing repainted, saving you a lot of draws.
If this is not enough, you would need to use the technique of blitting. Now since you don't have a minimal example, I will not provide any complete solution for this here, but e.g. the answer to this question, why is plotting with Matplotlib so slow?, has an example of that.
The idea is to store the background, and only redraw the part that changes (here the line).
background = fig.canvas.copy_from_bbox(ax.bbox)
# then during mouse move
fig.canvas.restore_region(background)
line.set_data(...)
ax.draw_artist(line)
fig.canvas.blit(ax.bbox)
# only after mouse has stopped moving
fig.canvas.draw_idle()
This technique is also used internally by some matplotlib widgets, e.g. matplotlib.widgets.Cursor to let the lines follow the cursor quickly.
This brings me to the last point, which is: You don't need to reinvent the wheel. There is a matplotlib.widgets.RectangleSelector, which by defaut draws a rectangle for selection. But you may use its drawtype='line' argument, to change the selection to a line, together with the argument blit=True this should already give you what you need - you will just need to add the code to finally draw a line once the selection is finished.
Note that in the newest matplotlib version, there is even a matplotlib.widgets.PolygonSelector, which may directly be what you need.
matplotlib is built to be flexible and to work with multiple different backends. It is very slow at real-time plotting. The problem is that your mouse move events are very rapid. Anything trying to keep up with the mouse movement will probably be slow. You need to call the plot less often. You can do this by checking the time in your mouse move function and trying to limit the plotting calls to whatever works.
import time
def onMouseMove(self, event):
if self.drawingLine and time.time() - last_time > 0.03: # Change the 0.03 to change how often you plot.
last_time = time.time()
...
I highly suggest pyqtgraph. pyqtgraph has built in rate limiting signals that you can work with to do this.
Below is a basic example of how you can do this.
# Change the style to look like matplotlib
pyqtgraph.setConfigOption("background", QtGui.QColor.fromRgbF(230/255, 230/255, 234/255, 255/255))
pyqtgraph.setConfigOption("background", 'w')
pyqtgraph.setConfigOption("foreground", 'k')
pyqtgraph.setConfigOption("antialias", True)
# Create the widgets and plot items
glw = pyqtgraph.GraphicsLayoutWidget()
pg = glw.addPlot(0, 0)
class MyClass(object):
...
...
def onMouseMove(self, event):
if self.drawingLine:
scene_pos = event[0]
data_pos = pg.getViewBox().mapSceneToView(scene_pos)
x, y = data_pos.x(), data_pos.y()
self.lineStopX = x
self.lineStopY = y
# Adjust the line to the new endpoint:
if not self.line:
self.line = pg.plot(x=[], y=[])
self.line.setData(x=[self.lineStartX, self.lineStopX],
y=[self.lineStartY, self.lineStopY])
mouse_move_sig = pyqtgraph.SignalProxy(pg.scene().sigMouseMoved,
rateLimit=60, slot=onMouseMove)

How do I set the colormap for Image?

I'm using the IPython Notebook on Chrome. I've been trying to display several images in a loop, so that they display one after the other. After no luck with imshow() or set_data() (weird JSON non_serialisable errors, even on uint8 data - same happens when I use Image() on a Numpy array) I wrote the following helper function:
def fshow(im):
imsave('/test.png',im)
display(Image(filename='/test.png'))
which saves the image to a temporary file and then uses Image() to display it. It works beautifully - images pop up one after the other in the output cell, in real time, and I can intersperse them with Print statements if I want to.
But with monochrome images, they show up in the Jet colormap! So I used the following hack to save monochrome images as RGB images with identical colour channels...
def fshow(im):
sh=im.shape
sh=(im.shape[0],im.shape[1],3)
im2=zeros(sh)
im2[:,:,0]=im
im2[:,:,1]=im
im2[:,:,2]=im
imsave('/test.png',im2)
display(Image(filename='/test.png'))
This is, however, a bit of a hack. So, how can I change the colormap which Image uses to display monochrome images?
And as we're here, how do I get Image() to display a Numpy array without complaining that it can't be JSON serialised?