image.show() method gives permission error - python

I am running through the facial_recognition library tests. In it I construct a PIL.Image.Image object from a numpy array. I then attempt to open that image.
I am using the Spyder IDE on macOS Mojave. I run Spyder by running sudo spyder from the terminal.
import face_recognition
from PIL import Image
image = face_recognition.load_image_file('test_images/biden.jpg')
face_locs = face_recognition.face_locations(image)
for loc in face_locs:
top, right, bottom, left = loc
face_image = image[top:bottom, left:right]
pil_image = Image.fromarray(face_image)
pil_image.show()
Upon reaching pil_image.show(), Preview opens and tries to open the image, but then displays the following error message in a window:
The file “tmp_pycgvqc.PNG” couldn’t be opened because you don’t have permission to view it.
When I use the pil_image.save() method to save the image, and then I try open it, it works fine. Only using the pil_image.show() method produces the error.

Related

Image.show() doesn't display image

I am trying to display an image on VScode using Image.show from the pillow library but it doesn't work.
This is the code:
from PIL import Image
im = Image.open("/workspaces/105456256/project/before2.jpg")
im.show()
when I run this I don't get any error, instead, nothing happens.
My OS is Windows 11.
I tried the same code on PyCharm and it worked just fine.
Try using:
from PIL import Image
im = Image.open("/workspaces/105456256/project/before2.jpg")
im.show()
input("Press ENTER to exit") # pause

PyQt5 - fromIccProfile: failed minimal tag size sanity error

I'm using latest PyQt5 5.12.2 and I'm getting a weird message for every JPG picture that I'm showing in my script using QPixmap or QIcon.
qt.gui.icc: fromIccProfile: failed minimal tag size sanity
It isn't causing anything and the script works as it should. The problem is that I'm trying to display a huge amount of jpg pictures at the same time (as a photo gallery) so the window gets unresponsive until all messages are printed for each photo.
I tried for hours to find something useful online but unfortunately, it seems like nearly no one had the same issue. I'm using some PNG files too and they don't raise this error so I'm assuming that the problem is with jpg format. I tried using older pyqt5 versions but the only difference is that they are not printing the message but the problem remains.
Meanwhile, I tried to use this command to mute those messages since there is no use of them but the problem with unresponsive window for a few seconds remains even when it's not printing in the console.
def handler(*args):
pass
qInstallMessageHandler(handler)
EDIT: I tried converting these images to PNG but the error remains. So the JPG format wasn't the problem
I dug more deeply into ICC profiles and colour spaces and it seems like the colour space that your pictures are using is somehow non-standard for PyQt.
My solution is to convert these pictures to an ICC profile that is classical such as sRGB.
Here's an example function:
import io
from PIL import Image, ImageCms
def convert_to_srgb(file_path):
'''Convert PIL image to sRGB color space (if possible)'''
img = Image.open(file_path)
icc = img.info.get('icc_profile', '')
if icc:
io_handle = io.BytesIO(icc) # virtual file
src_profile = ImageCms.ImageCmsProfile(io_handle)
dst_profile = ImageCms.createProfile('sRGB')
img_conv = ImageCms.profileToProfile(img, src_profile, dst_profile)
icc_conv = img_conv.info.get('icc_profile','')
if icc != icc_conv:
# ICC profile was changed -> save converted file
img_conv.save(file_path,
format = 'JPEG',
quality = 50,
icc_profile = icc_conv)
Using PIL library is a fast and effective way how to properly resolve that error.
I am making a GUI Image Viewer with Pyside2 and was having a similar issue.
The images were loading fine and for my case there was no performances issues, but I keep getting these ICC warnings.
And I didn't want to fix the original files, because my app is supposed to be only a viewer.
I don't know it will help for your case, but my solution is to first load the image with pillow ImageQT module
from pathlib import Path
from PIL.ImageQt import ImageQt
def load_image(path):
if Path(path).is_file():
return ImageQt(path)
Then in my QT Widget class that display the image, I load this image on a empty QPixmap:
def on_change(self, path):
pixmap = QtGui.QPixmap()
image = load_image(path)
if image:
pixmap.convertFromImage(image)
if pixmap.isNull():
self.display_area_label.setText('No Image')
else:
self.display_area_label.setPixmap(pixmap)

Python Cocos2d can't find resource image after resizing it

I'm trying to resize an image in Python and then load a cocos2d sprite with the resized image. However, trying to initialize a cocos2d sprite results in an error that the resource can't be found. Example code to reproduce the problem:
from pathlib import Path
import cocos
from PIL import Image
im = Image.open("in.jpg")
im.thumbnail((600, 900))
im.save("out.jpg", "JPEG")
im.close()
file = Path("out.jpg")
if file.is_file():
print("File exists")
sprite = cocos.sprite.Sprite("out.jpg")
This results in the error
pyglet.resource.ResourceNotFoundException: Resource "out.jpg" was not found on the path. Ensure that the filename has the correct captialisation.
However, the output is:
File exists
Running it a second time doesn't give errors, since out.jpg has been created in the previous run. Deleting out.jpg and running it again produces the error.
Adding an im.close() didn't solve the problem.
The OS is Windows 10 with Python version 3.6.4.
It turned out to be the method used in pyglet to load a resource. I had to reindex the images. The files in the images directory where dynamically added and pyglet creates an index of existing images. See https://stackoverflow.com/a/16438410/6350693 for the answer.

opencv.imshow will cause jupyter notebook crash

I check other question on google or stackoverflow, they are talking about run cv2.imshow in script, but my code run in jupyter notebook.
Here is my configuration:
ubuntu 16.4x64
python 3.5
opencv 3.1.0
I start a jupyter notebook: here is the code I put it notebook:
%pylab notebook
import cv2
cvim2disp = cv2.imread('data/home.jpg')
cv2.imshow('HelloWorld', cvim2disp)
cv2.waitKey() #image will not show until this is called
cv2.destroyWindow('HelloWorld') #make sure window closes cleanly
When I execute these code. image will show in a pop up window, but I can not close this window by clicking the x on the top right corner, and a moment later, system will prompt me that the window is not responding, it will give me 2 choices: "wait" , "fore quit". if I hit wait, then It will show the same prompt later, If I hit 'fore quit', then the jupyter notebook kernel die and I have to start over.
I google around, many solution suggest that I should add this code
cv2.startWindowThread()
before imshow, but situation get worse, the kernel hang forever!.
anybody have some idea what's going on.
Here is the pic of my error:
%matplotlib inline
#The line above is necesary to show Matplotlib's plots inside a Jupyter Notebook
import cv2
from matplotlib import pyplot as plt
#Import image
image = cv2.imread("input_path")
#Show the image with matplotlib
plt.imshow(image)
plt.show()
I was having a similar problem, and could not come to a good solution with cv2.imshow() in the Jupyter Notebook. I followed this stackoverflow answer, just using matplotlib to display the image.
import matplotlib.pyplot as plt
# load image using cv2....and do processing.
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
# as opencv loads in BGR format by default, we want to show it in RGB.
plt.show()
The API documentation for cv2.waitKey() notes the following:
This function is the only method in HighGUI that can fetch and handle events, so it needs to be called periodically for normal event processing unless HighGUI is used within an environment that takes care of event processing.
So perhaps calling the function in an endless loop would make the window responsive? I haven't tested this, but maybe you would like to try the following:
import cv2
cvim2disp = cv2.imread('data/home.jpg')
cv2.imshow('img', cvim2disp)
while(True):
k = cv2.waitKey(33)
if k == -1: # if no key was pressed, -1 is returned
continue
else:
break
cv2.destroyWindow('img')
This will help you understand what is happening:
import cv2
cvim2disp = cv2.imread('data/home.jpg')
cv2.imshow('HelloWorld', cvim2disp)
cv2.waitKey(0)
cv2.destroyWindow('HelloWorld')
waitKey(0) method is waiting for an input infinitely. When you see a frame of the corresponding image, do not try to close the image using close in top right corner.
Instead press some key. waitkey method will take that as an input and it will return back a value. Further you can also check which key was pressed to close the frame.
Additionally waitKey(33) will keep the frame active for 33 ms and then close it automatically.
destroyWindow() will destroy the current frame if there.
destroyAllWindows() will destroy all the frames currently present.
This will solve.
if your facing problem in google collab ,you can use this patch
from google.colab.patches import cv2_imshow
cv2_imshow(img)
%matplotlib inline
from matplotlib import pyplot as plt
img = cv2.imread(valid_img_paths[1])
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()
The following code works fine in Jupyter to show one image
%matplotlib inline
import cv2
from matplotlib import pyplot as plt
cap = cv2.VideoCapture(videoFName)
ret, image = cap.read()
image=cv2.resize(image,None,fx=0.25,fy=0.25,interpolation=cv2.INTER_AREA)
plt.imshow(image)
plt.show()
If you want to show the video instead of an image in a separate window, use the following code:
import cv2
cap = cv2.VideoCapture(videoFName)
while cap.isOpened():
ret, image = cap.read()
image=cv2.resize(image,None,fx=0.25,fy=0.25,interpolation=cv2.INTER_AREA)
cv2.imshow('image',image)
k = cv2.waitKey(30) & 0xff # press ESC to exit
if k == 27 or cv2.getWindowProperty('image', 0)<0:
break
cv2.destroyAllWindows()
cap.release()
Make sure the window name match, otherwise it will not work. In this case I use 'image' as window name.
The new window that opens up from Jupyter uses the same kernel as notebook. Just add this below to the code and it would work fine.
cv2.waitKey(0)
cv2.destroyAllWindows()
image = cv2.imread(file_path)
while True:
# Press 'q' for exit
exit_key = ord('q')
if cv2.waitKey(exit_key) & 255 == exit_key:
cv2.destroyAllWindows()
break
cv2.imshow('Image_title', image)
I have just developed a library that is exactly similar to cv2.imshow and it can be used in both Jupyter and colab. It can update the window. Therefore you can easily see the video inside it. It uses HTML canvas and is browser friendly :)
Installation:
pip install opencv_jupyter_ui
Usage:
This is the replacement of cv2.imshow for Jupiter. you need only to replace cv2.imshow with jcv2.imshow. It will work in Jupiter.
First:
please import the library
import opencv_jupyter_ui as jcv2
Then:
change cv2.imshow ->jcv2.imshow
More details exist on the Github Repository. Binder Demo gif
It also supports jcv2.waitKey(100) and jcv2.destroyAllWindows(). In case of the absence of Jupyter, it fallbacks to original cv2 functionality.
In order to change the default keys you can use jcv2.setKeys(['a','b','esc']). Please follow the document for more information
I am not sure if you can open a window from Jupyter Notebook.
cv2.imshow expects a waitKey which doesn't work in Jupyter.
Here is what I have done (using OpenCV 3.3):
from IPython.display import display, HTML
import cv2
import base64
def imshow(name, imageArray):
_, png = cv2.imencode('.png', imageArray)
encoded = base64.b64encode(png)
return HTML(data='''<img alt="{0}" src="data:image/png;base64, {1}"/>'''.format(name, encoded.decode('ascii')))
img = cv2.imread('./media/baboon.jpg',cv2.IMREAD_COLOR)
imshow('baboon', img)
If you don't need to use cv2, just:
from IPython.display import Image
Image('./media/baboon.jpg')

Taking Screen shots of specific size

What imaging modules for python will allow you to take a specific size screenshot (not whole screen)?
I have tried PIL, but can't seem to make ImageGrab.grab() select a small rectangle
and i have tried PyGame but i can't make it take a screen shot outside of it's main display panel
You can use pyscreenshot module.
The pyscreenshot module can be used to copy the contents of the screen to a PIL image memory or file.
You can install it using pip.
$ sudo pip install pyscreenshot
Usage:
import pyscreenshot as ImageGrab
# fullscreen
im=ImageGrab.grab()
im.show()
# part of the screen
im=ImageGrab.grab(bbox=(10,10,500,500))
im.show()
# to file
ImageGrab.grab_to_file('im.png')
I have tried PIL, but can't seem to make ImageGrab.grab() select a small rectangle
What did you try?
As the documentation for ImageGrab clearly states, the function has a bbox parameter, and:
The pixels inside the bounding box are returned as an “RGB” image. If the bounding box is omitted, the entire screen is copied.
So, you only get the whole screen if you don't pass a bbox.
Note that, although I linked to the Pillow docs (and you should be using Pillow), old-school PIL's docs say the same thing:
The bounding box argument can be used to copy only a part of the screen.
So, unless you're using a really, really old version of PIL (before 1.1.3, which I believe is more than a decade out of date), it has this feature.
1) Use pyscreenshot, ImageGrab works but only on Windows
2) Grab the image and box it, then save that image
3) Don't use ImageGrab.grab_to_file, it saves the full size image
4) You don't need to show the image with im.show if you just want to save a screenshot
import pyscreenshot as ImageGrab
im=ImageGrab.grab(bbox=(10,10,500,500))
im.save('im.png')
You could use Python MSS.
From documentation to capture only a part of the screen:
import mss
import mss.tools
with mss.mss() as sct:
# The screen part to capture
monitor = {"top": 160, "left": 160, "width": 160, "height": 135}
output = "sct-{top}x{left}_{width}x{height}.png".format(**monitor)
# Grab the data
sct_img = sct.grab(monitor)
# Save to the picture file
mss.tools.to_png(sct_img.rgb, sct_img.size, output=output)
print(output)
You can use pyscreenshot at linux or windows platforms . I am using Ubuntu it works for me. You can force if subprocess is applied setting it to false together with mss gives the best performance.
import pyscreenshot as ImageGrab
import time
t1 = time.time()
imgScreen = ImageGrab.grab(backend="mss", childprocess=False)
img = imgScreen.resize((640,480))
img.save("screen.png")
t2 = time.time()
print("The passing time",(t2-t1))

Categories

Resources