Python psychopy imageStim - python

I'm using psychopy to get an image on a window like this:
from psychopy import visual
window = visual.Window(size= (1000,600), units = 'pix', pos = (10,10))
stimulusimage = ('C:\Users\name\Documents\Python Scripts\Project\stimuli\Visual Stimuli\Positive\1.jpg')
showingimage = visual.ImageStim(window, image=stimulusimage)
window.flip()
I don't see an image on the window and I have no idea what I'm doing wrong, I don't get any error message.

You need to draw the image before you flip the window:
showingimage.draw()
window.flip()
Otherwise it will show a blank screen. By the way, you need not put the filename in parentheses.

Related

Display continuously change of an image in python

I am writing a python program that gradually changes an image step by step, adjusting each pixel by a small amount in each step. To get a visualization of what the program is doing during runtime, I want it to display the image at each step, always overwriting the currently shown image so that it doesen't open bunch of display windows.
I already tried matplotlib, opencv and skimage, with their according possibilities to display an image and update the frame content in the course of the program:
# using scimage
viewer = ImageViewer(image)
viewer.show(main_window=False) # set the parameter to false so that the code doesn't block here but continues computation
..other code..
viewer.update_image(new_image)
# using matplotlib
myplot = plt.imshow(image)
plt.show(block=False)
.. other code..
myplot.set_data(new_image)
plt.show()
# using opencv
cv2.imshow('image',image)
.. other code ..
cv2.imshow('image', new_image)
I always ran into the problem that when it was supposed to open a frame with an image, it did not display the image but only a black screen. Weirdly enough, when I ran the code in IntelliJ in debug-mode and hit a breakpoint after the display-function, it worked.
What can I do so that it is displayed correctly when running the program normally and not with a breakpoint?
Here's the thing, I think your program does work, except it does and finishes unless you tell it to pause, which is why your breakpoint strategy is working.
Try pausing after showing image -
You can ask for user input. It'll pause until you enter some input to the program.
Put the program thread to sleep for some specified amount of time. This'll freeze your program for some given specified time, but you'll be able to see the image if it's already rendered.
Edit -
Since opencv's waitKey method is working for you now, you can use this method again to prevent the program from closing image window. Use waitKey(0) as your last program statement. It waits for a key press indefinitely, and returns the pressed key's code. Press any key to continue (but remember to have your image window in focus or it won't work), and your program should close if it's used in the end.
Also, I've striked earlier suggested options for pausing a program, because I'm unsure if it would've helped. I think waitKey method is more complex, and helps pause the program without freezing it.
Well, I am still not sure what exactly your goal is but here is a code piece that modifies an image inside of a window whenever the upper button is pressed.
from tkinter import Tk, Canvas, Button, Label, PhotoImage, mainloop
import random
WIDTH, HEIGHT = 800, 600
def modify_image():
print ("modifiying image...")
for x in range(1000):
img.put ( '#%06x' % random.randint(0, 16777215), # 6 char hex color
( random.randint(0, WIDTH), random.randint(0, HEIGHT) ) # (x, y)
)
canvas.update_idletasks()
print ("done")
canvas = Canvas(Tk(), width=WIDTH, height=HEIGHT, bg="#000000")
canvas.pack()
Button(canvas,text="modifiying image",command=modify_image).pack()
img = PhotoImage(width=WIDTH, height=HEIGHT)
Label(canvas,image=img).pack()
mainloop()
The function modify_image() adds 1000 random pixels to the image within the main window. Note the tkinter module is a default python module.

Raspberry Pi not showing pygame with screen as expected

I am trying to get a Raspberry Pi 3B+ to show live streams from 3 cameras, using a screen to get multiple instances of omxplayer to run on the positions I want them. This works exactly as expected.
The problem now is, that I want a static image in the last space on the screen. For that I wanted to use pygame, so I later could have more fun in that area, and maybe not only have an image.
The problem now is how the image is positioned:
https://imgur.com/mUQ38vV (the image is the same size as the video feeds, and I had expected it to be in the bottom right of the monitor, with a thin black line towards the feed above and to the right of it)
I expected the white square to be directly under the top left video feed, but there are large black borders.
The Python code I use for showing the image is as follows:
import time
import pygame
transform_x = 958 #648 #how wide to scale the jpg when replaying
transfrom_y = 539 #how high to scale the jpg when replaying
offset_x = 0 #how far off to left corner to display photos
offset_y = 540 #how far off to left corner to display photos
try:
pygame.init()
info = pygame.display.Info() # You have to call this before pygame.display.set_mode()
screen_width,screen_height = info.current_w,info.current_h
window_width,window_height = screen_width,screen_height
screen = pygame.display.set_mode((window_width, window_height))
#screen = pygame.display.set_mode((0,0))
pygame.mouse.set_visible(False) #hide the mouse cursor
filename = "image.png"
img=pygame.image.load(filename)
#img = pygame.transform.scale(img,(transform_x,transfrom_y))
screen.blit(img,(offset_x,offset_y))
pygame.display.flip() # update the display
time.sleep(30) # pause
finally:
pygame.quit()
I tried with pygame.FULLSCREEN and other modes, but none of them would go all the way to the edge of the monitor.
To show the picture I used this command:
sudo screen -dmS pic sh -c 'python pic.py'
Can anyone help me figure out what I am doing wrong here?
So I got it fixed...
I had to comment out disable_overscan=1 in /boot/config.txt ...
I didn't think of this, because omxplayer was at the positions I expected it to be..

Detecting a smaller image (.png) within a larger image retrieved with ImageGrab?

I've spent the past hour researching this simple topic, but all of the answers I've come across have been very complex and, as a noob to Python, I've been unable to incorporate any of them into my program.
I am trying to make an AI play a browser version of the Piano Tiles Game. As of now, I'm simply trying to take a capture of the games window (a small portion of my computer screen), and then check that games window with a .png of the game's start button. From there I will go on to CLICK that start button, but that's a problem for another time.
How can I check to see if a Image contains a .png file?
Here is my current code:
from PIL import ImageGrab as ig, ImageOps as io, Image
import pyautogui
import bbox
def grabStart(window):
#The start button
start = Image.open("res/StartButton.PNG")
start = io.grayscale(start)
#This is the part I need to figure out. The following is just pseudocode
if window.contains(start): #I know that this doesn't actually work. Just pseudocode
#I'd like to return the location of 'start' in one of the following forms
return either: (x1, y1, x2, y2), (x1, y1, width, height), (a coordinate within 'start'))
def grabGame():
#The coordinates of the entire game window
x1 = 2222
y1 = 320
x2 = 2850
y2 = 1105
#The entire screen of the game
window = ig.grab(bbox = (x1, y1, x2, y2))
window = io.grayscale(window)
return window
grabStart(grabGame())
Try using pyautogui.locate(). Function takes in input two parameter's, the first is the image which needs to be found, the second one is the image in which the smaller image needs to be found. This method only works for images, so if you want to run this for a live window, you might consider another option. Secondly pyautogui is just a wrapper over PIL so if you run into efficiency issues, you might wanna translate the locate() into its PIL equivalent for performance.
Here's a way of doing it. I just leave the program running and open/close and move a preview of the button around the screen seeing if it spots the button and reports the coordinates correctly.
#!/usr/bin/env python3
from PIL import ImageGrab as ig, Image
import pyautogui as ag
def checkButton(button, window):
try:
location = ag.locate(button, window, confidence=0.8)
print(f'location: {location[0]},{location[1]},{location[2]},{location[3]}')
except:
print('Not found')
# Load button just once at startup
button = Image.open("button.png")
# Loop, looking for button
while True:
window = ig.grab()
checkButton(button, window)

pywinauto capture_as_image adds unwanted borders

I am using pywinauto to take a screenshot of a specific window.
Here is the code I use to take a capture of notepad ("Bloc-notes" in french) :
from pywinauto import Application
app = Application().connect(title_re=".*Bloc-notes")
hwin = app.top_window()
hwin.set_focus()
img = hwin.capture_as_image()
img.save('notepad_screenshot.png')
And here is the result:
The red "border" is the background of the window. How can I safely eliminate this red border?
I tried to configure Windows 10 in order not to show windows shadows (in the "visual effects settings") but it has no effect on the size of the capture.
When I look precisely on the capture, I can see that the left, bottom and right borders are 7 pixels thick. Can I reliably remove these pixels? What I mean by "reliably" is: will it always work, and work on other computers?
Any help appreciated.
Here is the solution I found.
import ctypes
from pywinauto import Application
import win32gui
app = Application().connect(title_re=".*Bloc-notes")
hwin = app.top_window()
hwin.set_focus()
window_title = hwin.window_text()
rect = ctypes.wintypes.RECT()
DWMWA_EXTENDED_FRAME_BOUNDS = 9
ctypes.windll.dwmapi.DwmGetWindowAttribute(
ctypes.wintypes.HWND(win32gui.FindWindow(None, window_title)),
ctypes.wintypes.DWORD(DWMWA_EXTENDED_FRAME_BOUNDS),
ctypes.byref(rect),
ctypes.sizeof(rect)
)
img = hwin.capture_as_image(rect)
img.save('notepad_screenshot_ok.png')
And here is the result:
It has worked on all the tests I run (different windows).
Application().connect can return a collection of windows.
Instead use app['YOUR TITLE HERE'] or use find_windows.
From there you can capture the image without those borders.
You can find more info from the docs.

SimpleCV not responding after clicking the picture

I'm trying out SimpleCV and I'm noticing every time I click title bar, simplecv stops working to the pint that it crashes. Before crashing it says "pythonw.exe Stopped working." That happens if I edit my script and run it from the python idle. If I simply double click it, the image is displayed for 20secs and then just closes.
This is what I tried. Really simple.
from SimpleCV import Image
img = Image("carro.jpg")
img = img.scale(300,300)
img.show()
Just wondering if this could causes any kind of trouble while doing some image processing like subtracting colors and stuff like that.
Had the same problem and after searching found this: From http://help.simplecv.org/question/1118/why-imageshow-freezes/ it looks like it is caused by pyGame requiring a while loop to keep pumping events to the window.
The solution, as indicated at that post, and worked for me, was to use the quit() method on the window handle returned by show.
````
img = Image("carro.jpg")
img = img.scale(300,300)
win = img.show()
#wait for user input before closing
raw_input()
win.quit()
````

Categories