Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial version of webcam importer, with preview display #2

Merged
merged 4 commits into from
Apr 1, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions glue_exp/importers/webcam/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# This plugin requires OpenCV to be installed, and returns a PIL Image object


def setup():

from glue.logger import logger
try:
import cv2
except ImportError:
logger.info("Could not load webcam importer plugin, since OpenCV is required")
return

from glue.config import importer
from .qt_widget import QtWebcamImporter

@importer("Import from webcam")
def webcam_importer():
wi = QtWebcamImporter()
wi.exec_()
return wi.data

logger.info("Loaded webcam importer plugin")
102 changes: 102 additions & 0 deletions glue_exp/importers/webcam/qt_widget.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import os

from glue.external.qt import QtGui, QtCore
from glue.qt.qtutil import load_ui

from .webcam_helpers import Webcam, frame_to_data

UI_FILE = os.path.join(os.path.dirname(__file__), 'webcam.ui')


class WebcamView(QtGui.QWidget):

def __init__(self, parent=None):

super(WebcamView, self).__init__()

self._frozen = False

self._webcam = Webcam()

self._update_image()

self._timer = QtCore.QTimer(self)
self._timer.timeout.connect(self._update_image)
self._timer.start(100)

def freeze(self):
self._frozen = True

def resume(self):
self._frozen = False

def paintEvent(self, event):

# We need to preserve aspect ratio. Figure out bounding box for
# webcam image.

im_dx = self._image.width()
im_dy = self._image.height()
im_ratio = im_dx / float(im_dy)

wi_dx = self.width()
wi_dy = self.height()
wi_ratio = wi_dx / float(wi_dy)

if wi_ratio > im_ratio: # Need to pad on sides

xmin = wi_dx / 2. - wi_dy / 2. * im_ratio
ymin = 0.
width = wi_dy * im_ratio
height = wi_dy

else: # Need to pad on top/bottom

xmin = 0.
ymin = wi_dy / 2. - wi_dx / 2. / float(im_ratio)
width = wi_dx
height = wi_dx / float(im_ratio)

painter = QtGui.QPainter(self)
painter.drawImage(QtCore.QRect(xmin, ymin, width, height), self._image)


def _update_image(self):
if not self._frozen:
frame = self._webcam.capture_frame()
self._image = QtGui.QImage(frame.tostring(), frame.shape[1], frame.shape[0], QtGui.QImage.Format_RGB888).rgbSwapped()
self._data = frame_to_data(frame)
self.update()


class QtWebcamImporter(QtGui.QDialog):

def __init__(self):
super(QtWebcamImporter, self).__init__()
self.pil_image = None
self.ui = load_ui(UI_FILE, self)
self._webcam_preview = WebcamView()
self.image.addWidget(self._webcam_preview)
self.capture.clicked.connect(self.flip_capture_button)
self.cancel.clicked.connect(self.reject)
self.ok.clicked.connect(self.finalize)
self.ok.setEnabled(False)
self.capture.setDefault(True)
self.data = []

def flip_capture_button(self):
if self._webcam_preview._frozen:
self._webcam_preview.resume()
self.capture.setText("Capture")
self.capture.setDefault(True)
self.ok.setEnabled(False)
else:
self._webcam_preview.freeze()
self.capture.setText("Try again")
self.capture.setDefault(False)
self.ok.setEnabled(True)
self.ok.setDefault(True)

def finalize(self):
self.data = [self._webcam_preview._data]
self.accept()
104 changes: 104 additions & 0 deletions glue_exp/importers/webcam/webcam.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>529</width>
<height>506</height>
</rect>
</property>
<property name="windowTitle">
<string>Webcam Importer</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="image"/>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="capture">
<property name="text">
<string>Capture</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancel">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ok">
<property name="text">
<string>OK</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
20 changes: 20 additions & 0 deletions glue_exp/importers/webcam/webcam_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import cv2

from glue.core import Data

class Webcam(object):

def __init__(self):
self._capture = cv2.VideoCapture(0)

def capture_frame(self):
ret, frame = self._capture.read()
return frame


def frame_to_data(frame):
data = Data(red=frame[::-1,::-1,2],
green=frame[::-1,::-1,1],
blue=frame[::-1,::-1,0])
data.label = "Webcam Snapshot"
return data