Python: displaying an image as a background process? - python

I am using scikit-image, and the following shows what I'm doing, in an ipython console:
import skimage.io as io
import skimage.viewer.viewers.core as sv
im = io.imread('image.jpg')
sv.ImageViewer(im).show()
This works well, except that the viewer runs as a foreground process, which means that I can't access the ipython shell until I've closed the viewing window. I like this viewer; for a grayscale image at least, the cursor shows the gray level and the indices of the current pixel. But I would like to be able to both display the image, and to continue work in the console. How can I best do this?

Worked it out! Just need to do it in two stages (as per the documentation); first
from skimage.viewer import ImageViewer
and then
fs = ImageViewer(f)
fs.show()
This works fine (except for a blank figure window which is created with the ImageViewer command).

Try launching IPython with:
ipython --gui=qt4

Related

Screenshot with selenium and python

I need to take a screenshot of my entire screen for some automated tests I need to perform.
I was able to do this, using driver.get_screenshot_as_file , but the problem is that it only takes the picture of the web page, I need to get the whole picture from the browser, since the data I need to check is in the devtools.
Pic:
enter image description here
I need this:
enter image description here
Thankss!
You can use the package pyautogui to get screenshot of the desktop on the os level. This take screenshot of the entire desktop rather than just the webpage.
import pyautogui
pyautogui.screenshot().save('screenshot.png')
Another alternative to pyautogui would be PIL's ImageGrab. The advantage is that you are able to specify a bounding box:
from PIL import ImageGrab
image = ImageGrab.grab(bbox=None) # bbox=None gives you the whole screen
image.save("your_browser.png")
# for later cv2 use:
import numpy
import cv2
image_cv2 = cv2.cvtColor(numpy.array(image), cv2.COLOR_BGR2RGB)
This also makes it possible to adapt to your browser's window size and only capture its specific window. You can get your browsers bounding box as shown in this answer: https://stackoverflow.com/a/3260811/20161430.
From a speed perspective, it doesn't seem to make much of a difference whether you are using pyautogui or PIL.

Command won't stop running

I have the following piece of code
import skimage.color
import skimage.io
import skimage.viewer
import skimage.filters
fname = "/Users/harryhat/Desktop/Code/Experimental/Frames/frame00055.png"
# read image
image = skimage.io.imread(fname, as_gray=True)
# display the image
viewer = skimage.viewer.ImageViewer(image)
viewer.show()
However when I run the code, firstly the command won't stop running and secondly when I interrupt the command I have to restart the kernel to be able to type in the console. I was wondering why this would be the case / any other ways to do this. Any help would be much appreciated.
The skimage viewer is a Qt application. To run these in a notebook, you need to enable the Qt event loop integration by typing %gui qt in its own cell at the start of the notebook.
Just by the way, the scikit-image viewer is going to be deprecated. I recommend trying out https://napari.org as an alternative. (But the advice above still applies!)

Python image recognition with pyautogui

When I try to recognize an image with pyautogui it just says: None
import pyautogui
s = pyautogui.locateOnScreen('Dark.png')
print s
When I ran this code the picture was on my screen but it still failed.
Pyautogui.locateOnScreen has a parameter that specifies the 'confidence' you have in the image you enter.
This way, pyautogui will deal with slight pixel deviations.
For example:
import pyautogui
s = pyautogui.locateOnScreen('Dark.png', confidence=0.9)
print(s)
For more information, see https://buildmedia.readthedocs.org/media/pdf/pyautogui/latest/pyautogui.pdf.
It's pixel perfect.
It can't find the image if it is not 100% match.
For example, I cropped an area with an Opera extension. Then I ran my script with Firefox, and pyautogui did not recognize it.
Don't let your image get resized or compressed by screen capture software or extensions.
Use the same window/screen (size, resolution) as where you saved your screenshot.
On my system, I get this if the picture is on a second monitor. If I move it to the main screen, the image is located successfully.
It looks like multiple-monitor functionality is not yet implemented:
From http://pyautogui.readthedocs.org/en/latest/roadmap.html
Future features planned (specific versions not planned yet):
Find a list of all windows and their captions.
Click coordinates relative to a window, instead of the entire screen.
Make it easier to work on systems with multiple monitors.
...

How do I display and close an image with Python?

I would like to display an image with Python and close it after user enters the name of the image in terminal. I use PIL to display image, here is the code:
im = Image.open("image.jpg")
im.show()
My application display this image, but user task is to recognize object on image and write answer in terminal. If answer entered is correct user should get another image. Problem with PIL is that I can't close the image and with research the only solution was to kill the process of image viewer, but this is not really reliable and elegant.
Are there any other libraries for displaying images that have methods like .show() and .close() ?
Just open any image viewer/editor in a separate process and kill it once user has answered your question e.g.
from PIL import Image
import subprocess
p = subprocess.Popen(["display", "/tmp/test.png"])
raw_input("Give a name for image:")
p.kill()
A little late to the party, but (as a disgruntled data scientist who really can't be bothered to learn gui programming for the sake of displaying an image) I can probably speak for several other folks who would like to see an easier solution for this. I figured out a little work around by expanding Anurag's solution:
Make a second python script (let's call it 'imviewer.py'):
from skimage.viewer import ImageViewer
from skimage.io import imread
img = imread('image.png') #path to IMG
view = ImageViewer(img)
view.show()
Then in your main script do as Anurag suggested:
import subprocess
p = subprocess.Popen('python imviewer.py')
#your code
p.kill()
You can make the main script save the image you want to open with 'imviewer.py' temporarily, then overwrite it with the next image etc.
Hope this helps someone with this issue!
Terminal is meant to deal with linear command flow - meaning it asks a question, user answers, and then it can ask a different question. What you are trying to do here is for terminal to do two things, show an image and at the same time ask user a question. To do this you can do two of either things:
Multiprocessing
You can start a new thread/process and make PIL show the image using that thread, and meanwhile in the first thread/process ask a user a question. Then after the user answers, you can close the other thread/process. You can take a look at Python's threading module (link) for more information on how you can do that.
GUI
Instead of making your user interface in terminal, make a simple GUI application using whatever framework you are comfortable. I personally like PyQt4. Qt is very powerful GUI development toolkit and PyQt4 is a wrapper for it. If you make a GUI, then what you are tyring to do is rather trivial.
Not all GUIs are difficult to use.
Here is a single-line solution using PySimpleGUI. Normally I wouldn't write it as a single line, but since it's a one-off, perhaps doesn't need adding to, then it's OK to do.
import PySimpleGUI as sg
sg.Window('My window').Layout([[ sg.Image('PySimpleGUI.png') ]]).Read()
Might be an overkill, but for me the easiest and most robust solution was just to use matplotlib as it properly keeps track of the figures it creates, e.g. :
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
imgplot = plt.imshow(mpimg.imread('animal.png'))
plt.ion()
plt.show()
animal_name = raw_input("What is the name?: ")
plt.close()

Taking screenshot from a python script by selecting the area

I saw that post (that is really helpful : Take a screenshot via a python script. [Linux]) about taking a screenshot from python. It works well but I'd like to have the same behavior as gnome-screenshot : having the possibility to choose between :
Capturing the whole desktop
Capturing an active window
Capturing an area
Is there a way to do this in python, or, eventually, to use the gnome-screenshot application to do it, and then getting the file ?
I tried to find the perfect command line for gnome-screenshot to be launched without asking where to save the screenshot after by giving the path at the call, but I can't find it.
Thanks for your help!
I have a wrapper project (pyscreenshot) for scrot, imagemagick, pyqt, wx and pygtk.
If you have one of them, you can use it.
Capturing an active window is missing.
Install:
easy_install pyscreenshot
Example:
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')
If you are not limited to using using gnome-screenshot specifically, ImageMagick's import command can save directly to file without an interactive prompt.
See here for details: http://www.imagemagick.org/script/import.php
In addition to the command line interface, there is also a Python API.

Categories

Resources