Closed robmarkcole closed 5 years ago
You mean like a gui with live view? I made one at work using pyqtgraph fairly easily.
Precisely. Would like to do live background subtraction whilst doing alignment.
Any chance your code is on GitHub?
I've previously made GUIs for pymba using PyQt for controlling the camera and OpenCV to display images in real time, which worked well. I don't have the code available to share unfortunately.
@derricw any chance you can post your code? Cheers
OK I discovered pymba/pymba/tests/opencv_liveview_example.py When I make a nice Gui I will add to Github. OpenCV appears the way to go. PyqtGraph looks fantastic for stills but can't get along with the video options.
Here is an example GUI that I wrote using tkinter that displays a live video from an AVT camera using the pymba library.
I am using python 3.6
I am using a USB to Ethernet connector and a 235 camera. Both color and mono works fine.
I am not a professional programmer so if others could improve on this code that would be great.
Thanks to morefigs for making the library available, I really appreciate it.
I have organized the code into two files, the first being the AVT camera class: GIGECamera_2_1_18.py
The second being the tkinter class: Tkinter...py
Camera Class:
#Import libraries
import pymba #vimba package - Allied Vision Camera
import time #included in python - time delays
import numpy as np #numpy package - matrix
import cv2 #Used if bayerRGB format is selected to convert format into something tkinter can use
class GIGECamera():
def __init__(self):
vimba = pymba.Vimba()
vimba.startup()
system = vimba.getSystem()
system.runFeatureCommand("GeVDiscoveryAllOnce")
time.sleep(0.2)
try:
camera_ids = vimba.getCameraIds()
for cam_id in camera_ids:
print("Camera found: ", cam_id)
self.cam = vimba.getCamera(camera_ids[0])
self.cam.openCamera()
#Set Single Frame or Continuous operation
self.cam.AcquisitionMode='SingleFrame'
#self.cam.AcquisitionMode='Continuous'
print(self.cam.AcquisitionMode)
#self.cameraFeatureNames = self.cam.getFeatureNames()
#for name in self.cameraFeatureNames:
# print('Camera feature:', name)
#Set pixel format
#Mono formats for 235
#Mono8, Mono12Packed, Mono12
#Color formats for 235
#Mono8, BayerRG8, BayerRG12, RGB8Packed, BGR8Packed, YUV411Packed, YUV422Packed, YUV444Packed
self.cam.PixelFormat="Mono8"
#self.cam.PixelFormat="RGB8Packed"
#self.cam.PixelFormat="BayerRG8"
#If we use the Bayer format - the speed is 4-5x more than RGB8Packed
#https://docs.opencv.org/3.1.0/de/d25/imgproc_color_conversions.html
#cv::COLOR_BayerBG2BGR, cv::COLOR_BayerGB2BGR, cv::COLOR_BayerRG2BGR, cv::COLOR_BayerGR2BGR, cv::COLOR_BayerBG2RGB, cv::COLOR_BayerGB2RGB, cv::COLOR_BayerRG2RGB, cv::COLOR_BayerGR2RGB
#Set Package size
#The default is 8228 - but 1500 works with either the USB 2 or 3 adapter
#Could not get anything higher than 1500 to work
print(self.cam.GevSCPSPacketSize)
self.cam.GevSCPSPacketSize=1500
print(self.cam.GevSCPSPacketSize)
#Set Payload Size
#Default seems to work
print(self.cam.PayloadSize)
#Set Stream Bytes Per Second
print(self.cam.StreamBytesPerSecond)
self.cam.StreamBytesPerSecond = 115000000 #124000000 is the max I could get
print(self.cam.StreamBytesPerSecond)
except:
#If any error
print("Camera Not Connected Or Other Error")
def start(self):
#Runs once
self.frame = self.cam.getFrame()
self.frame.announceFrame()
def getframe(self):
#Runs each time a frame is captured
try:
self.cam.startCapture()
self.frame.queueFrameCapture()
self.cam.runFeatureCommand("AcquisitionStart")
self.cam.runFeatureCommand("AcquisitionStop")
self.frame.waitFrameCapture()
frame_data = self.frame.getBufferByteData()
#frame_data = cv2.cvtColor(frame_data,cv2.COLOR_BayerRG2RGB) #Convert color if using BayerRGB
img = np.ndarray(buffer=frame_data,
dtype=np.uint8,
shape=(self.frame.height,self.frame.width,self.frame.pixel_bytes))
self.cam.endCapture()
self.cam.revokeAllFrames()
return img
except:
#Once in a while it will throw a frame error - sometimes the camera recovers if you just run getFrame again
#but other times it does not
#Doing the reboot sequence seems to work consistently
print("Frame Error")
self.reboot()
def reboot(self):
#Reboot sequence if frame error
self.cam.flushCaptureQueue()
self.cam.endCapture()
self.cam.revokeAllFrames()
self.start()
self.getframe()
def close(self):
#Close camera unless it isn't open
try:
self.cam.revokeAllFrames()
self.cam.closeCamera()
except:
pass
Tkinter class
import os #included in python - OS
import time #included in python - time delays
import numpy as np #numpy package - matrix
import cv2 #opencv package - image analysis
from PIL import Image, ImageTk #convert cv2 image to tkinter
import pymba #vimba package - Allied Vision Camera
import tkinter as tk #included in python - GUI
from tkinter import filedialog #dialog boxes
E = tk.E
W = tk.W
N = tk.N
S = tk.S
ypadding = 1.5 #ypadding just to save time - used for both x and y
import threading as threading
import datetime as datetime
import queue as queue
#Set working directory to import user defined python programs
os.chdir('C:\\Projects\\Python\\')
#import GIGECamera as GIGECamera
from GIGECamera_2_1_18 import GIGECamera #import AVT camera code
class MainApplication(tk.Frame):
#This is the root window so it does not require a parent
#But we will utilize the parent so that we can cross reference the different classes
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
#<create the rest of your GUI here>
#For each frame - we are passing self to the frame - which is the parent for the other scripts
#So here - self
#But in the other frames - self.parent
#Camera Frame
self.cameraframe = CameraFrame(self)
self.cameraframe.grid(row=0, column=0, padx=ypadding, pady=ypadding, sticky=E+S+W+N)
class CameraFrame(tk.Frame):
def __init__(self,parent):
tk.Frame.__init__(self, parent, width=250, height = 300, highlightthickness=2, highlightbackground="#111")
self.parent = parent
self.mainWidgets()
def mainWidgets(self):
self.cameraview = tk.Label(self)
self.cameraview.grid(row=1,column=0,sticky=N+S+E+W, pady=ypadding)
try:
camera.start()
self.queue = queue.Queue(maxsize=1)
ThreadedCamera(self.parent,self.queue).start()
except:
pass
def process_queue(self):
try:
img = self.queue.get()
#1936 x 1216 original
#picsize = 1936
picsize = 1500
r = picsize / img.shape[1]
dim = (picsize, int(img.shape[0] * r))
# perform the actual resizing of the image and show it
resized = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
imgresized = Image.fromarray(resized)
imgtk = ImageTk.PhotoImage(image=imgresized)
self.cameraview.configure(image=imgtk)
self.cameraview.image = imgtk #If you don't have this - it will flicker the image since it gets deleted during one
except:
pass
class ThreadedCamera(threading.Thread):
def __init__(self, parent,queue):
threading.Thread.__init__(self)
#Very import to import the parent
self.parent = parent
self.queue = queue
def run(self):
while True:
if(self.queue.empty()):
try:
camera.cam.ExposureTimeAbs=90000
img = camera.getframe()
#img = cv2.cvtColor(img,cv2.COLOR_BayerRG2BGR) #Remove this if using the RGB8Packed
self.queue.put(img)
self.parent.cameraframe.process_queue()
except:
pass
if __name__ == "__main__":
root = tk.Tk()
root.geometry("1500x700")
root.attributes('-topmost',True)
root.after_idle(root.attributes,'-topmost',False)
root.wm_title("Tkinter AVT GUI") #Makes the title that will appear in the top left
#Setup the AVT camera
camera = GIGECamera()
time.sleep(0.2)
#load main application
MainApplication(root).pack(side="top", fill="both", expand=True)
root.mainloop()
#Close Camera
try:
camera.close()
except:
pass
Has anyone made a GUI for pymba? e.g. using pyQT, wxPython