Commit f1df2c00 authored by Matt Clarkson's avatar Matt Clarkson

Issue #2: Added first pass, grabbing charuco markers.

parent e15c6f78
Pipeline #757 failed with stages
in 6 minutes and 41 seconds
......@@ -53,11 +53,15 @@ setup(
install_requires=[
'six>=1.10',
'numpy>=1.11',
'opencv-contrib-python>=3.4.4',
'PySide2>=5.12.0',
'scikit-surgeryimage>=0.1.0',
],
entry_points={
'console_scripts': [
'sksurgeryvideolag=sksurgeryvideoutils.ui.sksurgeryvideolag_command_line:main',
'sksurgerycharucotest=sksurgeryvideoutils.ui.sksurgerycharucotest_command_line:main',
],
},
)
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from sksurgeryvideoutils.ui.sksurgerycharucotest_command_line import main
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))
# coding=utf-8
""" Command line processing for charucotest app. """
import argparse
from sksurgeryvideoutils import __version__
from sksurgeryvideoutils.ui.sksurgerycharucotest_demo import run_charucotest_demo
def main(args=None):
"""Entry point for sksurgerycharucotest application"""
parser = argparse.ArgumentParser(description='sksurgerycharucotest')
parser.add_argument("-c", "--camera",
required=False,
default=0,
type=int,
help="Camera index.")
parser.add_argument("-x", "--x_squares",
required=False,
default=13,
type=int,
help="Number of squares in X direction.")
parser.add_argument("-y", "--y_squares",
required=False,
default=10,
type=int,
help="Number of squares in Y direction.")
parser.add_argument("-d", "--dictionary",
required=True,
type=str,
help="String describing aruco dictionary.")
version_string = __version__
friendly_version_string = version_string if version_string else 'unknown'
parser.add_argument(
"-v", "--version",
action='version',
version='sksurgerycharucotest version ' + friendly_version_string)
args = parser.parse_args(args)
run_charucotest_demo(args.camera,
args.x_squares,
args.y_squares,
args.dictionary
)
# coding=utf-8
""" Demo app, to demo charuco markers."""
import sys
import six
import cv2
from cv2 import aruco
from PySide2 import QtCore, QtWidgets, QtGui
from PySide2.QtCore import Slot
import sksurgeryvideoutils.utils.image_utils as iu
import sksurgeryimage.calibration.aruco as ar
# pylint: disable=too-many-instance-attributes
class CharucoDemoGui(QtWidgets.QWidget):
""" Demo GUI, with 2 QLabel side by side."""
def __init__(self, camera, x_squares, y_squares, dictionary):
super().__init__()
if camera < 0:
raise ValueError('The camera number should be >= 0')
self.cap = cv2.VideoCapture(camera) # pylint: disable=no-member
if not self.cap.isOpened():
raise ValueError("Unable to open camera:" + str(camera))
grabbed, self.frame = self.cap.read()
if not grabbed:
raise RuntimeError("Failed to grab first frame.")
self.dictionary = aruco.Dictionary_get(aruco.DICT_4X4_250)
self.board = aruco.CharucoBoard_create(x_squares,
y_squares,
2,
1,
self.dictionary)
self.layout = QtWidgets.QHBoxLayout()
self.image_label = QtWidgets.QLabel("Image")
self.image_label.setAlignment(QtCore.Qt.AlignCenter)
self.layout.addWidget(self.image_label)
self.setLayout(self.layout)
self.grab = QtCore.QTimer()
self.grab.setInterval(50)
# pylint: disable=maybe-no-member
self.grab.timeout.connect(self.update_image)
self.grab.start()
@Slot()
def update_image(self):
""" Updates the image. """
# Then grab image
grabbed = self.cap.grab()
if not grabbed:
raise RuntimeError("Failed to grab frame number:"
+ str(self.number_frames))
# Then decode image
self.cap.retrieve(self.frame)
# OpenCV does BGR, Qt wants RGB
# pylint: disable=no-member
rgb_frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
greyscale_frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2GRAY)
# Run aruco to detect markers
number_of_markers, marker_corners, marker_ids, \
chessboard_corners, chessboard_ids \
= ar.detect_charuco_points(self.dictionary,
greyscale_frame,
self.board
)
# Draw detected corners back on RGB image.
if chessboard_corners is not None \
and chessboard_ids is not None \
and len(chessboard_corners) \
and len(chessboard_ids):
annotated_frame = ar.draw_charuco_corners(rgb_frame,
chessboard_corners,
chessboard_ids
)
else:
annotated_frame = rgb_frame
# Display annotated RGB image.
pixmap = iu.image_to_pixmap(annotated_frame)
self.image_label.setPixmap(pixmap)
def run_charucotest_demo(camera, width, height, dictionary):
""" Prints command line args, and launches main screen."""
six.print_("Camera:" + str(camera))
six.print_(" Width:" + str(width))
six.print_(" Height:" + str(height))
six.print_("Dictionary:" + str(dictionary))
app = QtWidgets.QApplication([])
widget = CharucoDemoGui(camera, width, height, dictionary)
widget.show()
return sys.exit(app.exec_())
# coding=utf-8
"""Command line processing"""
""" Command line processing for videolag app. """
import argparse
from sksurgeryvideoutils import __version__
......
......@@ -3,11 +3,11 @@
""" Demo app, to show OpenCV video and PySide2 widgets together."""
import sys
import time
import ctypes
import six
import cv2
from PySide2 import QtCore, QtWidgets, QtGui
from PySide2.QtCore import Slot
import sksurgeryvideoutils.utils.image_utils as iu
# pylint: disable=too-many-instance-attributes
......@@ -135,21 +135,7 @@ class DemoGui(QtWidgets.QWidget):
decode_time = time.time()
self.total_time_to_decode += (decode_time - grab_time)
# Workaround for memory leak.
# See: https://bugreports.qt.io/browse/PYSIDE-140
# Should be fixed properly in PySide 5.11.3
# Once we upgrade to 5.11.3, take out the hack on
# the ch and rcount variables, and just create qimage
# and then instantiate pixmap from qimage.
pointer_to_buffer = ctypes.c_char.from_buffer(rgb_frame, 0)
rcount = ctypes.c_long.from_address(id(pointer_to_buffer)).value
qimage = QtGui.QImage(pointer_to_buffer,
rgb_frame.shape[1],
rgb_frame.shape[0],
QtGui.QImage.Format_RGB888)
if sys.version[0] == '3':
ctypes.c_long.from_address(id(pointer_to_buffer)).value = rcount
pixmap = QtGui.QPixmap.fromImage(qimage)
pixmap = iu.image_to_pixmap(rgb_frame)
self.image_label.setPixmap(pixmap)
# Independently work out the total time displaying.
......
# coding=utf-8
import sys
import numpy as np
import ctypes
from PySide2 import QtCore, QtWidgets, QtGui
def image_to_pixmap(image):
"""
Converts an OpenCV image to a Qt pixmap.
:param image: OpenCV image, 3 channel, RGB.
:return: QPixmap
"""
if not isinstance(image, np.ndarray):
raise TypeError('Input should be a numpy nd.array')
if image.shape[2] != 3:
raise ValueError('Input should be 3 channel RGB')
# Workaround for memory leak.
# See: https://bugreports.qt.io/browse/PYSIDE-140
# Should be fixed properly in PySide 5.11.3
# Once we upgrade to 5.11.3, take out the hack on
# the ch and rcount variables, and just create qimage
# and then instantiate pixmap from qimage.
pointer_to_buffer = ctypes.c_char.from_buffer(image, 0)
rcount = ctypes.c_long.from_address(id(pointer_to_buffer)).value
qimage = QtGui.QImage(pointer_to_buffer,
image.shape[1],
image.shape[0],
QtGui.QImage.Format_RGB888)
if sys.version[0] == '3':
ctypes.c_long.from_address(id(pointer_to_buffer)).value = rcount
pixmap = QtGui.QPixmap.fromImage(qimage)
return pixmap
# coding=utf-8
"""sksurgeryarucotest tests"""
from sksurgeryvideoutils.ui.sksurgerycharucotest_demo import run_demo
def test_sksurgeryarucotest():
# placeholder for now.
assert True
# coding=utf-8
import sksurgeryvideoutils.utils.image_utils as iu
def test_image_to_pixmap_greyscale():
pass
def test_image_to_pixmap_rgb():
pass
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment