Skip to content

Instantly share code, notes, and snippets.

@ExpandOcean
Created January 12, 2015 01:22
Show Gist options
  • Select an option

  • Save ExpandOcean/58f60113a7f61f549e40 to your computer and use it in GitHub Desktop.

Select an option

Save ExpandOcean/58f60113a7f61f549e40 to your computer and use it in GitHub Desktop.

Revisions

  1. ExpandOcean created this gist Jan 12, 2015.
    161 changes: 161 additions & 0 deletions opencv_pyqt_camera.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,161 @@
    # coding=utf-8
    import sys

    from PyQt4 import QtGui
    import cv
    from PyQt4 import QtCore


    class CameraDevice(QtCore.QObject):
    _DEFAULT_FPS = 30

    newFrame = QtCore.pyqtSignal(cv.iplimage)

    def __init__(self, cameraId=0, mirrored=False, parent=None,
    size=(640, 480)):
    super(CameraDevice, self).__init__(parent)

    self.mirrored = mirrored

    self._cameraDevice = cv.CaptureFromCAM(cameraId)
    cv.SetCaptureProperty(self._cameraDevice, cv.CV_CAP_PROP_FRAME_WIDTH,
    size[0])
    cv.SetCaptureProperty(self._cameraDevice, cv.CV_CAP_PROP_FRAME_HEIGHT,
    size[1])

    self._timer = QtCore.QTimer(self)
    self._timer.timeout.connect(self._queryFrame)
    self._timer.setInterval(1000 / self.fps)

    self.paused = False

    @QtCore.pyqtSlot()
    def _queryFrame(self):
    frame = cv.QueryFrame(self._cameraDevice)
    if self.mirrored:
    mirroredFrame = cv.CreateImage(cv.GetSize(frame), frame.depth,
    frame.nChannels)
    cv.Flip(frame, mirroredFrame, 1)
    frame = mirroredFrame
    self.newFrame.emit(frame)

    @property
    def paused(self):
    return not self._timer.isActive()

    @paused.setter
    def paused(self, p):
    if p:
    self._timer.stop()
    else:
    self._timer.start()

    @property
    def frameSize(self):
    w = cv.GetCaptureProperty(self._cameraDevice,
    cv.CV_CAP_PROP_FRAME_WIDTH)
    h = cv.GetCaptureProperty(self._cameraDevice,
    cv.CV_CAP_PROP_FRAME_HEIGHT)
    return int(w), int(h)

    @property
    def fps(self):
    fps = int(cv.GetCaptureProperty(self._cameraDevice, cv.CV_CAP_PROP_FPS))
    if not fps > 0:
    fps = self._DEFAULT_FPS
    return fps


    class CameraWidget(QtGui.QWidget):
    newFrame = QtCore.pyqtSignal(cv.iplimage)

    def __init__(self, cameraDevice, parent=None):
    super(CameraWidget, self).__init__(parent)

    self._frame = None

    self._cameraDevice = cameraDevice
    self._cameraDevice.newFrame.connect(self._on_new_frame)

    w, h = self._cameraDevice.frameSize
    self.setMinimumSize(w, h)
    self.setMaximumSize(w, h)

    @QtCore.pyqtSlot(cv.iplimage)
    def _on_new_frame(self, frame):
    self._frame = cv.CloneImage(frame)
    self.newFrame.emit(self._frame)
    self.update()

    def changeEvent(self, e):
    if e.type() == QtCore.QEvent.EnabledChange:
    if self.isEnabled():
    self._cameraDevice.newFrame.connect(self._on_new_frame)
    else:
    self._cameraDevice.newFrame.disconnect(self._on_new_frame)

    def paintEvent(self, e):
    if self._frame is None:
    return
    painter = QtGui.QPainter(self)
    painter.drawImage(QtCore.QPoint(0, 0), OpenCVQImage(self._frame))

    def get_curr_frame(self):
    return QtGui.QPixmap.fromImage(OpenCVQImage(self._frame))


    class OpenCVQImage(QtGui.QImage):
    def __init__(self, opencv_bgr_img):
    depth, n_channels = opencv_bgr_img.depth, opencv_bgr_img.nChannels
    if depth != cv.IPL_DEPTH_8U or n_channels != 3:
    raise ValueError("the input image must be 8-bit, 3-channel")
    w, h = cv.GetSize(opencv_bgr_img)
    opencv_rgb_img = cv.CreateImage((w, h), depth, n_channels)
    # it's assumed the image is in BGR format
    cv.CvtColor(opencv_bgr_img, opencv_rgb_img, cv.CV_BGR2RGB)
    self._imgData = opencv_rgb_img.tostring()
    super(OpenCVQImage, self).__init__(self._imgData, w, h,
    QtGui.QImage.Format_RGB888)


    class Example(QtGui.QWidget):
    def __init__(self):
    super(Example, self).__init__()
    self.initUI()

    def initUI(self):
    cameraDevice = CameraDevice(cameraId=1, mirrored=True, size=(640, 480))

    cameraWidget1 = CameraWidget(cameraDevice)
    cameraWidget2 = CameraWidget(cameraDevice)
    cameraWidget2.newFrame.connect(self.onNewFrame)

    hbox = QtGui.QHBoxLayout()
    hbox.addWidget(cameraWidget1)
    hbox.addWidget(cameraWidget2)

    self.setLayout(hbox)

    self.setWindowTitle('Buttons')
    self.show()

    @QtCore.pyqtSlot(cv.iplimage)
    def onNewFrame(self, frame):
    cv.CvtColor(frame, frame, cv.CV_RGB2BGR)
    msg = "processed frame"
    font = cv.InitFont(cv.CV_FONT_HERSHEY_DUPLEX, 1.0, 1.0)
    tsize, baseline = cv.GetTextSize(msg, font)
    w, h = cv.GetSize(frame)
    tpt = (w - tsize[0]) / 2, (h - tsize[1]) / 2
    cv.PutText(frame, msg, tpt, font, cv.RGB(255, 255, 0))


    def main():
    app = QtGui.QApplication(sys.argv)
    ex = Example()

    sys.exit(app.exec_())


    if __name__ == "__main__":
    main()