Closed zamar1022 closed 5 months ago
Thanks for the answer, but the idea is to take the video with pypylon (using basler cameras, basler dart) and without saving the video in the local disk display it in the tkinter GUI.
I saw the link that you put it, but I think that that doesn't work.
Please help me
Hi @zamar1022 I want to achieve a similar behavior but I want to display the video in the browser, basically what I am looking is the following --> "take the video with pypylon (using basler cameras, basler dart) and without saving the video in the local disk display it in the browser"
Did you make it work? or do you have any advice?
I have something that works after going through the solarianprogrammer.com tutorial.
It uses pypylon to capture images from a basler camera and then displays the images in a Tkinter GUI. Output is a real-time display, without having to save the video on local disk.
This is my main.py:
import tkinter as tk
from tkinter import ttk
from tkinter.constants import *
import oneCameraCapture
import PIL.Image, PIL.ImageTk
import cv2
import time
class Page(tk.Frame):
def __init__(self, parent, window):
tk.Frame.__init__(self, parent)
self.window = window
self.window.title = "Title"
#Open camera source
self.vid = oneCameraCapture.cameraCapture()
#Create a canvas that will fit the camera source
self.canvas = tk.Canvas(window, width=1000,height=600)
self.canvas.grid(row=0, column=0)
menuFrame = ttk.Labelframe(window, text=("Menu"))
menuFrame.grid(row=1, column=0, sticky="NSW",
padx=5, pady=2)
#Button that lets the user take a snapshot
self.btnSaveImage = tk.Button(menuFrame, text="Save Image", command=self.saveImage)
self.btnSaveImage.grid(row=0, column=2, sticky="W")
self.delay=100
self.update()
#self.window.mainloop()
def update(self):
#Get a frame from cameraCapture
frame = self.vid.getFrame() #This is an array
#https://stackoverflow.com/questions/48121916/numpy-resize-rescale-image/48121996
frame = cv2.resize(frame, dsize=(1000, 600), interpolation=cv2.INTER_CUBIC)
#OpenCV bindings for Python store an image in a NumPy array
#Tkinter stores and displays images using the PhotoImage class
# Use PIL (Pillow) to convert the NumPy ndarray to a PhotoImage
self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame))
self.canvas.create_image(500,300,image=self.photo)
self.window.after(self.delay, self.update)
def saveImage(self):
# Get a frame from the video source
frame = self.vid.getFrame()
cv2.imwrite("frame-" + time.strftime("%d-%m-%Y-%H-%M-%S") + ".jpg",
cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))
if __name__ == "__main__":
root = tk.Tk()
testWidget = Page(root, root)
testWidget.grid(row=0, column=0, sticky="W")
root.mainloop()
This is my cameraCapture class (oneCameraCapture.py)
import os
os.environ["PYLON_CAMEMU"] = "3"
from pypylon import genicam
from pypylon import pylon
import sys
import time
import cv2
import numpy as np
import tkinter as tk
class cameraCapture(tk.Frame):
def __init__(self):
self.img0 = []
self.windowName = 'title'
try:
# Create an instant camera object with the camera device found first.
self.camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice())
self.camera.Open() #Need to open camera before can use camera.ExposureTime
self.camera.ExposureTime.SetValue(500)
self.camera.Width=2448
self.camera.Height=2048
# Print the model name of the camera.
print("Using device ", self.camera.GetDeviceInfo().GetModelName())
print("Exposure time ", self.camera.ExposureTime.GetValue())
# According to their default configuration, the cameras are
# set up for free-running continuous acquisition.
#Grabbing continuously (video) with minimal delay
self.camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly)
# converting to opencv bgr format
self.converter = pylon.ImageFormatConverter()
self.converter.OutputPixelFormat = pylon.PixelType_BGR8packed
self.converter.OutputBitAlignment = pylon.OutputBitAlignment_MsbAligned
except genicam.GenericException as e:
# Error handling
print("An exception occurred.", e.GetDescription())
exitCode = 1
def getFrame(self):
try:
self.grabResult = self.camera.RetrieveResult(5000, pylon.TimeoutHandling_ThrowException)
if self.grabResult.GrabSucceeded():
image = self.converter.Convert(self.grabResult) # Access the openCV image data
self.img0 = image.GetArray()
else:
print("Error: ", self.grabResult.ErrorCode)
self.grabResult.Release()
#time.sleep(0.01)
return self.img0
except genicam.GenericException as e:
# Error handling
print("An exception occurred.", e.GetDescription())
exitCode = 1
if __name__ == "__main__":
testWidget = cameraCapture()
while testWidget.camera.IsGrabbing():
#input("Press Enter to continue...")
testWidget.getFrame()
#If window has been closed using the X button, close program
# getWindowProperty() returns -1 as soon as the window is closed
if cv2.getWindowProperty(testWidget.windowName, 0) < 0:
cv2.destroyAllWindows()
break
if testWidget.k == 27: #If press ESC key
print('ESC')
cv2.destroyAllWindows()
break
I have something that works after going through the solarianprogrammer.com tutorial.
It uses pypylon to capture images from a basler camera and then displays the images in a Tkinter GUI. Output is a real-time display, without having to save the video on local disk.
This is my main.py:
import tkinter as tk from tkinter import ttk from tkinter.constants import * import oneCameraCapture import PIL.Image, PIL.ImageTk import cv2 import time class Page(tk.Frame): def __init__(self, parent, window): tk.Frame.__init__(self, parent) self.window = window self.window.title = "Title" #Open camera source self.vid = oneCameraCapture.cameraCapture() #Create a canvas that will fit the camera source self.canvas = tk.Canvas(window, width=1000,height=600) self.canvas.grid(row=0, column=0) menuFrame = ttk.Labelframe(window, text=("Menu")) menuFrame.grid(row=1, column=0, sticky="NSW", padx=5, pady=2) #Button that lets the user take a snapshot self.btnSaveImage = tk.Button(menuFrame, text="Save Image", command=self.saveImage) self.btnSaveImage.grid(row=0, column=2, sticky="W") self.delay=100 self.update() #self.window.mainloop() def update(self): #Get a frame from cameraCapture frame = self.vid.getFrame() #This is an array #https://stackoverflow.com/questions/48121916/numpy-resize-rescale-image/48121996 frame = cv2.resize(frame, dsize=(1000, 600), interpolation=cv2.INTER_CUBIC) #OpenCV bindings for Python store an image in a NumPy array #Tkinter stores and displays images using the PhotoImage class # Use PIL (Pillow) to convert the NumPy ndarray to a PhotoImage self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame)) self.canvas.create_image(500,300,image=self.photo) self.window.after(self.delay, self.update) def saveImage(self): # Get a frame from the video source frame = self.vid.getFrame() cv2.imwrite("frame-" + time.strftime("%d-%m-%Y-%H-%M-%S") + ".jpg", cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)) if __name__ == "__main__": root = tk.Tk() testWidget = Page(root, root) testWidget.grid(row=0, column=0, sticky="W") root.mainloop()
This is my cameraCapture class (oneCameraCapture.py)
import os os.environ["PYLON_CAMEMU"] = "3" from pypylon import genicam from pypylon import pylon import sys import time import cv2 import numpy as np import tkinter as tk class cameraCapture(tk.Frame): def __init__(self): self.img0 = [] self.windowName = 'title' try: # Create an instant camera object with the camera device found first. self.camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice()) self.camera.Open() #Need to open camera before can use camera.ExposureTime self.camera.ExposureTime.SetValue(500) self.camera.Width=2448 self.camera.Height=2048 # Print the model name of the camera. print("Using device ", self.camera.GetDeviceInfo().GetModelName()) print("Exposure time ", self.camera.ExposureTime.GetValue()) # According to their default configuration, the cameras are # set up for free-running continuous acquisition. #Grabbing continuously (video) with minimal delay self.camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly) # converting to opencv bgr format self.converter = pylon.ImageFormatConverter() self.converter.OutputPixelFormat = pylon.PixelType_BGR8packed self.converter.OutputBitAlignment = pylon.OutputBitAlignment_MsbAligned except genicam.GenericException as e: # Error handling print("An exception occurred.", e.GetDescription()) exitCode = 1 def getFrame(self): try: self.grabResult = self.camera.RetrieveResult(5000, pylon.TimeoutHandling_ThrowException) if self.grabResult.GrabSucceeded(): image = self.converter.Convert(self.grabResult) # Access the openCV image data self.img0 = image.GetArray() else: print("Error: ", self.grabResult.ErrorCode) self.grabResult.Release() #time.sleep(0.01) return self.img0 except genicam.GenericException as e: # Error handling print("An exception occurred.", e.GetDescription()) exitCode = 1 if __name__ == "__main__": testWidget = cameraCapture() while testWidget.camera.IsGrabbing(): #input("Press Enter to continue...") testWidget.getFrame() #If window has been closed using the X button, close program # getWindowProperty() returns -1 as soon as the window is closed if cv2.getWindowProperty(testWidget.windowName, 0) < 0: cv2.destroyAllWindows() break if testWidget.k == 27: #If press ESC key print('ESC') cv2.destroyAllWindows() break
from that tutorial i have implemented into gui designed with PAGE, my only problem is that camera feed does not fit the canvas, and the snapshot also does not have the canvas dimensions :(
and here is my code `#! /usr/bin/env python
#
import sys
try: import Tkinter as tk except ImportError: import tkinter as tk
try: import ttk py3 = False except ImportError: import tkinter.ttk as ttk py3 = True
import snapshot_support
##################tutorial################ import cv2 import PIL.Image, PIL.ImageTk import time
def vp_start_gui(): '''Starting point when module is the main routine.''' global val, w, root root = tk.Tk() top = scannerApp (root) snapshot_support.init(root, top) root.mainloop()
w = None def create_scannerApp(rt, *args, *kwargs): '''Starting point when module is imported by another module. Correct form of call: 'create_scannerApp(root, args, **kwargs)' .''' global w, w_win, root
root = rt
w = tk.Toplevel (root)
top = scannerApp (w)
snapshot_support.init(w, top, *args, **kwargs)
return (w, top)
def destroy_scannerApp(): global w w.destroy() w = None
class scannerApp: def init(self, top=None, video_source=0): '''This class configures and populates the toplevel window. top is the toplevel containing window.''' _bgcolor = '#d9d9d9' # X11 color: 'gray85' _fgcolor = '#000000' # X11 color: 'black' _compcolor = '#d9d9d9' # X11 color: 'gray85' _ana1color = '#d9d9d9' # X11 color: 'gray85' _ana2color = '#ececec' # Closest X11 color: 'gray92'
top.geometry("600x450+420+128")
top.minsize(120, 1)
top.maxsize(1370, 749)
top.resizable(1, 1)
top.title("scaner")
top.configure(background="#d9d9d9")
self.video_source = video_source
# open video source (by default this will try to open the computer webcam)
self.vid = MyVideoCapture(self.video_source)
# Create a canvas that can fit the above video source size
self.Canvas1 = tk.Canvas(top)
self.Canvas1.place(relx=0.05, rely=0.244, relheight=0.651
, relwidth=0.355)
self.Canvas1.configure(background="#d9d9d9")
self.Canvas1.configure(borderwidth="2")
self.Canvas1.configure(insertbackground="black")
self.Canvas1.configure(relief="ridge")
self.Canvas1.configure(selectbackground="blue")
self.Canvas1.configure(selectforeground="white")
self.startFeedButton = tk.Button(top)
self.startFeedButton.place(relx=0.05, rely=0.022, height=34, width=207)
self.startFeedButton.configure(activebackground="#ececec")
self.startFeedButton.configure(activeforeground="#000000")
self.startFeedButton.configure(background="#d9d9d9")
self.startFeedButton.configure(disabledforeground="#a3a3a3")
self.startFeedButton.configure(foreground="#000000")
self.startFeedButton.configure(highlightbackground="#d9d9d9")
self.startFeedButton.configure(highlightcolor="black")
self.startFeedButton.configure(pady="0")
self.startFeedButton.configure(text='''start''')
self.snapshotButton = tk.Button(top)
self.snapshotButton.place(relx=0.05, rely=0.133, height=34, width=207)
self.snapshotButton.configure(activebackground="#ececec")
self.snapshotButton.configure(activeforeground="#000000")
self.snapshotButton.configure(background="#d9d9d9")
self.snapshotButton.configure(disabledforeground="#a3a3a3")
self.snapshotButton.configure(foreground="#000000")
self.snapshotButton.configure(highlightbackground="#d9d9d9")
self.snapshotButton.configure(highlightcolor="black")
self.snapshotButton.configure(pady="0")
self.snapshotButton.configure(text='''snapshot''', command=self.snapshot)
# After it is called once, the update method will be automatically called every delay milliseconds
self.delay = 15
self.update()
self.Canvas1.mainloop()
def snapshot(self):
# Get a frame from the video source
ret, frame = self.vid.get_frame()
if ret:
cv2.imwrite("frame-" + time.strftime("%d-%m-%Y-%H-%M-%S") + ".jpg", cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))
def update(self):
# Get a frame from the video source
ret, frame = self.vid.get_frame()
if ret:
self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame))
self.Canvas1.create_image(0, 0, image = self.photo, anchor = tk.NW)
self.Canvas1.after(self.delay, self.update)
class MyVideoCapture: def init(self, video_source=0):
self.vid = cv2.VideoCapture(video_source)
if not self.vid.isOpened():
raise ValueError("Unable to open video source", video_source)
# Get video source width and height
self.width = self.vid.get(cv2.CAP_PROP_FRAME_WIDTH)
self.height = self.vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
def get_frame(self):
if self.vid.isOpened():
ret, frame = self.vid.read()
if ret:
# Return a boolean success flag and the current frame converted to BGR
return (ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
else:
return (ret, None)
else:
return (ret, None)
# Release the video source when the object is destroyed
def __del__(self):
if self.vid.isOpened():
self.vid.release()
if name == 'main': vp_start_gui()
`
@danielcovaci : Hello, were you able to solve this problem using PAGE builder. I am trying to build a Qr scanner that will just display the Qr while scanning. wanted to display the video. what did you choose from the widget toolbar to display the video output? Thanks
The idea is to develop a simple GUI with Tkinter. After that take a video and display it in the GUI. I have been able to display a video using openCV, but now I want to show it in a GUI. Can anybody help me? Thanks