I would like to get this functionality with OpenCV 4.5.3 and Python 3.7 on Raspberry Pi 4 with 2021-05-07-raspios-buster-armhf-full:
cv::imshow("window", img);
do_something_while_img_is_displayed();
cv::destroyWindow("window");
I tried 2 options after a call to cv::imshow:
cv::waitKey(10)
cv::pollKey()
both of which display only a window frame without an image
What is the way to accomplish it?
NOTE
My intent is to have an image persistently displayed on the screen and be able to call other OpenCV functions at that time, e.g. capture and process images from a camera. I don't care about event processing loop - there will be no UI interaction at that time.
This snippet works on Ubuntu 18.04 and on 2021-05-07-raspios-buster-armhf-full:
import cv2, sys, time
image = cv2.imread("t1-4.png")
cv2.imshow("window", image)
cv2.waitKey(1000) # this delay has to be long on RPi
time.sleep(3) # substitute for do something
cv2.destroyWindow("window")
Equivalent C++ code works on both OSes as well.
Related
I'm currently creating a script using pyautogui, it intakes pixels and their RGBs, to locate monsters, and trigger things, but for some reason, the script and code I made only work on my PC, if I download the script to another pc, or laptop, and try to use it, it won't work, as if it doesn't recognize the RGB colors of other devices and so it doesn't function.
Also, the devices I used all got the same resolution, 1920x1080
Try some options of locateOnScreen like confidence or grayscale.
Note: You need to have OpenCV installed for the confidence keyword to work.
import pyautogui
pyautogui.locateOnScreen("image.png", confidence=0.9)
pyautogui.locateOnScreen("image.png", grayscale=True)
I'm transferring an application to an RPi, and I need a way to display full screen images using python (3) while code continues to execute. I would like to avoid delving into complicated GUI modules like Tkinter and Pygame. I just want images to fill the screen and stay there until the code replaces them or tells them to go away. If Tkinter or Pygame can do this, that would be fine, but it looks to me like they both enter loops that eventually require keyboard input. My application involves montiring sensors and external inputs, but there will be no keyboard attached. I've tried the following:
feh activated with subprocess.call (This displays the image, but the code stops executing until the image is cleared by a keystroke.
wand.display (this works but only shows a smallish window, not full screen)
fbi (couldn't get it to display an image)
xcd-open (works but opens in "Image Viewer" app in small window - no option for full screen without a mouse click)
I have not tried OpenCV. Seems like that might work, but that's a lot of infrastructure to bring in for this simple application.
For the record I've been to google and have put many hours into this. This request is a last resort.
If you want some pseudocode:
displayImage("/image_folder/image1.jpg" fullscreen = True)
time.sleep(1)
clearImage()
displayImage("/image_folder/image2.jpg" fullscreen = True)
You don't show how you tried with feh and a subprocess, but maybe try starting it in the background so it doesn't block your main thread:
subprocess.call("feh -F yourImage.jpg &", shell=True)
Note that background processes, i.e. those started with &, are using a feature of the shell, so I have set shell=True.
Then, before you display the next image, kill the previous instance:
subprocess.call("pkill feh")
Alternatively, if you know the names of all the images you plan to display in advance, you could start feh in "Slideshow mode" (by passing in all the image names on startup), and then deliver signal SIGUSR1 each time you want to advance the image:
os.kill(os.getpid(...), signal.SIGUSR1)
If the above doesn't work, please click edit under your original question and add in the output from the following commands so we can go down the framebuffer route:
fbset -fb /dev/fb0
tvservice -d edid
edidparser edid
I'm writing a GUI using python and pyQt to read in data packets through UDP socket, processing it through OpenCV, then finally showing it as real time images using Qt. I created a UDP socket outside the while loop, while using the sock.recvfrom method to read in data packets inside the while loop. Within the same while loop, i processed the data and put it into OpenCV format and use OpenCV imshow() method to show the real time video for experimenting. Everything's great and working smooth, but when i try to show the video through QLabel using QImage and QPixmap, things went bizarre. If OpenCV imshow() exist, the code works fine with additional QPixmap shown in the QLabel on top of the OpenCV cv2.imshow() window. However, if i take out the OpenCV imshow(), the UI will freeze and nothing showed leading "python not responding". I've not yet come up with a good reason why this is happening, and i also tried keeping/changing cv2.waitkey() time without succeeding. Any help would be appreciated.
import socket
import cv2
from PyQt4 import QtCore, QtGui, uic
while True:
data, addr = self.sock.recvfrom(10240)
# after some processing on data to get im_data ...
self.im_data_color_resized = cv2.resize(im_data, (0, 0), interpolation = True)
# using OpenCV to show the video (the entire code works with cv2.imshow but not without it)
cv2.imshow('Real Time Image', self.im_data_color_resized)
cv2.waitKey(10)
# using QLabel to show the video
qtimage = cv2.cvtColor(self.im_data_color_resized, cv2.COLOR_BGR2RGB)
height, width, bpc = qtimage.shape
bpl = bpc * width
qimage = QtGui.QImage(qtimage.data, width, height, bpl, QtGui.QImage.Format_RGB888)
self.imageViewer_label.setPixmap(QtGui.QPixmap.fromImage(qimage))
You need to refresh the event queue, so that your GUI can be updated. Add QtGui.QApplication.processEvents() after the setPixamp function.
It works with cv2.waitKey() because it internally already refreshes the painting events allowing the Qt GUI to be refreshed. But I recommend not to rely on this hack, and explicitly refresh the Qt events with processEvents.
You may also want to put this processing loop in its own thread to leave the GUI/Main thread responsive.
i'm using a sony ps3 eye as webcam input on my pi for an OpenCL python program I'm writing, but for some reason no matter what i do the pi python compiler isn't accessing the webcam. Yet the same code when run on my laptop using the same webcam runs perfectly. Then i checked the usb devices on my pi and it state that "sony playstation 3 eye cam" was on usb port 6. also when using the "motion" package on the pi i was able to use the camera perfectly as input. So my problem is again that the python compiler isn't communicating with my webcam on the pi. Please, think about this and tell me how to fix it; i simply can't think of what's wrong. Here's the sample code I used, and please help me out. Thank you very much.
import cv2.cv as cv
#cv.NamedWindow("w1", cv.CV_WINDOW_AUTOSIZE)
camera_index = 0
capture = cv.CaptureFromCAM(camera_index)
while not capture:
print "error opening capture device, correction attempt"
while True:
frame = cv.QueryFrame(capture)
if frame is None:
print "fail with putting in frame"
else:
c = cv.WaitKey(100)
print 'capturing!'
cv.SaveImage("pictest.png", frame)
I never updated this but my solution was: I used the Motion Package for Raspberry Pi to receive images (since the Sony Ps3 EyeToy Camera did not have drivers written that were compatible with the Pi) and then Used OpenCV to analyze each Image. Doing this as each image came in, many times a second, is the same as analyzing video through OpenCV.This implementation worked perfectly for my needs, and I used other Bash tools to delete old image files after a certain time period so my memory was not unnecessarily filled.
There are some known problems with isochronous USB. Some camera issues have been addressed with recent fixes, but others remain (and apparently being worked upon). What kernel version are you using (uname -a)?
The fixes have not worked their way into the official distribution yet, so if you don't want to wait can run rpi-update to pick up the latest kernel (assuming you're using Raspbian). You want at least #389.
What's the simplest way in Ubuntu 11.10 to programmatically guide (either from Bash or Python) the user to capture a webcam photo of themselves?
I can launch a simple app like Cheese, but I don't see an easy way to immediately detect or retrieve the photo it captures. I can also access and record the webcam stream directly via OpenCV, but I'd have to reinvent the GUI to communicate with the user.
Is there any kind of script that's a happy medium, where I can launch it, and it prints on stdout the filename of the image the user took?
I like using pygame for that -
it does not require you to open a Pygame SDL window, unlike when you want to use it to capture keyboard events, for example.
import pygame.camera
pygame.camera.init()
cam = pygame.camera.Camera(pygame.camera.list_cameras()[0])
cam.start()
img = cam.get_image()
import pygame.image
pygame.image.save(img, "photo.bmp")
pygame.camera.quit()
Though Pygame will only save uncompressed "bmp" files - you may want to combine it with PIL to write to other formats.
If you want to do this via Python, it looks like you have a few options. The Pygame library has the ability to access cameras.
If that's unsatisfactory, you can go much lower level and access the Video 4 Linux 2 API directly using ioctl calls using Python's fcntl library.