Advertisement
Guest User

Untitled

a guest
Feb 20th, 2020
409
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.95 KB | None | 0 0
  1. # USB camera display using PyQt and OpenCV, from iosoft.blog
  2. # Copyright (c) Jeremy P Bentham 2019
  3. # Please credit iosoft.blog if you use the information or software in it
  4.  
  5. VERSION = "Cam_display v0.10"
  6.  
  7. import sys, time, threading, cv2
  8. try:
  9.     from PyQt5.QtCore import Qt
  10.     pyqt5 = True
  11. except:
  12.     pyqt5 = False
  13. if pyqt5:
  14.     from PyQt5.QtCore import QTimer, QPoint, pyqtSignal
  15.     from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit, QLabel
  16.     from PyQt5.QtWidgets import QWidget, QAction, QVBoxLayout, QHBoxLayout
  17.     from PyQt5.QtGui import QFont, QPainter, QImage, QTextCursor
  18. else:
  19.     from PyQt4.QtCore import Qt, pyqtSignal, QTimer, QPoint
  20.     from PyQt4.QtGui import QApplication, QMainWindow, QTextEdit, QLabel
  21.     from PyQt4.QtGui import QWidget, QAction, QVBoxLayout, QHBoxLayout
  22.     from PyQt4.QtGui import QFont, QPainter, QImage, QTextCursor
  23. try:
  24.     import Queue as Queue
  25. except:
  26.     import queue as Queue
  27.  
  28. IMG_SIZE    = 1280,720          # 640,480 or 1280,720 or 1920,1080
  29. IMG_FORMAT  = QImage.Format_RGB888
  30. DISP_SCALE  = 2                # Scaling factor for display image
  31. DISP_MSEC   = 50                # Delay between display cycles
  32. # CAP_API     = cv2.CAP_ANY       # API: CAP_ANY or CAP_DSHOW etc...
  33. # CAP_API     = cv2.CAP_AVFOUNDATION       # API: CAP_ANY or CAP_DSHOW etc...
  34. EXPOSURE    = 0                 # Zero for automatic exposure
  35. TEXT_FONT   = QFont("Courier", 10)
  36.  
  37. camera_num  = 2                 # Default camera (first in list)
  38. image_queue = Queue.Queue()     # Queue to hold images
  39. capturing   = True              # Flag to indicate capturing
  40.  
  41. # Grab images from the camera (separate thread)
  42. def grab_images(cam_num, queue):
  43.     # cap = cv2.VideoCapture(cam_num-1 + CAP_API)
  44.     cap = cv2.VideoCapture(cam_num-1)
  45.     # we capture the first frame for the camera to adjust itself to the exposure
  46.     ret_val , cap_for_exposure = cap.read()
  47.  
  48.     # cap.set(cv2.CAP_PROP_FRAME_WIDTH, IMG_SIZE[0])
  49.     # cap.set(cv2.CAP_PROP_FRAME_HEIGHT, IMG_SIZE[1])
  50.     # if EXPOSURE:
  51.     #     cap.set(cv2.CAP_PROP_AUTO_EXPOSURE, 0)
  52.     #     cap.set(cv2.CAP_PROP_EXPOSURE, EXPOSURE)
  53.     # else:
  54.     #     cap.set(cv2.CAP_PROP_AUTO_EXPOSURE, 1)
  55.  
  56.     cap.set(cv2.CAP_PROP_AUTO_EXPOSURE, 0.25)
  57.     cap.set(cv2.CAP_PROP_EXPOSURE , 0.001)
  58.  
  59.     while capturing:
  60.         if cap.grab():
  61.             retval, image = cap.retrieve(0)
  62.             if image is not None and queue.qsize() < 2:
  63.                 queue.put(image)
  64.             else:
  65.                 time.sleep(DISP_MSEC / 1000.0)
  66.         else:
  67.             print("Error: can't grab camera image")
  68.             break
  69.     cap.release()
  70.  
  71. # Image widget
  72. class ImageWidget(QWidget):
  73.     def __init__(self, parent=None):
  74.         super(ImageWidget, self).__init__(parent)
  75.         self.image = None
  76.  
  77.     def setImage(self, image):
  78.         self.image = image
  79.         self.setMinimumSize(image.size())
  80.         self.update()
  81.  
  82.     def paintEvent(self, event):
  83.         qp = QPainter()
  84.         qp.begin(self)
  85.         if self.image:
  86.             qp.drawImage(QPoint(0, 0), self.image)
  87.         qp.end()
  88.  
  89. # Main window
  90. class MyWindow(QMainWindow):
  91.     text_update = pyqtSignal(str)
  92.  
  93.     # Create main window
  94.     def __init__(self, parent=None):
  95.         QMainWindow.__init__(self, parent)
  96.  
  97.         self.central = QWidget(self)
  98.         self.textbox = QTextEdit(self.central)
  99.         self.textbox.setFont(TEXT_FONT)
  100.         self.textbox.setMinimumSize(300, 100)
  101.         self.text_update.connect(self.append_text)
  102.         sys.stdout = self
  103.         print("Camera number %u" % camera_num)
  104.         print("Image size %u x %u" % IMG_SIZE)
  105.         if DISP_SCALE > 1:
  106.             print("Display scale %u:1" % DISP_SCALE)
  107.  
  108.         self.vlayout = QVBoxLayout()        # Window layout
  109.         self.displays = QHBoxLayout()
  110.         self.disp = ImageWidget(self)    
  111.         self.displays.addWidget(self.disp)
  112.         self.vlayout.addLayout(self.displays)
  113.         self.label = QLabel(self)
  114.         self.vlayout.addWidget(self.label)
  115.         self.vlayout.addWidget(self.textbox)
  116.         self.central.setLayout(self.vlayout)
  117.         self.setCentralWidget(self.central)
  118.  
  119.         self.mainMenu = self.menuBar()      # Menu bar
  120.         exitAction = QAction('&Exit', self)
  121.         exitAction.setShortcut('Ctrl+Q')
  122.         exitAction.triggered.connect(self.close)
  123.         self.fileMenu = self.mainMenu.addMenu('&File')
  124.         self.fileMenu.addAction(exitAction)
  125.  
  126.     # Start image capture & display
  127.     def start(self):
  128.         self.timer = QTimer(self)           # Timer to trigger display
  129.         self.timer.timeout.connect(lambda:
  130.                     self.show_image(image_queue, self.disp, DISP_SCALE))
  131.         self.timer.start(DISP_MSEC)        
  132.         self.capture_thread = threading.Thread(target=grab_images,
  133.                     args=(camera_num, image_queue))
  134.         self.capture_thread.start()         # Thread to grab images
  135.  
  136.     # Fetch camera image from queue, and display it
  137.     def show_image(self, imageq, display, scale):
  138.         if not imageq.empty():
  139.             image = imageq.get()
  140.             if image is not None and len(image) > 0:
  141.                 img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  142.                 self.display_image(img, display, scale)
  143.  
  144.     # Display an image, reduce size if required
  145.     def display_image(self, img, display, scale=1):
  146.         disp_size = img.shape[1]//scale, img.shape[0]//scale
  147.         disp_bpl = disp_size[0] * 3
  148.         if scale > 1:
  149.             img = cv2.resize(img, disp_size,
  150.                              interpolation=cv2.INTER_CUBIC)
  151.         qimg = QImage(img.data, disp_size[0], disp_size[1],
  152.                       disp_bpl, IMG_FORMAT)
  153.         display.setImage(qimg)
  154.  
  155.     # Handle sys.stdout.write: update text display
  156.     def write(self, text):
  157.         self.text_update.emit(str(text))
  158.     def flush(self):
  159.         pass
  160.  
  161.     # Append to text display
  162.     def append_text(self, text):
  163.         cur = self.textbox.textCursor()     # Move cursor to end of text
  164.         cur.movePosition(QTextCursor.End)
  165.         s = str(text)
  166.         while s:
  167.             head,sep,s = s.partition("\n")  # Split line at LF
  168.             cur.insertText(head)            # Insert text at cursor
  169.             if sep:                         # New line if LF
  170.                 cur.insertBlock()
  171.         self.textbox.setTextCursor(cur)     # Update visible cursor
  172.  
  173.     # Window is closing: stop video capture
  174.     def closeEvent(self, event):
  175.         global capturing
  176.         capturing = False
  177.         self.capture_thread.join()
  178.  
  179. if __name__ == '__main__':
  180.     if len(sys.argv) > 1:
  181.         try:
  182.             camera_num = int(sys.argv[1])
  183.         except:
  184.             camera_num = 0
  185.     if camera_num < 1:
  186.         print("Invalid camera number '%s'" % sys.argv[1])
  187.     else:
  188.         app = QApplication(sys.argv)
  189.         win = MyWindow()
  190.         win.show()
  191.         win.setWindowTitle(VERSION)
  192.         win.start()
  193.         sys.exit(app.exec_())
  194.  
  195. #EOF
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement