moved Pastie so seperate repo
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
Pastie
|
||||||
|
moc_*
|
||||||
|
ui_*
|
119
Pastie.pro
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
#-------------------------------------------------
|
||||||
|
#
|
||||||
|
# Project created by QtCreator 2014-09-12T15:39:17
|
||||||
|
#
|
||||||
|
#-------------------------------------------------
|
||||||
|
|
||||||
|
QT += core gui opengl multimedia
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
TARGET = Pastie
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
ICON = resources/Mr-potato.icns
|
||||||
|
|
||||||
|
SOURCES += main.cpp\
|
||||||
|
mainwindow.cpp \
|
||||||
|
camera.cpp \
|
||||||
|
imagelist.cpp \
|
||||||
|
image.cpp \
|
||||||
|
viewer.cpp \
|
||||||
|
debugstream.cpp \
|
||||||
|
filterlist.cpp \
|
||||||
|
source.cpp \
|
||||||
|
tabcalibration.cpp \
|
||||||
|
tabimages.cpp \
|
||||||
|
tabcamera.cpp \
|
||||||
|
tabfilters.cpp \
|
||||||
|
tabpads.cpp \
|
||||||
|
console.cpp \
|
||||||
|
painter.cpp \
|
||||||
|
filters/maxchannel.cpp \
|
||||||
|
filters/normalize.cpp \
|
||||||
|
filters/shapedetect.cpp \
|
||||||
|
filters/setting.cpp \
|
||||||
|
filters/result.cpp \
|
||||||
|
filters/blur.cpp \
|
||||||
|
filters/watershed.cpp
|
||||||
|
|
||||||
|
HEADERS += mainwindow.h \
|
||||||
|
camera.h \
|
||||||
|
imagelist.h \
|
||||||
|
image.h \
|
||||||
|
viewer.h \
|
||||||
|
debugstream.h \
|
||||||
|
filterlist.h \
|
||||||
|
source.h \
|
||||||
|
tabcalibration.h \
|
||||||
|
tabimages.h \
|
||||||
|
tabcamera.h \
|
||||||
|
tabfilters.h \
|
||||||
|
tabpads.h \
|
||||||
|
console.h \
|
||||||
|
cast.h \
|
||||||
|
painter.h \
|
||||||
|
filters.h \
|
||||||
|
filters/maxchannel.h \
|
||||||
|
filters/normalize.h \
|
||||||
|
filters/shapedetect.h \
|
||||||
|
filters/setting.h \
|
||||||
|
filters/result.h \
|
||||||
|
filters/blur.h \
|
||||||
|
filters/watershed.h
|
||||||
|
|
||||||
|
SOURCES += filters/filter.cpp \
|
||||||
|
filters/undistort.cpp \
|
||||||
|
filters/threshold.cpp \
|
||||||
|
filters/kmeans.cpp \
|
||||||
|
filters/histequalize.cpp \
|
||||||
|
filters/morph.cpp \
|
||||||
|
filters/convert.cpp \
|
||||||
|
filters/pattern.cpp \
|
||||||
|
filters/padfilter.cpp \
|
||||||
|
filters/edgedetect.cpp \
|
||||||
|
filters/channel.cpp \
|
||||||
|
filters/perspective.cpp
|
||||||
|
|
||||||
|
HEADERS += filters/filter.h \
|
||||||
|
filters/kmeans.h \
|
||||||
|
filters/threshold.h \
|
||||||
|
filters/undistort.h \
|
||||||
|
filters/histequalize.h \
|
||||||
|
filters/morph.h \
|
||||||
|
filters/convert.h \
|
||||||
|
filters/pattern.h \
|
||||||
|
filters/edgedetect.h \
|
||||||
|
filters/channel.h \
|
||||||
|
filters/perspective.h \
|
||||||
|
filters/padfilter.h
|
||||||
|
|
||||||
|
FORMS += mainwindow.ui \
|
||||||
|
about.ui \
|
||||||
|
imagelist.ui \
|
||||||
|
tabcalibration.ui \
|
||||||
|
tabimages.ui \
|
||||||
|
tabcamera.ui \
|
||||||
|
tabfilters.ui \
|
||||||
|
tabpads.ui
|
||||||
|
|
||||||
|
# OpenCV
|
||||||
|
INCLUDEPATH += /usr/local/include
|
||||||
|
|
||||||
|
LIBS += -L/usr/local/lib
|
||||||
|
LIBS += -lopencv_core \
|
||||||
|
-lopencv_highgui \
|
||||||
|
-lopencv_imgproc\
|
||||||
|
-lopencv_imgcodecs \
|
||||||
|
-lopencv_videoio \
|
||||||
|
-lopencv_calib3d \
|
||||||
|
-lopencv_features2d
|
||||||
|
|
||||||
|
RESOURCES += \
|
||||||
|
images.qrc \
|
||||||
|
texts.qrc
|
||||||
|
|
||||||
|
OTHER_FILES +=
|
||||||
|
|
||||||
|
CONFIG += c++11
|
||||||
|
QMAKE_MAC_SDK = macosx10.10
|
263
Pastie.pro.user
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE QtCreatorProject>
|
||||||
|
<!-- Written by QtCreator 3.3.0, 2014-12-20T13:25:42. -->
|
||||||
|
<qtcreator>
|
||||||
|
<data>
|
||||||
|
<variable>EnvironmentId</variable>
|
||||||
|
<value type="QByteArray">{8f80b8d2-0f3b-47b3-a327-f81ae0873a3f}</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||||
|
<value type="int">0</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||||
|
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||||
|
<value type="QString" key="language">Cpp</value>
|
||||||
|
<valuemap type="QVariantMap" key="value">
|
||||||
|
<value type="QByteArray" key="CurrentPreferences">qt2</value>
|
||||||
|
</valuemap>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="EditorConfiguration.CodeStyle.Count">1</value>
|
||||||
|
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||||
|
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||||
|
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||||
|
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||||
|
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||||
|
<valuemap type="QVariantMap"/>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||||
|
<valuemap type="QVariantMap">
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.4.0 clang 64bit</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.4.0 clang 64bit</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.54.clang_64_kit</value>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/stv0g/workspace/rwth-dbv/code/build-Pastie-Desktop_Qt_5_4_0_clang_64bit-Debug</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
|
||||||
|
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
|
||||||
|
<value type="QString">-w</value>
|
||||||
|
<value type="QString">-r</value>
|
||||||
|
</valuelist>
|
||||||
|
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
|
||||||
|
<value type="QString">-w</value>
|
||||||
|
<value type="QString">-r</value>
|
||||||
|
</valuelist>
|
||||||
|
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||||
|
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
||||||
|
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
||||||
|
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/stv0g/workspace/rwth-dbv/code/build-Pastie-Desktop_Qt_5_4_0_clang_64bit-Release</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibraryAuto">true</value>
|
||||||
|
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||||
|
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
|
||||||
|
<value type="QString">-w</value>
|
||||||
|
<value type="QString">-r</value>
|
||||||
|
</valuelist>
|
||||||
|
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||||
|
</valuemap>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||||
|
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
|
||||||
|
<value type="QString">-w</value>
|
||||||
|
<value type="QString">-r</value>
|
||||||
|
</valuelist>
|
||||||
|
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||||
|
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||||
|
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||||
|
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
||||||
|
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||||
|
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deployment</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Lokales Deployment</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
|
||||||
|
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
||||||
|
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
||||||
|
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
||||||
|
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
||||||
|
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
||||||
|
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
||||||
|
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
||||||
|
<value type="int">0</value>
|
||||||
|
<value type="int">1</value>
|
||||||
|
<value type="int">2</value>
|
||||||
|
<value type="int">3</value>
|
||||||
|
<value type="int">4</value>
|
||||||
|
<value type="int">5</value>
|
||||||
|
<value type="int">6</value>
|
||||||
|
<value type="int">7</value>
|
||||||
|
<value type="int">8</value>
|
||||||
|
<value type="int">9</value>
|
||||||
|
<value type="int">10</value>
|
||||||
|
<value type="int">11</value>
|
||||||
|
<value type="int">12</value>
|
||||||
|
<value type="int">13</value>
|
||||||
|
<value type="int">14</value>
|
||||||
|
</valuelist>
|
||||||
|
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||||
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Pastie</value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||||
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/Users/stv0g/workspace/rwth-dbv/code/pastie/Pastie.pro</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments">google/*</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">Pastie.pro</value>
|
||||||
|
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
|
||||||
|
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">false</value>
|
||||||
|
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory">/Users/stv0g/workspace/rwth-dbv/data</value>
|
||||||
|
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||||
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
</valuemap>
|
||||||
|
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||||
|
</valuemap>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||||
|
<value type="int">1</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||||
|
<value type="int">18</value>
|
||||||
|
</data>
|
||||||
|
<data>
|
||||||
|
<variable>Version</variable>
|
||||||
|
<value type="int">18</value>
|
||||||
|
</data>
|
||||||
|
</qtcreator>
|
143
about.ui
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>AboutDialog</class>
|
||||||
|
<widget class="QDialog" name="AboutDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>585</width>
|
||||||
|
<height>254</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>About</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="3" column="2">
|
||||||
|
<widget class="QPushButton" name="pushButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Close</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QPlainTextEdit" name="plainTextEdit">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="plainText">
|
||||||
|
<string>Seminar Bildverarbeitung und Inhaltsanalyse
|
||||||
|
Lehrstuhl für Bildverarbeitung
|
||||||
|
RWTH Aachen
|
||||||
|
|
||||||
|
Steffen Vogel
|
||||||
|
- Mail: steffen.vogel@rwth-aachen.de
|
||||||
|
- Web: http:///www.steffenvogel.de
|
||||||
|
|
||||||
|
Wintersemester 2014/15</string>
|
||||||
|
</property>
|
||||||
|
<property name="backgroundVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QWidget" name="widget" native="true">
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>128</width>
|
||||||
|
<height>128</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>192</width>
|
||||||
|
<height>192</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="baseSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="images.qrc">:/icons/resources/Mr-potato.png</pixmap>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="margin">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<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 row="1" column="1">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="images.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>pushButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>AboutDialog</receiver>
|
||||||
|
<slot>close()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>400</x>
|
||||||
|
<y>176</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>294</x>
|
||||||
|
<y>186</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
76
camera.cpp
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
#include <opencv2/calib3d.hpp>
|
||||||
|
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
#include "filters/pattern.h"
|
||||||
|
#include "camera.h"
|
||||||
|
#include "image.h"
|
||||||
|
|
||||||
|
Camera::Camera(Source *s) :
|
||||||
|
source(s),
|
||||||
|
calibrated(false)
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::reset()
|
||||||
|
{
|
||||||
|
calibrated = false;
|
||||||
|
avgReprErr = 0;
|
||||||
|
distCoeffs = Mat::zeros(8, 1, CV_32F);
|
||||||
|
matrix = Mat::eye(3, 3, CV_32F);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Camera::calibrate(list<Image *> imgs, Pattern *pattern)
|
||||||
|
{
|
||||||
|
vector<vector<Point2f>> imagePoints;
|
||||||
|
vector<vector<Point3f>> objectPoints;
|
||||||
|
vector<Mat> rvecs, tvecs;
|
||||||
|
|
||||||
|
if (calibrated) {
|
||||||
|
qWarning() << "Camera is already calibrated. Reset first!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto img : imgs) {
|
||||||
|
img->applyFilter(pattern);
|
||||||
|
PatternResult *result = (PatternResult *) img->getResult(pattern);
|
||||||
|
|
||||||
|
if (result->isFound())
|
||||||
|
imagePoints.push_back(result->getPoints());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imagePoints.size() < 5) {
|
||||||
|
qWarning() << "Only " << imagePoints.size() << " patterns detected. This is not enough!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill in vector of calibration rig points */
|
||||||
|
std::vector<Point3f> planar = pattern->getPoints();
|
||||||
|
for (unsigned i = 0; i < imagePoints.size(); i++)
|
||||||
|
objectPoints.push_back(planar);
|
||||||
|
|
||||||
|
/* Calculate camera matrix and distortion coefficients */
|
||||||
|
calibrateCamera(objectPoints, imagePoints, source->getSize(), matrix, distCoeffs, rvecs, tvecs);
|
||||||
|
|
||||||
|
/* Calculate average reprojection error */
|
||||||
|
double totalErr = 0;
|
||||||
|
int totalPoints = 0;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < imagePoints.size(); i++) {
|
||||||
|
std::vector<Point2f> imagePoints2;
|
||||||
|
|
||||||
|
projectPoints(objectPoints[i], rvecs[i], tvecs[i], matrix, distCoeffs, imagePoints2);
|
||||||
|
|
||||||
|
totalErr += pow(norm(imagePoints[i], imagePoints2, NORM_L2), 2);
|
||||||
|
totalPoints += objectPoints[i].size();
|
||||||
|
}
|
||||||
|
|
||||||
|
avgReprErr = totalErr / totalPoints;
|
||||||
|
calibrated = true;
|
||||||
|
|
||||||
|
qDebug() << "Calibration completed: Found " << imagePoints.size() << " patterns in " << imgs.size() << " images";
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
41
camera.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#ifndef CAMERA_H
|
||||||
|
#define CAMERA_H
|
||||||
|
|
||||||
|
#include <opencv2/videoio.hpp>
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#include "source.h"
|
||||||
|
#include "filters/pattern.h"
|
||||||
|
|
||||||
|
using namespace cv;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class Image;
|
||||||
|
|
||||||
|
class Camera
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Camera(Source *s);
|
||||||
|
|
||||||
|
bool calibrate(list<Image *> imgs, Pattern *pattern);
|
||||||
|
|
||||||
|
/* Getters */
|
||||||
|
const Mat & getDistCoeffs() { return distCoeffs; }
|
||||||
|
const Mat & getMatrix() { return matrix; }
|
||||||
|
double getAvgReprErr() { return avgReprErr; }
|
||||||
|
bool isCalibrated() { return calibrated; }
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
Source *source;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool calibrated;
|
||||||
|
double avgReprErr;
|
||||||
|
|
||||||
|
Mat matrix;
|
||||||
|
Mat distCoeffs;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CAMERA_H
|
58
cast.h
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#ifndef CAST_H
|
||||||
|
#define CAST_H
|
||||||
|
|
||||||
|
#include <opencv2/core.hpp>
|
||||||
|
#include <opencv2/imgproc.hpp>
|
||||||
|
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
#include <QTransform>
|
||||||
|
#include <QSize>
|
||||||
|
#include <QPoint>
|
||||||
|
#include <QRect>
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
inline QImage toQImage(const Mat &mat)
|
||||||
|
{
|
||||||
|
Mat *conv = new Mat;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
switch (mat.channels()) {
|
||||||
|
case 3: cvtColor(mat, *conv, COLOR_RGB2RGBA); break;
|
||||||
|
case 1: cvtColor(mat, *conv, COLOR_GRAY2RGBA); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QImage((const unsigned char *) conv->data, conv->cols, conv->rows, conv->step,
|
||||||
|
QImage::Format_RGB32, [] (void * data) { ((Mat *) data)->release(); }, conv);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QTransform toQTransform(const Mat &m)
|
||||||
|
{
|
||||||
|
return QTransform(
|
||||||
|
m.at<float>(0,0), m.at<float>(0,1), m.at<float>(0,2),
|
||||||
|
m.at<float>(1,0), m.at<float>(1,1), m.at<float>(1,2),
|
||||||
|
m.at<float>(2,0), m.at<float>(2,1), m.at<float>(2,2));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QSize toQt(const Size2i &s) { return QSize (s.width, s.height); }
|
||||||
|
inline QSizeF toQt(const Size2d &s) { return QSizeF(s.width, s.height); }
|
||||||
|
|
||||||
|
inline QPoint toQt(const Point2i &p) { return QPoint (p.x, p.y); }
|
||||||
|
inline QPointF toQt(const Point2d &p) { return QPointF(p.x, p.y); }
|
||||||
|
|
||||||
|
inline QRect toQt(const Rect2i &r) { return QRect (r.x, r.y, r.width, r.height); }
|
||||||
|
inline QRectF toQt(const Rect2d &r) { return QRectF(r.x, r.y, r.width, r.height); }
|
||||||
|
|
||||||
|
inline Size2i toCv(const QSize &s) { return Size2i(s.width(), s.height()); }
|
||||||
|
inline Size2d toCv(const QSizeF &s) { return Size2d(s.width(), s.height()); }
|
||||||
|
|
||||||
|
inline Point2i toCv(const QPoint &p) { return Point2i(p.x(), p.y()); }
|
||||||
|
inline Point2d toCv(const QPointF &p) { return Point2d(p.x(), p.y()); }
|
||||||
|
|
||||||
|
inline Rect2i toCv(const QRect &r) { return Rect2i(r.x(), r.y(), r.width(), r.height()); }
|
||||||
|
inline Rect2d toCv(const QRectF &r) { return Rect2d(r.x(), r.y(), r.width(), r.height()); }
|
||||||
|
|
||||||
|
#endif // CAST_H
|
25
console.cpp
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#include <QtDebug>
|
||||||
|
#include <QScrollBar>
|
||||||
|
|
||||||
|
#include "console.h"
|
||||||
|
|
||||||
|
Console::Console(QWidget *parent) :
|
||||||
|
QPlainTextEdit(parent),
|
||||||
|
qcout(std::cout, QtDebugMsg), /* redirect standard outputs to console */
|
||||||
|
qcerr(std::cerr, QtCriticalMsg)
|
||||||
|
{
|
||||||
|
DebugStream::registerConsole(this);
|
||||||
|
DebugStream::registerHandler();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::setup()
|
||||||
|
{
|
||||||
|
QFile intro(":/resources/intro.html");
|
||||||
|
if (!intro.open(QFile::ReadOnly))
|
||||||
|
qCritical() << "Failed to open intro.html resource";
|
||||||
|
|
||||||
|
appendHtml(intro.readAll());
|
||||||
|
moveCursor(QTextCursor::Start);
|
||||||
|
}
|
20
console.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef CONSOLE_H
|
||||||
|
#define CONSOLE_H
|
||||||
|
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
|
||||||
|
#include "debugstream.h"
|
||||||
|
|
||||||
|
class Console : public QPlainTextEdit
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Console(QWidget *parent = 0);
|
||||||
|
|
||||||
|
void setup();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DebugStream qcout;
|
||||||
|
DebugStream qcerr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CONSOLE_H
|
98
debugstream.cpp
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
#include "debugstream.h"
|
||||||
|
|
||||||
|
QPlainTextEdit *DebugStream::console;
|
||||||
|
|
||||||
|
DebugStream::DebugStream(std::ostream &s, QtMsgType t) :
|
||||||
|
stream(s),
|
||||||
|
type(t)
|
||||||
|
{
|
||||||
|
oldBuf = s.rdbuf();
|
||||||
|
s.rdbuf(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugStream::~DebugStream()
|
||||||
|
{
|
||||||
|
if (!string.empty())
|
||||||
|
handler(type, QString::fromStdString(string));
|
||||||
|
|
||||||
|
stream.rdbuf(oldBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::streamsize DebugStream::xsputn(const char *p, std::streamsize n)
|
||||||
|
{
|
||||||
|
string.append(p, p + n);
|
||||||
|
|
||||||
|
size_t pos = 0;
|
||||||
|
while (pos != std::string::npos) {
|
||||||
|
pos = string.find('\n');
|
||||||
|
if (pos != std::string::npos) {
|
||||||
|
std::string tmp(string.begin(), string.begin() + pos);
|
||||||
|
handler(type, QString::fromStdString(tmp));
|
||||||
|
string. erase(string.begin(), string.begin() + pos + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DebugStream::overflow(int v)
|
||||||
|
{
|
||||||
|
if (v == '\n') {
|
||||||
|
handler(type, QString::fromStdString(string));
|
||||||
|
string.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
string += v;
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DebugStream::format(QString msg, QtMsgType type)
|
||||||
|
{
|
||||||
|
QString out("<pre><div style='font-weight: bold; color: %1'>[%2]</div> %3</pre>");
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case QtDebugMsg: out = out.arg("Gray").arg("Debug "); break;
|
||||||
|
case QtWarningMsg: out = out.arg("Orange").arg("Warning "); break;
|
||||||
|
case QtCriticalMsg: out = out.arg("DarkRed").arg("Critical"); break;
|
||||||
|
case QtFatalMsg: out = out.arg("Magenta").arg("Fatal "); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.arg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugStream::registerHandler()
|
||||||
|
{
|
||||||
|
qInstallMessageHandler(DebugStream::handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugStream::registerConsole(QPlainTextEdit *pte)
|
||||||
|
{
|
||||||
|
console = pte;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugStream::handler(QtMsgType type, const QString &msg)
|
||||||
|
{
|
||||||
|
static int dropped;
|
||||||
|
static int next = 1;
|
||||||
|
if (msg == "Camera dropped frame!") {
|
||||||
|
if (++dropped == next) {
|
||||||
|
next = next + next*2;
|
||||||
|
printf("Camera dropped %u frames! Next %u\n\n", dropped, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (console)
|
||||||
|
console->appendHtml(format(msg, type));
|
||||||
|
else
|
||||||
|
printf("%s\n", (const char *) QByteArray(msg.toLocal8Bit().constData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugStream::handler(QtMsgType type, const QMessageLogContext &, const QString &msg)
|
||||||
|
{
|
||||||
|
handler(type, msg);
|
||||||
|
}
|
36
debugstream.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef DEBUGSTREAM_H
|
||||||
|
#define DEBUGSTREAM_H
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class DebugStream : public std::basic_streambuf<char>
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
DebugStream(std::ostream &stream, QtMsgType type);
|
||||||
|
~DebugStream();
|
||||||
|
|
||||||
|
static QString format(QString msg, QtMsgType type = QtDebugMsg);
|
||||||
|
static void registerConsole(QPlainTextEdit *);
|
||||||
|
static void registerHandler();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int overflow(int_type v);
|
||||||
|
std::streamsize xsputn(const char *p, std::streamsize n);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::ostream &stream;
|
||||||
|
std::streambuf *oldBuf;
|
||||||
|
std::string string;
|
||||||
|
|
||||||
|
QtMsgType type;
|
||||||
|
|
||||||
|
static void handler(QtMsgType type, const QString &msg);
|
||||||
|
static void handler(QtMsgType type, const QMessageLogContext &, const QString &str);
|
||||||
|
static QPlainTextEdit *console;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DEBUGSTREAM_H
|
131
filterlist.cpp
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
#include "filterlist.h"
|
||||||
|
|
||||||
|
FilterList::FilterList(QObject *parent) :
|
||||||
|
QAbstractTableModel(parent),
|
||||||
|
selection(this)
|
||||||
|
{
|
||||||
|
connect(&selection, &QItemSelectionModel::currentChanged, [&] (QModelIndex i, QModelIndex) {
|
||||||
|
emit filterSelected(at(i.row()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
int FilterList::rowCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int FilterList::columnCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant FilterList::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
Filter *filter = at(index.row());
|
||||||
|
Result *result = filter->getLastResult();
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
case Qt::EditRole:
|
||||||
|
switch (index.column()) {
|
||||||
|
case 2: return filter->getName();
|
||||||
|
case 3: return (filter->isEnabled() && result) ? result->getResult() : QVariant();
|
||||||
|
case 4: return (filter->isEnabled()) ? QString::number(filter->getTime() * 1e-6, 'g', 3) : QVariant();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::CheckStateRole:
|
||||||
|
switch (index.column()) {
|
||||||
|
case 0: return (filter->isEnabled()) ? Qt::Checked: Qt::Unchecked;
|
||||||
|
case 1: return (filter->isShown()) ? Qt::Checked: Qt::Unchecked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FilterList::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
|
{
|
||||||
|
Filter *filter = at(index.row());
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case Qt::CheckStateRole:
|
||||||
|
switch (index.column()) {
|
||||||
|
case 0: filter->setEnabled(value == Qt::Checked);
|
||||||
|
case 1: filter->setShow(value == Qt::Checked); break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit filtersChanged();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant FilterList::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
if (orientation == Qt::Horizontal) {
|
||||||
|
switch (section) {
|
||||||
|
case 0: return QString(tr("Enabled"));
|
||||||
|
case 1: return QString(tr("Show"));
|
||||||
|
case 2: return QString(tr("Filter"));
|
||||||
|
case 3: return QString(tr("Result"));
|
||||||
|
case 4: return QString(tr("Time [mSec]"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags FilterList::flags(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
Qt::ItemFlags flags = Qt::ItemIsEnabled;
|
||||||
|
|
||||||
|
switch (index.column()) {
|
||||||
|
case 0:
|
||||||
|
case 1: flags |= Qt::ItemIsUserCheckable; break;
|
||||||
|
case 2: flags |= Qt::ItemIsSelectable; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterList::add(Filter *filter)
|
||||||
|
{
|
||||||
|
beginInsertRows(QModelIndex(), size(), size());
|
||||||
|
push_back(filter);
|
||||||
|
endInsertRows();
|
||||||
|
|
||||||
|
connect(filter, SIGNAL(filterChanged()), this, SIGNAL(filtersChanged()));
|
||||||
|
|
||||||
|
emit filterAdded(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterList::execute(Image *img)
|
||||||
|
{
|
||||||
|
img->filtered = img->original.clone();
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (auto filter : *this) {
|
||||||
|
img->applyFilter(filter);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
qCritical("%s", e.msg.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update times and results */
|
||||||
|
emit dataChanged(
|
||||||
|
createIndex(0, 4),
|
||||||
|
createIndex(size(), 4)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilterList::reset()
|
||||||
|
{
|
||||||
|
for (Filter *filter : *this)
|
||||||
|
filter->reset();
|
||||||
|
}
|
41
filterlist.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#ifndef FILTERLIST_H
|
||||||
|
#define FILTERLIST_H
|
||||||
|
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
#include <QItemSelection>
|
||||||
|
|
||||||
|
#include "filters/filter.h"
|
||||||
|
|
||||||
|
class FilterList :
|
||||||
|
public QAbstractTableModel,
|
||||||
|
public QList<Filter *>
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
FilterList(QObject *parent = 0);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &) const;
|
||||||
|
int columnCount(const QModelIndex &) const;
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||||
|
Qt::ItemFlags flags(const QModelIndex & index) const;
|
||||||
|
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||||
|
|
||||||
|
void add(Filter *filt);
|
||||||
|
void execute(Image *img);
|
||||||
|
|
||||||
|
QItemSelectionModel selection;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void filtersChanged();
|
||||||
|
void filterSelected(Filter *filter);
|
||||||
|
void filterAdded(Filter *filter);
|
||||||
|
void filterRemoved(Filter *filter);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FILTERLIST_H
|
22
filters.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef FILTERS_H
|
||||||
|
#define FILTERS_H
|
||||||
|
|
||||||
|
#include "filters/blur.h"
|
||||||
|
#include "filters/channel.h"
|
||||||
|
#include "filters/convert.h"
|
||||||
|
#include "filters/edgedetect.h"
|
||||||
|
#include "filters/fourier.h"
|
||||||
|
#include "filters/histequalize.h"
|
||||||
|
#include "filters/kmeans.h"
|
||||||
|
#include "filters/maxchannel.h"
|
||||||
|
#include "filters/morph.h"
|
||||||
|
#include "filters/normalize.h"
|
||||||
|
#include "filters/pattern.h"
|
||||||
|
#include "filters/perspective.h"
|
||||||
|
#include "filters/shapedetect.h"
|
||||||
|
#include "filters/threshold.h"
|
||||||
|
#include "filters/undistort.h"
|
||||||
|
#include "filters/watershed.h"
|
||||||
|
|
||||||
|
#endif // FILTERS_H
|
||||||
|
|
55
filters/blur.cpp
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#include <opencv2/imgproc.hpp>
|
||||||
|
|
||||||
|
#include "blur.h"
|
||||||
|
|
||||||
|
Blur::Blur(enum Type t, Size ks, double sp, double clr, double si, int bdr) :
|
||||||
|
type(t),
|
||||||
|
size(ks),
|
||||||
|
border(bdr),
|
||||||
|
sigma(si),
|
||||||
|
color(clr),
|
||||||
|
space(sp)
|
||||||
|
{
|
||||||
|
QMap<int, QString> mapType;
|
||||||
|
QMap<int, QString> mapBorder;
|
||||||
|
|
||||||
|
mapType[BILATERAL] = "Bilateral";
|
||||||
|
//mapType[BILATERAL_ADAPTIVE] = "Adaptive Bilateral";
|
||||||
|
mapType[BOX] = "Box";
|
||||||
|
mapType[BOX_NORMALIZED] = "Box Normalized";
|
||||||
|
mapType[GAUSSIAN] = "Gaussian";
|
||||||
|
mapType[MEDIAN] = "Median";
|
||||||
|
|
||||||
|
mapBorder[BORDER_DEFAULT] = "Default";
|
||||||
|
//mapBorder[BORDER_CONSTANT] = "Constant";
|
||||||
|
//mapBorder[BORDER_REPLICATE] = "Replicate";
|
||||||
|
mapBorder[BORDER_ISOLATED] = "Isolated";
|
||||||
|
mapBorder[BORDER_REFLECT] = "Reflect";
|
||||||
|
mapBorder[BORDER_REFLECT_101] = "Reflect 101";
|
||||||
|
mapBorder[BORDER_WRAP] = "Wrap";
|
||||||
|
|
||||||
|
settings["Type"] = new EnumSetting(this, (int&) type, mapType);
|
||||||
|
settings["Border"] = new EnumSetting(this, (int&) border, mapBorder);
|
||||||
|
settings["Kernel Size"] = new SizeSetting(this, size);
|
||||||
|
settings["Space"] = new DoubleSetting(this, space);
|
||||||
|
settings["Color"] = new DoubleSetting(this, color);
|
||||||
|
settings["Sigma"] = new DoubleSetting(this, sigma);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result * Blur::applyInternal(Image *img)
|
||||||
|
{
|
||||||
|
Mat m = img->filtered.clone();
|
||||||
|
Mat &n = img->filtered;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case BILATERAL: bilateralFilter(m, n, -1, space, color); break;
|
||||||
|
case BILATERAL_ADAPTIVE: break; // FIXME adaptiveBilateralFilter(m, n, size, color, space); break;
|
||||||
|
case BOX: boxFilter(m, n, -1, size, anchor, true, border); break;
|
||||||
|
case BOX_NORMALIZED: blur(m, n, size, anchor, border); break;
|
||||||
|
case GAUSSIAN: GaussianBlur(m, n, size, sigma, 0, border); break;
|
||||||
|
case MEDIAN: medianBlur(m, n, size.width); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
36
filters/blur.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef BLUR_H
|
||||||
|
#define BLUR_H
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
class Blur : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
BILATERAL,
|
||||||
|
BILATERAL_ADAPTIVE,
|
||||||
|
BOX,
|
||||||
|
BOX_NORMALIZED,
|
||||||
|
GAUSSIAN,
|
||||||
|
MEDIAN
|
||||||
|
};
|
||||||
|
|
||||||
|
Blur(enum Type t, Size ks, double sp = 10, double clr = 20, double sigma = 2, int bdr = BORDER_DEFAULT);
|
||||||
|
|
||||||
|
QString getName() const { return "Blur"; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Result * applyInternal(Image *img);
|
||||||
|
|
||||||
|
enum Blur::Type type;
|
||||||
|
|
||||||
|
Size size;
|
||||||
|
Point anchor = Point(-1, -1);
|
||||||
|
int border;
|
||||||
|
|
||||||
|
double sigma;
|
||||||
|
double color;
|
||||||
|
double space;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BLUR_H
|
22
filters/channel.cpp
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#include <opencv2/imgproc.hpp>
|
||||||
|
|
||||||
|
#include "channel.h"
|
||||||
|
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
Channel::Channel(int ch) :
|
||||||
|
channel(ch)
|
||||||
|
{
|
||||||
|
settings["Channel"] = new IntegerSetting(this, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result * Channel::applyInternal(Image *img)
|
||||||
|
{
|
||||||
|
Mat channels[3];
|
||||||
|
split(img->filtered, channels);
|
||||||
|
|
||||||
|
img->filtered = channels[(int) channel];
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
19
filters/channel.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef CHANNEL_H
|
||||||
|
#define CHANNEL_H
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
class Channel : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Channel(int ch);
|
||||||
|
|
||||||
|
QString getName() const { return "Channel"; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Result * applyInternal(Image *img);
|
||||||
|
|
||||||
|
int channel;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CHANNEL_H
|
28
filters/convert.cpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#include "convert.h"
|
||||||
|
|
||||||
|
Convert::Convert(int c) :
|
||||||
|
Filter(),
|
||||||
|
code(c)
|
||||||
|
{
|
||||||
|
QMap<int, QString> mapCode;
|
||||||
|
mapCode[COLOR_BGR2HSV] = "BGR to HSV";
|
||||||
|
mapCode[COLOR_BGR2GRAY] = "BGR to Gray";
|
||||||
|
mapCode[COLOR_BGR2Lab] = "BGR to Lab";
|
||||||
|
mapCode[COLOR_BGR2Luv] = "BGR to Luv";
|
||||||
|
mapCode[COLOR_BGR2HLS] = "BGR to HLS";
|
||||||
|
mapCode[COLOR_BGR2YUV] = "BGR to YUV";
|
||||||
|
mapCode[COLOR_BGR2YCrCb]= "BGR to YCrCb";
|
||||||
|
// FIXME add more codes
|
||||||
|
|
||||||
|
settings["Code"] = new EnumSetting(this, code, mapCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result * Convert::applyInternal(Image *img)
|
||||||
|
{
|
||||||
|
Mat dest;
|
||||||
|
cvtColor(img->filtered, dest, code);
|
||||||
|
img->filtered = dest;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
19
filters/convert.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef CONVERT_H
|
||||||
|
#define CONVERT_H
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
class Convert : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Convert(int code);
|
||||||
|
|
||||||
|
QString getName() const { return "Convert"; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Result * applyInternal(Image *img);
|
||||||
|
|
||||||
|
int code;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CONVERT_H
|
19
filters/edgedetect.cpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include "edgedetect.h"
|
||||||
|
|
||||||
|
#include <opencv2/imgproc.hpp>
|
||||||
|
|
||||||
|
EdgeDetect::EdgeDetect(double t, double r) :
|
||||||
|
threshold(t),
|
||||||
|
ratio(r)
|
||||||
|
{
|
||||||
|
settings["Threshold"] = new DoubleSetting(this, threshold);
|
||||||
|
settings["Ratio"] = new DoubleSetting(this, ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result * EdgeDetect::applyInternal(Image *img)
|
||||||
|
{
|
||||||
|
Canny(img->filtered, img->filtered, threshold, threshold * ratio);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
20
filters/edgedetect.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef EDGEDETECT_H
|
||||||
|
#define EDGEDETECT_H
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
class EdgeDetect : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EdgeDetect(double t, double r);
|
||||||
|
|
||||||
|
QString getName() const { return "EdgeDetect"; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Result * applyInternal(Image *img);
|
||||||
|
|
||||||
|
double threshold;
|
||||||
|
double ratio;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDGEDETECT_H
|
40
filters/filter.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#include <QElapsedTimer>
|
||||||
|
#include <QFormLayout>
|
||||||
|
|
||||||
|
#include "cast.h"
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
Filter::~Filter()
|
||||||
|
{
|
||||||
|
delete widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget * Filter::getWidget(QWidget *parent)
|
||||||
|
{
|
||||||
|
if (!widget) {
|
||||||
|
widget = new QWidget(parent);
|
||||||
|
|
||||||
|
QFormLayout *layout = new QFormLayout(widget);
|
||||||
|
layout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
|
||||||
|
|
||||||
|
for (QString key : settings.keys())
|
||||||
|
layout->addRow(key, settings[key]->getWidget(widget));
|
||||||
|
}
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result * Filter::apply(Image *img)
|
||||||
|
{
|
||||||
|
QElapsedTimer timer;
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
timer.start();
|
||||||
|
result = applyInternal(img); /* Virtual call */
|
||||||
|
time = timer.nsecsElapsed();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
57
filters/filter.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#ifndef FILTER_H
|
||||||
|
#define FILTER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <opencv2/core.hpp>
|
||||||
|
|
||||||
|
#include <QVector>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "painter.h"
|
||||||
|
#include "image.h"
|
||||||
|
#include "result.h"
|
||||||
|
#include "setting.h"
|
||||||
|
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
class Filter : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~Filter();
|
||||||
|
|
||||||
|
Result * apply(Image *img);
|
||||||
|
|
||||||
|
QWidget * getWidget(QWidget *parent = 0);
|
||||||
|
|
||||||
|
/* Setter */
|
||||||
|
void setEnabled(bool e) { enabled = e; }
|
||||||
|
void setShow(bool s) { show = s; }
|
||||||
|
|
||||||
|
/* Getter */
|
||||||
|
bool isEnabled() const { return enabled; }
|
||||||
|
bool isShown() const { return show; }
|
||||||
|
long getTime() const { return time; }
|
||||||
|
Result * getLastResult() const { return result; }
|
||||||
|
virtual QString getName() const = 0;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void reset() { }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void filterChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool enabled = true;
|
||||||
|
bool show = true;
|
||||||
|
long time = 0; /* in uSecs */
|
||||||
|
|
||||||
|
Result *result = NULL;
|
||||||
|
QWidget *widget = NULL;
|
||||||
|
QMap<QString, Setting*> settings;
|
||||||
|
virtual Result * applyInternal(Image *img) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FILTER_H
|
14
filters/fourier.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef FOURIER_H
|
||||||
|
#define FOURIER_H
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
class Fourier : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void apply(Image *img);
|
||||||
|
|
||||||
|
QString getName() const { return "Fourier"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FOURIER_H
|
8
filters/histequalize.cpp
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#include "histequalize.h"
|
||||||
|
|
||||||
|
Result * HistEqualize::applyInternal(Image *img)
|
||||||
|
{
|
||||||
|
equalizeHist(img->filtered, img->filtered);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
16
filters/histequalize.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef HISTEQUALIZE_H
|
||||||
|
#define HISTEQUALIZE_H
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
class HistEqualize : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString getName() const { return "HistEqualize"; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Result * applyInternal(Image *img);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HISTEQUALIZE_H
|
60
filters/kmeans.cpp
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
#include "kmeans.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
KMeans::KMeans(int km) :
|
||||||
|
k(km),
|
||||||
|
low(0),
|
||||||
|
high(k)
|
||||||
|
{
|
||||||
|
settings["K"] = new IntegerSetting(this, k, 1, 2*k);
|
||||||
|
settings["Low"] = new IntegerSetting(this, low, 0, 2*k-1,
|
||||||
|
"Only set pixels with a label higher or equal to this value.");
|
||||||
|
settings["High"] = new IntegerSetting(this, high, 0, 2*k,
|
||||||
|
"Only set Pixels with a label lower or equal to this value.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void KMeans::reset()
|
||||||
|
{
|
||||||
|
labels.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result * KMeans::applyInternal(Image *img)
|
||||||
|
{
|
||||||
|
Mat m = img->filtered.clone();
|
||||||
|
Mat reshaped_image, reshaped_image32f;
|
||||||
|
Mat centers, centers_u8;
|
||||||
|
int flags = KMEANS_RANDOM_CENTERS; //KMEANS_PP_CENTERS;
|
||||||
|
|
||||||
|
TermCriteria criteria = TermCriteria(TermCriteria::COUNT | TermCriteria::EPS, 4, 0.1);
|
||||||
|
|
||||||
|
reshaped_image = m.reshape(1, m.cols * m.rows);
|
||||||
|
reshaped_image.convertTo(reshaped_image32f, CV_32FC1, 1.0 / 255.0);
|
||||||
|
|
||||||
|
if (labels.data)
|
||||||
|
flags |= KMEANS_USE_INITIAL_LABELS;
|
||||||
|
|
||||||
|
kmeans(reshaped_image32f, k, labels, criteria, 1, flags, centers);
|
||||||
|
|
||||||
|
MatIterator_<Vec3b> first = img->filtered.begin<Vec3b>();
|
||||||
|
MatIterator_<Vec3b> last = img->filtered.end<Vec3b>();
|
||||||
|
MatConstIterator_<int> label = labels.begin<int>();
|
||||||
|
|
||||||
|
centers.convertTo(centers_u8, CV_8UC1, 255.0);
|
||||||
|
Mat centers_u8c3 = centers_u8.reshape(3);
|
||||||
|
|
||||||
|
while (first != last) {
|
||||||
|
if (*label >= low && *label <= high)
|
||||||
|
*first = centers_u8c3.ptr<Vec3b>(*label)[0];
|
||||||
|
else
|
||||||
|
*first = Vec3b(0, 0, 0);
|
||||||
|
|
||||||
|
++first;
|
||||||
|
++label;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
26
filters/kmeans.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef KMEANS_H
|
||||||
|
#define KMEANS_H
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
class KMeans : public Filter
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
KMeans(int k);
|
||||||
|
|
||||||
|
QString getName() const { return "KMeans"; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Result * applyInternal(Image *img);
|
||||||
|
|
||||||
|
int k;
|
||||||
|
int low, high;
|
||||||
|
Mat labels;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // KMEANS_H
|
20
filters/maxchannel.cpp
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include "maxchannel.h"
|
||||||
|
|
||||||
|
Result * MaxChannel::applyInternal(Image *img)
|
||||||
|
{
|
||||||
|
Mat &m = img->filtered;
|
||||||
|
|
||||||
|
CV_Assert(m.type() == CV_8UC3);
|
||||||
|
|
||||||
|
for(int i = 0; i < m.rows; i++) {
|
||||||
|
uchar *p = m.ptr<uchar>(i);
|
||||||
|
for (int j = 0; j < 3*m.cols; j += 3) {
|
||||||
|
p[j] = (p[j ] > p[j+1] && p[j ] > p[j+2]) ? 0xff : 0;
|
||||||
|
p[j+1] = (p[j+1] > p[j ] && p[j+1] > p[j+2]) ? 0xff : 0;
|
||||||
|
p[j+2] = (p[j+2] > p[j ] && p[j+2] > p[j+2]) ? 0xff : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
15
filters/maxchannel.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef MAXCHANNEL_H
|
||||||
|
#define MAXCHANNEL_H
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
class MaxChannel : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Result * applyInternal(Image *img);
|
||||||
|
|
||||||
|
QString getName() const { return "MaxChannel"; }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MAXCHANNEL_H
|
54
filters/morph.cpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#include "morph.h"
|
||||||
|
|
||||||
|
Morph::Morph(int o, int t, Size s, Point a, int i) :
|
||||||
|
op(o),
|
||||||
|
shape(t),
|
||||||
|
iterations(i),
|
||||||
|
size(s),
|
||||||
|
anchor(a)
|
||||||
|
{
|
||||||
|
QMap<int, QString> mapOp;
|
||||||
|
QMap<int, QString> mapShape;
|
||||||
|
|
||||||
|
mapOp[MORPH_OPEN] = "Open";
|
||||||
|
mapOp[MORPH_CLOSE] = "Close";
|
||||||
|
mapOp[MORPH_ERODE] = "Erode";
|
||||||
|
mapOp[MORPH_DILATE] = "Dilate";
|
||||||
|
mapOp[MORPH_BLACKHAT] = "Blackhat";
|
||||||
|
mapOp[MORPH_GRADIENT] = "Gradient";
|
||||||
|
|
||||||
|
mapShape[MORPH_RECT] = "Rectangle";
|
||||||
|
mapShape[MORPH_ELLIPSE] = "Ellipse";
|
||||||
|
mapShape[MORPH_CROSS] = "Cross";
|
||||||
|
|
||||||
|
settings["Iterations"] = new IntegerSetting(this, iterations);
|
||||||
|
settings["Operation"] = new EnumSetting(this, op, mapOp);
|
||||||
|
settings["Shape"] = new EnumSetting(this, shape, mapShape);
|
||||||
|
settings["Size"] = new SizeSetting(this, size, 1);
|
||||||
|
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Morph::reset()
|
||||||
|
{
|
||||||
|
kernel = getStructuringElement(shape, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result * Morph::applyInternal(Image *img)
|
||||||
|
{
|
||||||
|
Mat &m = img->filtered;
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case MORPH_DILATE: dilate(m, m, kernel, anchor, iterations); break;
|
||||||
|
case MORPH_ERODE: erode(m, m, kernel, anchor, iterations); break;
|
||||||
|
case MORPH_OPEN:
|
||||||
|
case MORPH_CLOSE:
|
||||||
|
case MORPH_BLACKHAT:
|
||||||
|
case MORPH_GRADIENT:
|
||||||
|
morphologyEx(m, m, op, kernel, anchor, iterations); break;
|
||||||
|
default:
|
||||||
|
CV_Error(100, "Invalid morph operation");
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
27
filters/morph.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef MORPH_H
|
||||||
|
#define MORPH_H
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
class Morph : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Morph(int op, int shape, Size size = Size(3, 3), Point anchor = Point(-1, -1), int iterations = 1);
|
||||||
|
QString getName() const { return "Morph"; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Result * applyInternal(Image *img);
|
||||||
|
|
||||||
|
Mat kernel;
|
||||||
|
|
||||||
|
int op;
|
||||||
|
int shape;
|
||||||
|
int iterations;
|
||||||
|
Size size;
|
||||||
|
Point anchor;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MORPH_H
|
22
filters/normalize.cpp
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#include "normalize.h"
|
||||||
|
|
||||||
|
Result * Normalize::applyInternal(Image *img)
|
||||||
|
{
|
||||||
|
Mat &m = img->filtered;
|
||||||
|
|
||||||
|
CV_Assert(m.type() == CV_8UC3);
|
||||||
|
|
||||||
|
for(int i = 0; i < m.rows; i++) {
|
||||||
|
uchar *p = m.ptr<uchar>(i);
|
||||||
|
for (int j = 0; j < 3*m.cols; j += 3) {
|
||||||
|
|
||||||
|
double s = 255.0 / (p[j] + p[j+1] + p[j+2]);
|
||||||
|
|
||||||
|
p[j] *= s;
|
||||||
|
p[j+1] *= s;
|
||||||
|
p[j+2] *= s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
13
filters/normalize.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#ifndef NORMALIZE_H
|
||||||
|
#define NORMALIZE_H
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
class Normalize : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Result * applyInternal(Image *img);
|
||||||
|
QString getName() const { return "Normalize"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NORMALIZE_H
|
7
filters/padfilter.cpp
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#include "padfilter.h"
|
||||||
|
|
||||||
|
Result * PadFilter::applyInternal(Image *)
|
||||||
|
{
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
16
filters/padfilter.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef PADFILTER_H
|
||||||
|
#define PADFILTER_H
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
class PadFilter : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString getName() const { return "PadFilter"; };
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Result * applyInternal(Image *img);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PADFILTER_H
|
121
filters/pattern.cpp
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
#include <opencv2/imgproc.hpp>
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
#include "cast.h"
|
||||||
|
#include "pattern.h"
|
||||||
|
#include "image.h"
|
||||||
|
#include "convert.h"
|
||||||
|
|
||||||
|
Pattern::Pattern(Size si, double sp, Type t) :
|
||||||
|
type(t),
|
||||||
|
size(si),
|
||||||
|
spacing(sp)
|
||||||
|
{
|
||||||
|
//QMap<int, QString> mapType
|
||||||
|
|
||||||
|
settings["Size"] = new SizeSetting(this, size, 1, 20);
|
||||||
|
settings["Spacing"] = new DoubleSetting(this, spacing, 1e-3, 1e2);
|
||||||
|
//settings["Type"] = new EnumSetting(this, type, mapType);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Result * Pattern::applyInternal(Image *img)
|
||||||
|
{
|
||||||
|
bool found;
|
||||||
|
std::vector<Point2f> points;
|
||||||
|
|
||||||
|
Mat gray;
|
||||||
|
if (img->original.channels() > 1)
|
||||||
|
cvtColor(img->original, gray, COLOR_RGB2GRAY);
|
||||||
|
else
|
||||||
|
gray = img->original;
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case CHESSBOARD:
|
||||||
|
found = findChessboardCorners(gray, size, points, flags);
|
||||||
|
if(found) {
|
||||||
|
cornerSubPix(gray, points, Size(11, 11), Size(-1, -1),
|
||||||
|
TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 30, 0.1));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CIRCLES_GRID:
|
||||||
|
found = findCirclesGrid(gray, size, points);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASYMMETRIC_CIRCLES_GRID:
|
||||||
|
found = findCirclesGrid(gray, size, points, CALIB_CB_ASYMMETRIC_GRID);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PatternResult(found, points);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<Point3f> Pattern::getPoints() const
|
||||||
|
{
|
||||||
|
std::vector<Point3f> points;
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case CHESSBOARD:
|
||||||
|
case CIRCLES_GRID:
|
||||||
|
for (int i = 0; i < size.height; ++i) {
|
||||||
|
for (int j = 0; j < size.width; ++j)
|
||||||
|
points.push_back(Point3f(j*spacing, i*spacing, 0));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASYMMETRIC_CIRCLES_GRID:
|
||||||
|
for (int i = 0; i < size.height; i++) {
|
||||||
|
for (int j = 0; j < size.width; j++)
|
||||||
|
points.push_back(Point3f((2*j+i%2)*spacing, i*spacing, 0));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> Pattern::getCornerIndizes() const
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
0,
|
||||||
|
size.width - 1,
|
||||||
|
size.width * size.height - size.width,
|
||||||
|
size.width * size.height - 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
PatternResult::PatternResult(bool f, std::vector<Point2f> p) :
|
||||||
|
found(f),
|
||||||
|
points(p)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void PatternResult::draw(Painter *p) const
|
||||||
|
{
|
||||||
|
QPen pen = p->pen();
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < points.size(); i++) {
|
||||||
|
QColor clr = found ? QColor::fromHsl(360.0 / points.size() * i, 255, 128) : Qt::gray;
|
||||||
|
|
||||||
|
pen.setColor(clr);
|
||||||
|
p->setPen(pen);
|
||||||
|
p->drawMarker(toQt((Point2i) points[i]));
|
||||||
|
|
||||||
|
if (i != 0)
|
||||||
|
p->drawLine(toQt((Point2i) points[i-1]), toQt((Point2i) points[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PatternResult::getResult() const
|
||||||
|
{
|
||||||
|
return QString("found = %1, points = %2").arg(found).arg(points.size());
|
||||||
|
}
|
57
filters/pattern.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#ifndef PATTERN_H
|
||||||
|
#define PATTERN_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <opencv2/core.hpp>
|
||||||
|
#include <opencv2/calib3d.hpp>
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
class Image;
|
||||||
|
class PatternResult;
|
||||||
|
|
||||||
|
class Pattern : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
CHESSBOARD,
|
||||||
|
CIRCLES_GRID,
|
||||||
|
ASYMMETRIC_CIRCLES_GRID
|
||||||
|
} type;
|
||||||
|
|
||||||
|
Pattern(Size si, double sp, Type t = Type::CHESSBOARD);
|
||||||
|
|
||||||
|
Result * applyInternal(Image *img);
|
||||||
|
|
||||||
|
/* Getter */
|
||||||
|
QString getName() const { return "Pattern"; }
|
||||||
|
std::vector<int> getCornerIndizes() const;
|
||||||
|
std::vector<Point3f> getPoints() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Size size;
|
||||||
|
int flags = CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CALIB_CB_FAST_CHECK;
|
||||||
|
double spacing;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PatternResult : public Result
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PatternResult(bool found, std::vector<Point2f> op);
|
||||||
|
|
||||||
|
void draw(Painter *p) const;
|
||||||
|
QString getResult() const;
|
||||||
|
|
||||||
|
/* Getter */
|
||||||
|
std::vector<Point2f> getPoints() const { return points; }
|
||||||
|
bool isFound() const { return found; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool found;
|
||||||
|
std::vector<Point2f> points;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PATTERN_H
|
42
filters/perspective.cpp
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#include <opencv2/imgproc.hpp>
|
||||||
|
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
#include "cast.h"
|
||||||
|
#include "perspective.h"
|
||||||
|
|
||||||
|
Perspective::Perspective(Camera *c, Pattern *p) :
|
||||||
|
cam(c),
|
||||||
|
pattern(p)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
Result * Perspective::applyInternal(Image *img)
|
||||||
|
{
|
||||||
|
Mat &m = img->filtered;
|
||||||
|
PatternResult *presult = (PatternResult *) img->getResult(pattern);
|
||||||
|
|
||||||
|
if (presult->isFound()) {
|
||||||
|
std::vector<Point2f> src, dest, tmp;
|
||||||
|
std::vector<Point2f> srcPoints = presult->getPoints();
|
||||||
|
std::vector<Point3f> destPoints = pattern->getPoints();
|
||||||
|
|
||||||
|
for (int i : pattern->getCornerIndizes()) {
|
||||||
|
src.push_back(srcPoints[i]);
|
||||||
|
tmp.push_back(Point2f(destPoints[i].x, destPoints[i].y));
|
||||||
|
}
|
||||||
|
|
||||||
|
int destWidth = 0.75 * m.cols;
|
||||||
|
int destHeight = tmp[2].y * (destWidth / tmp[1].x);
|
||||||
|
|
||||||
|
dest.push_back( Point2f((m.cols - destWidth) / 2, (m.rows - destHeight) / 2) );
|
||||||
|
dest.push_back( dest[0] + Point2f(destWidth, 0) );
|
||||||
|
dest.push_back( dest[0] + Point2f(0, destHeight) );
|
||||||
|
dest.push_back( dest[0] + Point2f(destWidth, destHeight) );
|
||||||
|
|
||||||
|
map = getPerspectiveTransform(src, dest);
|
||||||
|
warpPerspective(img->filtered, img->filtered, map, img->filtered.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
22
filters/perspective.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef PERSPECTIVE_H
|
||||||
|
#define PERSPECTIVE_H
|
||||||
|
|
||||||
|
#include "pattern.h"
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
class Perspective : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Perspective(Camera *cam, Pattern *p);
|
||||||
|
|
||||||
|
QString getName() const { return "Perspective"; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Result * applyInternal(Image *img);
|
||||||
|
|
||||||
|
Mat map;
|
||||||
|
Camera *cam;
|
||||||
|
Pattern *pattern;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PERSPECTIVE_H
|
3
filters/result.cpp
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#include "result.h"
|
||||||
|
|
||||||
|
|
51
filters/result.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef RESULT_H
|
||||||
|
#define RESULT_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class Painter;
|
||||||
|
|
||||||
|
class Result
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Result() { };
|
||||||
|
|
||||||
|
virtual void draw(Painter *) const { };
|
||||||
|
virtual QString getResult() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IntegerResult : public Result
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IntegerResult(QString n, int v) :
|
||||||
|
name(n),
|
||||||
|
value(v)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
QString getResult() const {
|
||||||
|
return QString("%1 = %2").arg(name).arg(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QString name;
|
||||||
|
int value;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DoubleResult : public Result
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DoubleResult(QString n, double v) :
|
||||||
|
name(n),
|
||||||
|
value(v)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
QString getResult() const {
|
||||||
|
return QString("%1 = %2").arg(name).arg(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QString name;
|
||||||
|
double value;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RESULT_H
|
150
filters/setting.cpp
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
#include <QLayout>
|
||||||
|
#include <QtDebug>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
#include "ui_doublesetting.h"
|
||||||
|
#include "setting.h"
|
||||||
|
#include "viewer.h"
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
Setting::Setting(Filter *f, QString tip)
|
||||||
|
: toolTip(tip)
|
||||||
|
{
|
||||||
|
connect(this, SIGNAL(valueChanged()), f, SIGNAL(filterChanged()));
|
||||||
|
connect(this, SIGNAL(valueChanged()), f, SLOT(reset()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget * Setting::getWidget(QWidget *parent)
|
||||||
|
{
|
||||||
|
if (!widget)
|
||||||
|
widget = createWidget(parent);
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget * BooleanSetting::createWidget(QWidget *parent)
|
||||||
|
{
|
||||||
|
box = new QCheckBox(parent);
|
||||||
|
|
||||||
|
connect(box, static_cast<void (QCheckBox::*)(bool)>(&QCheckBox::clicked), [&](bool v) {
|
||||||
|
value = v;
|
||||||
|
emit valueChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget * IntegerSetting::createWidget(QWidget *parent)
|
||||||
|
{
|
||||||
|
QWidget *widget = new QWidget(parent);
|
||||||
|
QHBoxLayout *layout = new QHBoxLayout(widget);
|
||||||
|
|
||||||
|
slider = new QSlider(Qt::Horizontal, widget);
|
||||||
|
spinner = new QSpinBox(widget);
|
||||||
|
|
||||||
|
widget->setToolTip(toolTip);
|
||||||
|
layout->setMargin(0);
|
||||||
|
layout->addWidget(slider);
|
||||||
|
layout->addWidget(spinner);
|
||||||
|
spinner->setValue(value);
|
||||||
|
slider->setValue(value);
|
||||||
|
slider->setMinimum(min);
|
||||||
|
slider->setMaximum(max);
|
||||||
|
slider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||||
|
|
||||||
|
connect(slider, static_cast<void (QSlider::*)(int)>(&QSlider::valueChanged), [&](int v) {
|
||||||
|
value = v;
|
||||||
|
spinner->setValue(v);
|
||||||
|
emit valueChanged();
|
||||||
|
});
|
||||||
|
connect(spinner, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [&](int v) {
|
||||||
|
value = v;
|
||||||
|
slider->setValue(value);
|
||||||
|
emit valueChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget * DoubleSetting::createWidget(QWidget *parent)
|
||||||
|
{
|
||||||
|
QWidget *widget = new QWidget(parent);
|
||||||
|
QHBoxLayout *layout = new QHBoxLayout(widget);
|
||||||
|
|
||||||
|
slider = new QSlider(Qt::Horizontal, widget);
|
||||||
|
spinner = new QDoubleSpinBox(widget);
|
||||||
|
|
||||||
|
widget->setToolTip(toolTip);
|
||||||
|
layout->setMargin(0);
|
||||||
|
layout->addWidget(slider);
|
||||||
|
layout->addWidget(spinner);
|
||||||
|
layout->setMargin(0);
|
||||||
|
spinner->setValue(value);
|
||||||
|
slider->setValue(value * SCALE);
|
||||||
|
slider->setMinimum(min * SCALE);
|
||||||
|
slider->setMaximum(max * SCALE);
|
||||||
|
slider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||||
|
|
||||||
|
connect(slider, static_cast<void (QSlider::*)(int)>(&QSlider::valueChanged), [&](int v) {
|
||||||
|
value = (double) v / SCALE;
|
||||||
|
spinner->setValue(value);
|
||||||
|
emit valueChanged();
|
||||||
|
});
|
||||||
|
connect(spinner, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), [&](double v) {
|
||||||
|
value = v;
|
||||||
|
slider->setValue(value * SCALE);
|
||||||
|
emit valueChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget * EnumSetting::createWidget(QWidget *parent)
|
||||||
|
{
|
||||||
|
QComboBox *combo = new QComboBox(parent);
|
||||||
|
|
||||||
|
for (int key : map.keys())
|
||||||
|
combo->addItem(map.value(key), QVariant(key));
|
||||||
|
|
||||||
|
combo->setCurrentText(map[value]);
|
||||||
|
combo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||||
|
|
||||||
|
connect(combo, &QComboBox::currentTextChanged, [&](QString v) {
|
||||||
|
value = map.key(v, map.keys().first());
|
||||||
|
emit valueChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
return combo;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget * SizeSetting::createWidget(QWidget *parent)
|
||||||
|
{
|
||||||
|
QWidget *widget = new QWidget(parent);
|
||||||
|
QHBoxLayout *layout = new QHBoxLayout(widget);
|
||||||
|
QLabel *lblX = new QLabel("x", widget);
|
||||||
|
|
||||||
|
spinnerH = new QSpinBox(widget);
|
||||||
|
spinnerW = new QSpinBox(widget);
|
||||||
|
|
||||||
|
layout->setMargin(0);
|
||||||
|
layout->addWidget(spinnerW);
|
||||||
|
layout->addWidget(lblX);
|
||||||
|
layout->addWidget(spinnerH);
|
||||||
|
spinnerH->setValue(value.height);
|
||||||
|
spinnerW->setValue(value.width);
|
||||||
|
spinnerH->setMinimum(min);
|
||||||
|
spinnerH->setMaximum(max);
|
||||||
|
spinnerW->setMinimum(min);
|
||||||
|
spinnerW->setMaximum(max);
|
||||||
|
|
||||||
|
connect(spinnerH, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [&](int v) {
|
||||||
|
value.height = v;
|
||||||
|
emit valueChanged();
|
||||||
|
});
|
||||||
|
connect(spinnerW, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [&](int v) {
|
||||||
|
value.width = v;
|
||||||
|
emit valueChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
118
filters/setting.h
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
#ifndef SETTING_H
|
||||||
|
#define SETTING_H
|
||||||
|
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QSlider>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QMap>
|
||||||
|
|
||||||
|
#include <opencv2/core.hpp>
|
||||||
|
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
class Filter;
|
||||||
|
|
||||||
|
class Setting : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Setting(Filter *f, QString tip);
|
||||||
|
QWidget * getWidget(QWidget *parent);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void valueChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual QWidget * createWidget(QWidget *parent) = 0;
|
||||||
|
|
||||||
|
Filter *filter;
|
||||||
|
QWidget *widget = NULL;
|
||||||
|
QString toolTip;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IntegerSetting : public Setting
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
IntegerSetting(Filter *f, int &v, int mi = 0, int ma = 100, QString tip = "") :
|
||||||
|
Setting(f, tip), value(v), min(mi), max(ma) { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QWidget * createWidget(QWidget *parent = 0);
|
||||||
|
|
||||||
|
int &value, min, max;
|
||||||
|
QSpinBox *spinner;
|
||||||
|
QSlider *slider;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BooleanSetting : public Setting
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
BooleanSetting(Filter *f, bool &v, QString tip = "") :
|
||||||
|
Setting(f, tip), value(v) { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QWidget *createWidget(QWidget *parent);
|
||||||
|
|
||||||
|
bool &value;
|
||||||
|
QCheckBox *box;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DoubleSetting : public Setting
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
DoubleSetting(Filter *f, double &v, double mi = 0, double ma = 100, QString tip = "") :
|
||||||
|
Setting(f, tip), value(v), min(mi), max(ma) { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static const int SCALE = 1000;
|
||||||
|
|
||||||
|
QWidget * createWidget(QWidget *parent = 0);
|
||||||
|
|
||||||
|
double &value, min, max;
|
||||||
|
QDoubleSpinBox *spinner;
|
||||||
|
QSlider *slider;
|
||||||
|
};
|
||||||
|
|
||||||
|
class EnumSetting : public Setting
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
EnumSetting(Filter *f, int &v, QMap<int, QString> m, QString tip = "") :
|
||||||
|
Setting(f, tip), value(v), map(m) { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QWidget * createWidget(QWidget *parent);
|
||||||
|
|
||||||
|
int &value;
|
||||||
|
QMap<int, QString> map;
|
||||||
|
QComboBox *combo;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SizeSetting : public Setting
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SizeSetting(Filter *f, Size &v, int mi = 1, int ma = 100, QString tip = "") :
|
||||||
|
Setting(f, tip), value(v), min(mi), max(ma) { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QWidget * createWidget(QWidget *parent);
|
||||||
|
|
||||||
|
Size &value;
|
||||||
|
int min, max;
|
||||||
|
|
||||||
|
QSpinBox *spinnerH, *spinnerW;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SETTING_H
|
113
filters/shapedetect.cpp
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
#include "cast.h"
|
||||||
|
#include "shapedetect.h"
|
||||||
|
|
||||||
|
static double angle(Point pt1, Point pt2, Point pt0)
|
||||||
|
{
|
||||||
|
double dx1 = pt1.x - pt0.x;
|
||||||
|
double dy1 = pt1.y - pt0.y;
|
||||||
|
double dx2 = pt2.x - pt0.x;
|
||||||
|
double dy2 = pt2.y - pt0.y;
|
||||||
|
|
||||||
|
return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double area(RotatedRect rect)
|
||||||
|
{
|
||||||
|
Point2f p[4];
|
||||||
|
rect.points(p);
|
||||||
|
|
||||||
|
double dxa = p[0].x - p[1].x;
|
||||||
|
double dya = p[0].y - p[1].y;
|
||||||
|
double dxb = p[1].x - p[2].x;
|
||||||
|
double dyb = p[2].y - p[2].y;
|
||||||
|
|
||||||
|
return sqrt( (dxa*dxa + dya*dya) * (dxb*dxb + dyb*dyb) );
|
||||||
|
}
|
||||||
|
|
||||||
|
ShapeDetect::ShapeDetect(double e, double cos) :
|
||||||
|
epsilon(e),
|
||||||
|
cosine(cos)
|
||||||
|
{
|
||||||
|
QMap<int, QString> mapMode;
|
||||||
|
mapMode[AREA] = "Area";
|
||||||
|
mapMode[COSINE] = "Cosine";
|
||||||
|
|
||||||
|
settings["Mode"] = new EnumSetting(this, (int&) mode, mapMode);
|
||||||
|
settings["Epsilon"] = new DoubleSetting(this, epsilon, 0, 1);
|
||||||
|
settings["Cosine"] = new DoubleSetting(this, cosine, 0, 1);
|
||||||
|
settings["Shape no"]= new IntegerSetting(this, shape, 0, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result * ShapeDetect::applyInternal(Image *img)
|
||||||
|
{
|
||||||
|
Mat &m = img->filtered;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
std::vector<std::vector<Point>> contours;
|
||||||
|
ShapeResult *result = new ShapeResult;
|
||||||
|
|
||||||
|
findContours(m.clone(), contours, RETR_LIST, CHAIN_APPROX_SIMPLE);
|
||||||
|
|
||||||
|
for (std::vector<Point> contour : contours) {
|
||||||
|
//std::vector<Point> contour = contours[shape];
|
||||||
|
|
||||||
|
std::vector<Point> approx;
|
||||||
|
bool closed = isContourConvex(contour);
|
||||||
|
double arc = arcLength(contour, closed);
|
||||||
|
|
||||||
|
approxPolyDP(contour, approx, epsilon * arc, closed);
|
||||||
|
|
||||||
|
switch (approx.size()) {
|
||||||
|
case 4:
|
||||||
|
if (mode == ShapeDetect::COSINE) {
|
||||||
|
double maxCosine = 0;
|
||||||
|
|
||||||
|
for (int j = 2; j < 5; j++) {
|
||||||
|
double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
|
||||||
|
maxCosine = std::max(maxCosine, cosine);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxCosine < cosine) {
|
||||||
|
RotatedRect rect = minAreaRect(approx);
|
||||||
|
//RotatedRect rect = minAreaRect(contour);
|
||||||
|
if (i++ == shape)
|
||||||
|
result->rects.push_back(rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mode == ShapeDetect::AREA) {
|
||||||
|
RotatedRect rect = minAreaRect(contour);
|
||||||
|
|
||||||
|
double areaContour = contourArea(contour);
|
||||||
|
double areaRect = area(rect);
|
||||||
|
|
||||||
|
if (areaContour / areaRect > epsilon) {
|
||||||
|
if (i++ == shape)
|
||||||
|
result->rects.push_back(rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShapeResult::draw(Painter *p) const
|
||||||
|
{
|
||||||
|
QPen pen = p->pen();
|
||||||
|
pen.setWidth(2);
|
||||||
|
p->setPen(pen);
|
||||||
|
|
||||||
|
for (auto rect : rects) {
|
||||||
|
Point2f v[4];
|
||||||
|
rect.points(v);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
p->drawLine(toQt((Point2i) v[i]), toQt((Point2i) v[(i+1)%4]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ShapeResult::getResult() const
|
||||||
|
{
|
||||||
|
return QString("rects = %1").arg(rects.size());
|
||||||
|
}
|
40
filters/shapedetect.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef SHAPEDETECT_H
|
||||||
|
#define SHAPEDETECT_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class ShapeDetect : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Mode {
|
||||||
|
AREA,
|
||||||
|
COSINE
|
||||||
|
};
|
||||||
|
|
||||||
|
ShapeDetect(double epsilon = 1, double cosine = 0.3);
|
||||||
|
QString getName() const { return "ShapeDetect"; };
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Result * applyInternal(Image *img);
|
||||||
|
|
||||||
|
double epsilon;
|
||||||
|
double cosine;
|
||||||
|
int shape = 0;
|
||||||
|
enum Mode mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShapeResult : public Result
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void draw(Painter *p) const;
|
||||||
|
|
||||||
|
QString getResult() const;
|
||||||
|
|
||||||
|
QList<RotatedRect> rects;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SHAPEDETECT_H
|
48
filters/threshold.cpp
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
#include "threshold.h"
|
||||||
|
|
||||||
|
Threshold::Threshold(enum Threshold::Type t, double v, int sz, double d) :
|
||||||
|
Filter(),
|
||||||
|
type(t),
|
||||||
|
size(sz),
|
||||||
|
value(v),
|
||||||
|
c(d)
|
||||||
|
{
|
||||||
|
QMap<int, QString> typeMap;
|
||||||
|
typeMap[ADAPTIVE_GAUSS] = "Adaptive Gauss";
|
||||||
|
typeMap[ADAPTIVE_MEAN] = "Adaptive Mean";
|
||||||
|
typeMap[FIXED] = "Fixed";
|
||||||
|
typeMap[OTSU] = "Otsu's method";
|
||||||
|
typeMap[TRIANGLE] = "Triangle";
|
||||||
|
|
||||||
|
settings["Type"] = new EnumSetting(this, (int&) type, typeMap);
|
||||||
|
settings["Threshold"] = new DoubleSetting(this, value, 0, 0xff);
|
||||||
|
settings["C"] = new DoubleSetting(this, c, 0, 0xff);
|
||||||
|
settings["Size"] = new IntegerSetting(this, size, 1, 100);
|
||||||
|
settings["Inverted"] = new BooleanSetting(this, invert);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result * Threshold::applyInternal(Image *img)
|
||||||
|
{
|
||||||
|
Mat &m = img->filtered;
|
||||||
|
|
||||||
|
int mode = (invert) ? THRESH_BINARY_INV : THRESH_BINARY;
|
||||||
|
|
||||||
|
if (type == ADAPTIVE_GAUSS)
|
||||||
|
adaptiveThreshold(m, m, 0xff, ADAPTIVE_THRESH_GAUSSIAN_C, mode, size, c);
|
||||||
|
else if (type == ADAPTIVE_MEAN)
|
||||||
|
adaptiveThreshold(m, m, 0xff, ADAPTIVE_THRESH_MEAN_C, mode, size, c);
|
||||||
|
else {
|
||||||
|
int method;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case OTSU: method = THRESH_OTSU; break;
|
||||||
|
case TRIANGLE: method = THRESH_TRIANGLE; break;
|
||||||
|
default: method = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double ret = threshold(img->filtered, img->filtered, value, 0xff, mode | method);
|
||||||
|
return new DoubleResult("tresh", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
32
filters/threshold.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef THRESHOLD_H
|
||||||
|
#define THRESHOLD_H
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class Threshold : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
ADAPTIVE_GAUSS,
|
||||||
|
ADAPTIVE_MEAN,
|
||||||
|
OTSU,
|
||||||
|
TRIANGLE,
|
||||||
|
FIXED
|
||||||
|
};
|
||||||
|
|
||||||
|
Threshold(enum Threshold::Type t, double v = 0, int sz = 7, double c = 100);
|
||||||
|
|
||||||
|
QString getName() const { return "Threshold"; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Result * applyInternal(Image *img);
|
||||||
|
|
||||||
|
enum Threshold::Type type;
|
||||||
|
bool invert = false;
|
||||||
|
int size;
|
||||||
|
double value, c;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // THRESHOLD_H
|
30
filters/undistort.cpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#include "undistort.h"
|
||||||
|
|
||||||
|
Undistort::Undistort(Camera *c) :
|
||||||
|
cam(c)
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Undistort::reset()
|
||||||
|
{
|
||||||
|
Mat newCamMat = getOptimalNewCameraMatrix(cam->getMatrix(), cam->getDistCoeffs(), cam->source->getSize(), 1);
|
||||||
|
|
||||||
|
initUndistortRectifyMap(cam->getMatrix(), cam->getDistCoeffs(),
|
||||||
|
Mat(), newCamMat, cam->source->getSize(), CV_16SC2, map1, map2);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result * Undistort::applyInternal(Image *img)
|
||||||
|
{
|
||||||
|
if (cam->isCalibrated()) {
|
||||||
|
#if 1
|
||||||
|
remap(img->filtered, img->filtered, map1, map2, INTER_LINEAR);
|
||||||
|
#else
|
||||||
|
Mat dest;
|
||||||
|
undistort(mat, dest, cam->getMatrix(), cam->getDistCoeffs());
|
||||||
|
mat = dest;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
24
filters/undistort.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef UNDISTORT_H
|
||||||
|
#define UNDISTORT_H
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
|
class Undistort : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Undistort(Camera *c);
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
QString getName() const { return "Undistort"; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Result * applyInternal(Image *img);
|
||||||
|
|
||||||
|
Mat map1;
|
||||||
|
Mat map2;
|
||||||
|
|
||||||
|
Camera *cam;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // UNDISTORT_H
|
22
filters/watershed.cpp
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#include "watershed.h"
|
||||||
|
|
||||||
|
Watershed::Watershed()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Result * Watershed::applyInternal(Image *img)
|
||||||
|
{
|
||||||
|
Mat dist, dist_8u, &m = img->filtered;
|
||||||
|
|
||||||
|
CV_Assert(m.channels() == 1);
|
||||||
|
|
||||||
|
distanceTransform(m, dist, DIST_L2, 3);
|
||||||
|
normalize(m, m, 0, 0xff, NORM_MINMAX);
|
||||||
|
|
||||||
|
dist.convertTo(dist_8u, CV_8U);
|
||||||
|
m = dist_8u;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
18
filters/watershed.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef WATERSHED_H
|
||||||
|
#define WATERSHED_H
|
||||||
|
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
|
class Watershed : public Filter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Watershed();
|
||||||
|
|
||||||
|
QString getName() const { return "Watershed"; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Result * applyInternal(Image *img);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WATERSHED_H
|
54
image.cpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#include <opencv2/highgui.hpp>
|
||||||
|
|
||||||
|
#include "image.h"
|
||||||
|
#include "filters/filter.h"
|
||||||
|
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
Image::Image(Mat m, QString p) :
|
||||||
|
path(p),
|
||||||
|
original(m.clone()),
|
||||||
|
loaded(false),
|
||||||
|
saved(false)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
Image::Image(QString p) :
|
||||||
|
path(p),
|
||||||
|
saved(false)
|
||||||
|
{
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
||||||
|
Image::~Image()
|
||||||
|
{
|
||||||
|
qDeleteAll(results);
|
||||||
|
results.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Image::load(QString p)
|
||||||
|
{
|
||||||
|
if (p != "")
|
||||||
|
path = p;
|
||||||
|
|
||||||
|
original = cv::imread(path.toStdString());
|
||||||
|
loaded = (bool) original.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Image::save(QString p)
|
||||||
|
{
|
||||||
|
if (p != "")
|
||||||
|
path = p;
|
||||||
|
|
||||||
|
saved = imwrite(path.toStdString(), original);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Image::applyFilter(Filter *filter)
|
||||||
|
{
|
||||||
|
// FIXME!
|
||||||
|
// if (results.contains(filter))
|
||||||
|
// delete results[filter];
|
||||||
|
|
||||||
|
Result *result = filter->apply(this);
|
||||||
|
if (result)
|
||||||
|
results[filter] = result;
|
||||||
|
}
|
43
image.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef IMAGE_H
|
||||||
|
#define IMAGE_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QMap>
|
||||||
|
|
||||||
|
#include <opencv2/core.hpp>
|
||||||
|
#include <opencv2/imgproc.hpp>
|
||||||
|
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
class Camera;
|
||||||
|
class Filter;
|
||||||
|
class Result;
|
||||||
|
|
||||||
|
class Image
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Image(Mat mat = Mat(), QString path = "");
|
||||||
|
Image(QString p);
|
||||||
|
~Image();
|
||||||
|
|
||||||
|
void save(QString path = "");
|
||||||
|
void load(QString path = "");
|
||||||
|
|
||||||
|
QString path;
|
||||||
|
|
||||||
|
Mat original;
|
||||||
|
Mat filtered;
|
||||||
|
|
||||||
|
void applyFilter(Filter *filter);
|
||||||
|
|
||||||
|
/* Getter */
|
||||||
|
Result * getResult(Filter *f) { return results[f]; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QMap<Filter*, Result*> results;
|
||||||
|
|
||||||
|
bool loaded;
|
||||||
|
bool saved;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IMAGE_H
|
158
imagelist.cpp
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#include "imagelist.h"
|
||||||
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
extern MainWindow *mwindow;
|
||||||
|
|
||||||
|
ImageList::ImageList(QObject *parent) :
|
||||||
|
QAbstractTableModel(parent),
|
||||||
|
selection(this)
|
||||||
|
{
|
||||||
|
connect(&selection, &QItemSelectionModel::currentChanged, this, &ImageList::currentImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageList::~ImageList()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ImageList::rowCount(const QModelIndex &) const {
|
||||||
|
return count();
|
||||||
|
};
|
||||||
|
|
||||||
|
int ImageList::columnCount(const QModelIndex &) const {
|
||||||
|
return 6;
|
||||||
|
};
|
||||||
|
|
||||||
|
QVariant ImageList::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
Image *img = at(index.row());
|
||||||
|
QFileInfo fi = QFileInfo(img->path);
|
||||||
|
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
switch (index.column()) {
|
||||||
|
case 0: return fi.baseName();
|
||||||
|
case 1: return fi.suffix();
|
||||||
|
case 2: return fi.size();
|
||||||
|
case 3: return img->original.cols;
|
||||||
|
case 4: return img->original.rows;
|
||||||
|
case 5: return img->original.channels();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ImageList::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
if (orientation == Qt::Horizontal) {
|
||||||
|
switch (section) {
|
||||||
|
case 0: return QString(tr("Name"));
|
||||||
|
case 1: return QString(tr("Typ"));
|
||||||
|
case 2: return QString(tr("Size"));
|
||||||
|
case 3: return QString(tr("Width"));
|
||||||
|
case 4: return QString(tr("Height"));
|
||||||
|
case 5: return QString(tr("Channels"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageList::clear() {
|
||||||
|
QList<Image *>::iterator it;
|
||||||
|
|
||||||
|
beginResetModel();
|
||||||
|
for (Image *img : *this) {
|
||||||
|
delete img;
|
||||||
|
removeOne(img);
|
||||||
|
}
|
||||||
|
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<Image *> ImageList::selectedImages()
|
||||||
|
{
|
||||||
|
QList<Image *> sel;
|
||||||
|
|
||||||
|
for (QModelIndex index : selection.selectedRows())
|
||||||
|
sel.append(at(index.row()));
|
||||||
|
|
||||||
|
return sel;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image * ImageList::currentImage()
|
||||||
|
{
|
||||||
|
current = at(selection.currentIndex().row());
|
||||||
|
emit newImage(current);
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image * ImageList::nextImage()
|
||||||
|
{
|
||||||
|
QModelIndex oldIdx = selection.currentIndex();
|
||||||
|
QModelIndex newIdx = index(oldIdx.row()-1, oldIdx.column());
|
||||||
|
|
||||||
|
if (newIdx.isValid()) {
|
||||||
|
selection.setCurrentIndex(newIdx, QItemSelectionModel::Current);
|
||||||
|
|
||||||
|
current = at(newIdx.row());
|
||||||
|
emit newImage(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
Image * ImageList::prevImage()
|
||||||
|
{
|
||||||
|
QModelIndex oldIdx = selection.currentIndex();
|
||||||
|
QModelIndex newIdx = index(oldIdx.row()+1, oldIdx.column());
|
||||||
|
|
||||||
|
if (newIdx.isValid()) {
|
||||||
|
selection.setCurrentIndex(newIdx, QItemSelectionModel::Current);
|
||||||
|
|
||||||
|
current = at(newIdx.row());
|
||||||
|
emit newImage(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageList::load(QStringList files)
|
||||||
|
{
|
||||||
|
for (QString file : files)
|
||||||
|
add(new Image(file));
|
||||||
|
|
||||||
|
current = first();
|
||||||
|
emit newImage(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageList::save(QString path)
|
||||||
|
{
|
||||||
|
currentImage()->save(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageList::loadFilePicker()
|
||||||
|
{
|
||||||
|
QStringList files = QFileDialog::getOpenFileNames(mwindow, tr("Open Image"), QDir::currentPath(),
|
||||||
|
tr("Image Files (*.png *.jpg *.bmp)"));
|
||||||
|
load(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageList::saveFilePicker()
|
||||||
|
{
|
||||||
|
QString path = QFileDialog::getSaveFileName(mwindow, tr("Save Image"), current->path,
|
||||||
|
tr("Image Files (*.png *.jpg *.bmp)"));
|
||||||
|
save(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageList::add(Image *img)
|
||||||
|
{
|
||||||
|
beginInsertRows(QModelIndex(), size(), size());
|
||||||
|
push_back(img);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
49
imagelist.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#ifndef IMAGELIST_H
|
||||||
|
#define IMAGELIST_H
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
#include <QItemSelectionModel>
|
||||||
|
|
||||||
|
#include "image.h"
|
||||||
|
|
||||||
|
class ImageList :
|
||||||
|
public QAbstractTableModel,
|
||||||
|
protected QList<Image *>
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ImageList(QObject *parent = 0);
|
||||||
|
~ImageList();
|
||||||
|
|
||||||
|
void add(Image *img);
|
||||||
|
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &) const;
|
||||||
|
int columnCount(const QModelIndex &) const;
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||||
|
|
||||||
|
QItemSelectionModel selection;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void newImage(Image *img);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void load(QStringList files);
|
||||||
|
void save(QString path);
|
||||||
|
void loadFilePicker();
|
||||||
|
void saveFilePicker();
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
QList<Image *> selectedImages();
|
||||||
|
Image * currentImage();
|
||||||
|
Image * prevImage();
|
||||||
|
Image * nextImage();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Image *current;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IMAGELIST_H
|
99
imagelist.ui
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Form</class>
|
||||||
|
<widget class="QWidget" name="Form">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTableView" name="tblImages">
|
||||||
|
<property name="selectionBehavior">
|
||||||
|
<enum>QAbstractItemView::SelectRows</enum>
|
||||||
|
</property>
|
||||||
|
<property name="showGrid">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="gridStyle">
|
||||||
|
<enum>Qt::DotLine</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sortingEnabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="horizontalHeaderCascadingSectionResizes">
|
||||||
|
<bool>true</bool>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="horizontalHeaderStretchLastSection">
|
||||||
|
<bool>true</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="widget_3" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnClear">
|
||||||
|
<property name="text">
|
||||||
|
<string>Clear</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/edit-clear.png</normaloff>:/icons/resources/edit-clear.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnLoad">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/document-open.png</normaloff>:/icons/resources/document-open.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnSave">
|
||||||
|
<property name="text">
|
||||||
|
<string>Save</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/document-save.png</normaloff>:/icons/resources/document-save.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="images.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
35
images.qrc
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<RCC>
|
||||||
|
<qresource prefix="/icons">
|
||||||
|
<file>resources/Mr-potato.png</file>
|
||||||
|
<file>resources/calibrate.png</file>
|
||||||
|
<file>resources/chess.png</file>
|
||||||
|
<file>resources/circ.png</file>
|
||||||
|
<file>resources/acirc.png</file>
|
||||||
|
<file>resources/Boris.png</file>
|
||||||
|
<file>resources/camera-photo.png</file>
|
||||||
|
<file>resources/cap5h.jpg</file>
|
||||||
|
<file>resources/chess.svg</file>
|
||||||
|
<file>resources/circ.svg</file>
|
||||||
|
<file>resources/document-open.png</file>
|
||||||
|
<file>resources/document-save.png</file>
|
||||||
|
<file>resources/edit-clear.png</file>
|
||||||
|
<file>resources/edit-undo.png</file>
|
||||||
|
<file>resources/go-next.png</file>
|
||||||
|
<file>resources/go-previous.png</file>
|
||||||
|
<file>resources/image-x-generic.png</file>
|
||||||
|
<file>resources/media-playback-start.png</file>
|
||||||
|
<file>resources/system-log-out.png</file>
|
||||||
|
<file>resources/media-playback-stop.png</file>
|
||||||
|
<file>resources/perspective.png</file>
|
||||||
|
<file>resources/list-add.png</file>
|
||||||
|
<file>resources/list-remove.png</file>
|
||||||
|
<file>resources/view-refresh.png</file>
|
||||||
|
</qresource>
|
||||||
|
<qresource prefix="/math">
|
||||||
|
<file>resources/matbr_left.png</file>
|
||||||
|
<file>resources/matbr_right.png</file>
|
||||||
|
</qresource>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>resources/Mr-potato.icns</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
18
imglist.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef IMGLIST_H
|
||||||
|
#define IMGLIST_H
|
||||||
|
|
||||||
|
#include <QListWidget>
|
||||||
|
|
||||||
|
class ImgList : public QListWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ImgList(QWidget *parent = 0);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IMGLIST_H
|
62
main.cpp
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QCameraInfo>
|
||||||
|
|
||||||
|
/* Filters */
|
||||||
|
#include "filters.h"
|
||||||
|
#include "imagelist.h"
|
||||||
|
#include "filterlist.h"
|
||||||
|
#include "source.h"
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
|
Source *source;
|
||||||
|
Camera *cam;
|
||||||
|
FilterList *filters;
|
||||||
|
ImageList *images;
|
||||||
|
MainWindow *mwindow;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
|
||||||
|
QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
|
||||||
|
foreach (const QCameraInfo &cameraInfo, cameras)
|
||||||
|
qDebug() << "Found Qt camera: " << cameraInfo.deviceName() << ": " << cameraInfo.description();
|
||||||
|
|
||||||
|
filters = new FilterList;
|
||||||
|
images = new ImageList;
|
||||||
|
source = new Source;
|
||||||
|
cam = new Camera(source);
|
||||||
|
mwindow = new MainWindow;
|
||||||
|
|
||||||
|
QStringList imgs = QCoreApplication::arguments();
|
||||||
|
imgs.removeFirst();
|
||||||
|
imgs.removeDuplicates();
|
||||||
|
imgs.sort();
|
||||||
|
images->load(imgs);
|
||||||
|
|
||||||
|
/* Setup pipeline */
|
||||||
|
#if 1
|
||||||
|
filters->add(new Blur(Blur::GAUSSIAN, Size(3, 3)));
|
||||||
|
filters->add(new KMeans(4));
|
||||||
|
filters->add(new Convert(COLOR_BGR2HSV));
|
||||||
|
filters->add(new Channel(1));
|
||||||
|
//filters->add(new Convert(COLOR_BGR2GRAY));
|
||||||
|
//filters->add(new HistEqualize());
|
||||||
|
filters->add(new Threshold(Threshold::OTSU));
|
||||||
|
//filters->add(new EdgeDetect(80, 3));
|
||||||
|
//filters->add(new Watershed());
|
||||||
|
filters->add(new Morph(MORPH_CLOSE, MORPH_RECT));
|
||||||
|
filters->add(new ShapeDetect());
|
||||||
|
//filters->add(new MaxChannel());
|
||||||
|
//filters->add(new Normalize());
|
||||||
|
#else
|
||||||
|
filters->add(new Undistort(cam));
|
||||||
|
filters->add(new Pattern(Size(13, 9), 60));
|
||||||
|
filters->add(new Perspective(cam, (Pattern *) filters->last()));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mwindow->show();
|
||||||
|
|
||||||
|
return a.exec();
|
||||||
|
}
|
64
mainwindow.cpp
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
#include <opencv2/core.hpp>
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
#include "ui_about.h"
|
||||||
|
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
extern FilterList *filters;
|
||||||
|
extern ImageList *images;
|
||||||
|
extern Camera *cam;
|
||||||
|
extern Source *source;
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent) :
|
||||||
|
QMainWindow(parent),
|
||||||
|
ui(new Ui::MainWindow)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
ui->logConsole->setup();
|
||||||
|
ui->splitterH->setSizes({
|
||||||
|
static_cast<int>(0.8 * ui->splitterH->width()),
|
||||||
|
static_cast<int>(0.2 * ui->splitterH->width())
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Connect actions */
|
||||||
|
connect(images, &ImageList::newImage, ui->viewer, &Viewer::showImage);
|
||||||
|
connect(source, &Source::newImage, ui->viewer, &Viewer::showImage);
|
||||||
|
connect(filters, &FilterList::filtersChanged,ui->viewer, &Viewer::updateImage);
|
||||||
|
connect(ui->actionRedraw, &QAction::triggered, ui->viewer, &Viewer::updateImage);
|
||||||
|
connect(ui->actionCalibrate, &QAction::triggered, ui->tabCalibration, &TabCalibration::doCalibration);
|
||||||
|
connect(ui->actionSnapshot, &QAction::triggered, ui->tabCamera, &TabCamera::doSnapshot);
|
||||||
|
connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::showAbout);
|
||||||
|
connect(ui->actionExit, &QAction::triggered, this, &MainWindow::close);
|
||||||
|
connect(ui->actionClear, &QAction::triggered, images, &ImageList::clear);
|
||||||
|
connect(ui->actionLoad, &QAction::triggered, images, &ImageList::loadFilePicker);
|
||||||
|
connect(ui->actionSave, &QAction::triggered, images, &ImageList::saveFilePicker);
|
||||||
|
connect(ui->actionNextImage, &QAction::triggered, images, &ImageList::nextImage);
|
||||||
|
connect(ui->actionPrevImage, &QAction::triggered, images, &ImageList::prevImage);
|
||||||
|
connect(ui->actionPlay, &QAction::triggered, source, &Source::play);
|
||||||
|
connect(ui->actionTabImages, &QAction::triggered, [=]() { ui->tabWidget->setCurrentWidget(ui->tabImages); });
|
||||||
|
connect(ui->actionTabFilters, &QAction::triggered, [=]() { ui->tabWidget->setCurrentWidget(ui->tabFilters); });
|
||||||
|
connect(ui->actionTabCamera, &QAction::triggered, [=]() { ui->tabWidget->setCurrentWidget(ui->tabCamera); });
|
||||||
|
connect(ui->actionTabCalibration,&QAction::triggered, [=]() { ui->tabWidget->setCurrentWidget(ui->tabCalibration); });
|
||||||
|
|
||||||
|
updateGeometry();
|
||||||
|
showMaximized();
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::showAbout()
|
||||||
|
{
|
||||||
|
QDialog dialog(this);
|
||||||
|
Ui::AboutDialog about;
|
||||||
|
|
||||||
|
about.setupUi(&dialog);
|
||||||
|
dialog.exec();
|
||||||
|
}
|
43
mainwindow.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef MAINWINDOW_H
|
||||||
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QSignalMapper>
|
||||||
|
|
||||||
|
#include "tabcalibration.h"
|
||||||
|
#include "tabcamera.h"
|
||||||
|
#include "tabfilters.h"
|
||||||
|
#include "tabimages.h"
|
||||||
|
#include "tabpads.h"
|
||||||
|
|
||||||
|
#include "filterlist.h"
|
||||||
|
#include "imagelist.h"
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class MainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MainWindow(QWidget *parent = 0);
|
||||||
|
~MainWindow();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void showAbout();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void newImage(Image *img);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MAINWINDOW_H
|
490
mainwindow.ui
Normal file
|
@ -0,0 +1,490 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>1267</width>
|
||||||
|
<height>903</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Pastie</string>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>32</width>
|
||||||
|
<height>32</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="tabShape">
|
||||||
|
<enum>QTabWidget::Triangular</enum>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralWidget">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QSplitter" name="splitterV">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<widget class="QSplitter" name="splitterH">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<widget class="Viewer" name="viewer" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>320</width>
|
||||||
|
<height>240</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="contextMenuPolicy">
|
||||||
|
<enum>Qt::DefaultContextMenu</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>200</width>
|
||||||
|
<height>400</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="tabShape">
|
||||||
|
<enum>QTabWidget::Rounded</enum>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="TabImages" name="tabImages">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Images</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
<widget class="TabFilters" name="tabFilters">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Filters</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
<widget class="TabCamera" name="tabCamera">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Camera</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
<widget class="TabCalibration" name="tabCalibration">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Calibration</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="Console" name="logConsole">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>100</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="undoRedoEnabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="plainText">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="centerOnScroll">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QToolBar" name="toolBar">
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>toolBar</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="movable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="floatable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="toolBarArea">
|
||||||
|
<enum>LeftToolBarArea</enum>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="toolBarBreak">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<addaction name="actionLoad"/>
|
||||||
|
<addaction name="actionSave"/>
|
||||||
|
<addaction name="actionClear"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionPlay"/>
|
||||||
|
<addaction name="actionSnapshot"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionPrevImage"/>
|
||||||
|
<addaction name="actionRedraw"/>
|
||||||
|
<addaction name="actionNextImage"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionCalibrate"/>
|
||||||
|
<addaction name="actionReset"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionExit"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenuBar" name="menuBar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>1267</width>
|
||||||
|
<height>22</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="nativeMenuBar">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenu" name="menuFile">
|
||||||
|
<property name="title">
|
||||||
|
<string>Images</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionLoad"/>
|
||||||
|
<addaction name="actionClear"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionExit"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menu">
|
||||||
|
<property name="title">
|
||||||
|
<string>?</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionAbout"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuCamera">
|
||||||
|
<property name="title">
|
||||||
|
<string>Camera</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionSnapshot"/>
|
||||||
|
<addaction name="actionPlay"/>
|
||||||
|
<addaction name="actionCalibrate"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuTabs">
|
||||||
|
<property name="title">
|
||||||
|
<string>Tabs</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionTabImages"/>
|
||||||
|
<addaction name="actionTabCamera"/>
|
||||||
|
<addaction name="actionTabFilters"/>
|
||||||
|
<addaction name="actionTabCalibration"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menuFile"/>
|
||||||
|
<addaction name="menuCamera"/>
|
||||||
|
<addaction name="menuTabs"/>
|
||||||
|
<addaction name="menu"/>
|
||||||
|
</widget>
|
||||||
|
<action name="actionLoad">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="document-open" resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/document-open.png</normaloff>:/icons/resources/document-open.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Load</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Load images from files</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+O</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionExit">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/system-log-out.png</normaloff>:/icons/resources/system-log-out.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Exit</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Quit program</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+Q</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionAbout">
|
||||||
|
<property name="text">
|
||||||
|
<string>About</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionCalibrate">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/calibrate.png</normaloff>:/icons/resources/calibrate.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Calibrate</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+C</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionClear">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/edit-clear.png</normaloff>:/icons/resources/edit-clear.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Clear</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Remove all images from the list</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+P</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionPlay">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/media-playback-start.png</normaloff>
|
||||||
|
<normalon>:/icons/resources/media-playback-stop.png</normalon>:/icons/resources/media-playback-start.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Start / Stop</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Start / Stop the live preview</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+X</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSnapshot">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/camera-photo.png</normaloff>:/icons/resources/camera-photo.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Snapshot</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Take a snapshot of the current viewfinder</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+Y</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionPrevImage">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/go-previous.png</normaloff>:/icons/resources/go-previous.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Previous Image</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Show previous image from list</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Down</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionNextImage">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/go-next.png</normaloff>:/icons/resources/go-next.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Next Image</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Show next image from list</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Up</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSave">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/document-save.png</normaloff>:/icons/resources/document-save.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Save</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Save the current image to a file</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+S</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionReset">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/edit-undo.png</normaloff>:/icons/resources/edit-undo.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Reset Calibration</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Reset camera matrix and distortion coefficients obtained through calibration</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+R</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionTabImages">
|
||||||
|
<property name="text">
|
||||||
|
<string>Images</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>F1</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionTabFilters">
|
||||||
|
<property name="text">
|
||||||
|
<string>Filters</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>F2</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionTabCamera">
|
||||||
|
<property name="text">
|
||||||
|
<string>Camera</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>F3</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionTabCalibration">
|
||||||
|
<property name="text">
|
||||||
|
<string>Calibration</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>F4</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionRedraw">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/view-refresh.png</normaloff>:/icons/resources/view-refresh.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Redraw</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>F5</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>Viewer</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>viewer.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>Console</class>
|
||||||
|
<extends>QPlainTextEdit</extends>
|
||||||
|
<header>console.h</header>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>TabImages</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>tabimages.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>TabFilters</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>tabfilters.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>TabCamera</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>tabcamera.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>TabCalibration</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>tabcalibration.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources>
|
||||||
|
<include location="images.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
<slots>
|
||||||
|
<slot>showAbout()</slot>
|
||||||
|
</slots>
|
||||||
|
</ui>
|
15
painter.cpp
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#include "painter.h"
|
||||||
|
|
||||||
|
Painter::Painter(QPaintDevice *device, double r) :
|
||||||
|
QPainter(device),
|
||||||
|
ratio(r)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
void Painter::drawMarker(const QPoint ¢er, int r)
|
||||||
|
{
|
||||||
|
drawEllipse(center, r, r);
|
||||||
|
drawLine(center + QPoint(+r, +r), center - QPoint(+r, +r));
|
||||||
|
drawLine(center + QPoint(+r, -r), center - QPoint(+r, -r));
|
||||||
|
}
|
||||||
|
|
18
painter.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef PAINTER_H
|
||||||
|
#define PAINTER_H
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
class Painter : public QPainter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Painter(QPaintDevice *device, double ratio = 1);
|
||||||
|
|
||||||
|
void drawMarker(const QPoint ¢er, int radius = 8);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
double ratio;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PAINTER_H
|
BIN
resources/Mr-potato.icns
Normal file
BIN
resources/Mr-potato.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
resources/acirc.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/calibrate.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
resources/camera-photo.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
resources/cap5h.jpg
Normal file
After Width: | Height: | Size: 79 KiB |
BIN
resources/chess.png
Normal file
After Width: | Height: | Size: 953 B |
185
resources/chess.svg
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="48"
|
||||||
|
height="48"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.5 r10040"
|
||||||
|
sodipodi:docname="circ.svg"
|
||||||
|
inkscape:export-filename="/home/stv0g/workspace/dbvsem/code/pastie/resources/chess.png"
|
||||||
|
inkscape:export-xdpi="90"
|
||||||
|
inkscape:export-ydpi="90">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="5.7604167"
|
||||||
|
inkscape:cx="30.786693"
|
||||||
|
inkscape:cy="19.146453"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:snap-bbox="true"
|
||||||
|
inkscape:bbox-nodes="true"
|
||||||
|
inkscape:snap-page="true"
|
||||||
|
inkscape:snap-global="true"
|
||||||
|
inkscape:window-width="1278"
|
||||||
|
inkscape:window-height="750"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="24"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Ebene 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-1004.3622)">
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||||
|
d="m 40.508388,1049.148 -5.892129,0 0,-10.459 10.556733,0 0,6.1626 z"
|
||||||
|
id="rect3755-6"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccc" />
|
||||||
|
<path
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
d="m 13.502795,1049.148 -6.0148868,0 -4.541846,-4.2964 0,-6.1626 10.5567328,0 z"
|
||||||
|
id="rect3755-0-2-7"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccc" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||||
|
d="m 7.6106683,1007.3119 5.8921297,0 0,10.459 -10.5567333,0 0,-6.1626 z"
|
||||||
|
id="rect3755"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccc" />
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3755-0"
|
||||||
|
width="10.556733"
|
||||||
|
height="10.458986"
|
||||||
|
x="13.502797"
|
||||||
|
y="1007.3119" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3755-4"
|
||||||
|
width="10.556733"
|
||||||
|
height="10.458986"
|
||||||
|
x="24.059528"
|
||||||
|
y="1007.3119" />
|
||||||
|
<path
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
d="m 34.616261,1007.3119 6.014887,0 4.541846,4.2964 0,6.1626 -10.556733,0 z"
|
||||||
|
id="rect3755-0-2"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccc" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3755-2"
|
||||||
|
width="10.556733"
|
||||||
|
height="10.458986"
|
||||||
|
x="-45.172997"
|
||||||
|
y="1017.7709"
|
||||||
|
transform="scale(-1,1)" />
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3755-0-24"
|
||||||
|
width="10.556733"
|
||||||
|
height="10.458986"
|
||||||
|
x="-34.616264"
|
||||||
|
y="1017.7709"
|
||||||
|
transform="scale(-1,1)" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3755-4-0"
|
||||||
|
width="10.556733"
|
||||||
|
height="10.458986"
|
||||||
|
x="-24.059528"
|
||||||
|
y="1017.7709"
|
||||||
|
transform="scale(-1,1)" />
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3755-0-2-8"
|
||||||
|
width="10.556733"
|
||||||
|
height="10.458986"
|
||||||
|
x="-13.502797"
|
||||||
|
y="1017.7709"
|
||||||
|
transform="scale(-1,1)" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3755-1"
|
||||||
|
width="10.556733"
|
||||||
|
height="10.458986"
|
||||||
|
x="2.9460647"
|
||||||
|
y="1028.23" />
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3755-0-0"
|
||||||
|
width="10.556733"
|
||||||
|
height="10.458986"
|
||||||
|
x="13.502797"
|
||||||
|
y="1028.23" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3755-4-6"
|
||||||
|
width="10.556733"
|
||||||
|
height="10.458986"
|
||||||
|
x="24.059528"
|
||||||
|
y="1028.23" />
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3755-0-2-9"
|
||||||
|
width="10.556733"
|
||||||
|
height="10.458986"
|
||||||
|
x="34.616261"
|
||||||
|
y="1028.23" />
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3755-0-24-5"
|
||||||
|
width="10.556733"
|
||||||
|
height="10.458986"
|
||||||
|
x="-34.616264"
|
||||||
|
y="1038.689"
|
||||||
|
transform="scale(-1,1)" />
|
||||||
|
<rect
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none"
|
||||||
|
id="rect3755-4-0-5"
|
||||||
|
width="10.556733"
|
||||||
|
height="10.458986"
|
||||||
|
x="-24.059528"
|
||||||
|
y="1038.689"
|
||||||
|
transform="scale(-1,1)" />
|
||||||
|
<rect
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.94646239000000021;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
id="rect2985"
|
||||||
|
width="44.053532"
|
||||||
|
height="44.053532"
|
||||||
|
x="1.9732312"
|
||||||
|
y="1006.3354"
|
||||||
|
ry="10.36474" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 5.5 KiB |
BIN
resources/circ.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
187
resources/circ.svg
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="48"
|
||||||
|
height="48"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.5 r10040"
|
||||||
|
sodipodi:docname="circ.svg"
|
||||||
|
inkscape:export-filename="/home/stv0g/workspace/dbvsem/code/pastie/resources/chess.png"
|
||||||
|
inkscape:export-xdpi="90"
|
||||||
|
inkscape:export-ydpi="90">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="5.7604167"
|
||||||
|
inkscape:cx="8.479279"
|
||||||
|
inkscape:cy="19.146453"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:snap-bbox="false"
|
||||||
|
inkscape:bbox-nodes="true"
|
||||||
|
inkscape:snap-page="true"
|
||||||
|
inkscape:snap-global="true"
|
||||||
|
inkscape:window-width="1278"
|
||||||
|
inkscape:window-height="750"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="24"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:object-paths="true"
|
||||||
|
inkscape:object-nodes="false"
|
||||||
|
inkscape:snap-intersection-paths="true"
|
||||||
|
inkscape:snap-smooth-nodes="false"
|
||||||
|
inkscape:snap-midpoints="false"
|
||||||
|
inkscape:snap-nodes="true"
|
||||||
|
inkscape:snap-object-midpoints="true" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Ebene 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(0,-1004.3622)">
|
||||||
|
<rect
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:3.94646239;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
id="rect2985"
|
||||||
|
width="44.053532"
|
||||||
|
height="44.053532"
|
||||||
|
x="1.9732342"
|
||||||
|
y="1006.3354"
|
||||||
|
ry="10.36474" />
|
||||||
|
<g
|
||||||
|
id="g4780"
|
||||||
|
transform="translate(-2.6303638e-6,-0.18770124)">
|
||||||
|
<g
|
||||||
|
transform="translate(-0.34719718,0)"
|
||||||
|
id="g4716">
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="fill:#000000;stroke:none"
|
||||||
|
id="path3915"
|
||||||
|
sodipodi:cx="-25.345388"
|
||||||
|
sodipodi:cy="4.6003618"
|
||||||
|
sodipodi:rx="4.687161"
|
||||||
|
sodipodi:ry="4.687161"
|
||||||
|
d="m -20.658227,4.6003618 c 0,2.5886475 -2.098514,4.687161 -4.687161,4.687161 -2.588648,0 -4.687161,-2.0985135 -4.687161,-4.687161 0,-2.5886475 2.098513,-4.68716094 4.687161,-4.68716094 2.588647,0 4.687161,2.09851344 4.687161,4.68716094 z"
|
||||||
|
transform="matrix(0.93157895,0,0,0.93157895,36.267022,1012.5729)" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="fill:#000000;stroke:none"
|
||||||
|
id="path3915-2"
|
||||||
|
sodipodi:cx="-25.345388"
|
||||||
|
sodipodi:cy="4.6003618"
|
||||||
|
sodipodi:rx="4.687161"
|
||||||
|
sodipodi:ry="4.687161"
|
||||||
|
d="m -20.658227,4.6003618 c 0,2.5886475 -2.098514,4.687161 -4.687161,4.687161 -2.588648,0 -4.687161,-2.0985135 -4.687161,-4.687161 0,-2.5886475 2.098513,-4.68716094 4.687161,-4.68716094 2.588647,0 4.687161,2.09851344 4.687161,4.68716094 z"
|
||||||
|
transform="matrix(0.93157895,0,0,0.93157895,47.958425,1012.5729)" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="fill:#000000;stroke:none"
|
||||||
|
id="path3915-5"
|
||||||
|
sodipodi:cx="-25.345388"
|
||||||
|
sodipodi:cy="4.6003618"
|
||||||
|
sodipodi:rx="4.687161"
|
||||||
|
sodipodi:ry="4.687161"
|
||||||
|
d="m -20.658227,4.6003618 c 0,2.5886475 -2.098514,4.687161 -4.687161,4.687161 -2.588648,0 -4.687161,-2.0985135 -4.687161,-4.687161 0,-2.5886475 2.098513,-4.68716094 4.687161,-4.68716094 2.588647,0 4.687161,2.09851344 4.687161,4.68716094 z"
|
||||||
|
transform="matrix(0.93157895,0,0,0.93157895,59.649833,1012.5729)" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g4774">
|
||||||
|
<g
|
||||||
|
id="g4716-2"
|
||||||
|
transform="translate(-0.34719563,11.503652)">
|
||||||
|
<path
|
||||||
|
transform="matrix(0.93157895,0,0,0.93157895,36.267022,1012.5729)"
|
||||||
|
d="m -20.658227,4.6003618 c 0,2.5886475 -2.098514,4.687161 -4.687161,4.687161 -2.588648,0 -4.687161,-2.0985135 -4.687161,-4.687161 0,-2.5886475 2.098513,-4.68716094 4.687161,-4.68716094 2.588647,0 4.687161,2.09851344 4.687161,4.68716094 z"
|
||||||
|
sodipodi:ry="4.687161"
|
||||||
|
sodipodi:rx="4.687161"
|
||||||
|
sodipodi:cy="4.6003618"
|
||||||
|
sodipodi:cx="-25.345388"
|
||||||
|
id="path3915-6"
|
||||||
|
style="fill:#000000;stroke:none"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<path
|
||||||
|
transform="matrix(0.93157895,0,0,0.93157895,47.958425,1012.5729)"
|
||||||
|
d="m -20.658227,4.6003618 c 0,2.5886475 -2.098514,4.687161 -4.687161,4.687161 -2.588648,0 -4.687161,-2.0985135 -4.687161,-4.687161 0,-2.5886475 2.098513,-4.68716094 4.687161,-4.68716094 2.588647,0 4.687161,2.09851344 4.687161,4.68716094 z"
|
||||||
|
sodipodi:ry="4.687161"
|
||||||
|
sodipodi:rx="4.687161"
|
||||||
|
sodipodi:cy="4.6003618"
|
||||||
|
sodipodi:cx="-25.345388"
|
||||||
|
id="path3915-2-5"
|
||||||
|
style="fill:#000000;stroke:none"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<path
|
||||||
|
transform="matrix(0.93157895,0,0,0.93157895,59.649833,1012.5729)"
|
||||||
|
d="m -20.658227,4.6003618 c 0,2.5886475 -2.098514,4.687161 -4.687161,4.687161 -2.588648,0 -4.687161,-2.0985135 -4.687161,-4.687161 0,-2.5886475 2.098513,-4.68716094 4.687161,-4.68716094 2.588647,0 4.687161,2.09851344 4.687161,4.68716094 z"
|
||||||
|
sodipodi:ry="4.687161"
|
||||||
|
sodipodi:rx="4.687161"
|
||||||
|
sodipodi:cy="4.6003618"
|
||||||
|
sodipodi:cx="-25.345388"
|
||||||
|
id="path3915-5-5"
|
||||||
|
style="fill:#000000;stroke:none"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="translate(-0.34719191,23.382802)"
|
||||||
|
id="g4716-8">
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="fill:#000000;stroke:none"
|
||||||
|
id="path3915-71"
|
||||||
|
sodipodi:cx="-25.345388"
|
||||||
|
sodipodi:cy="4.6003618"
|
||||||
|
sodipodi:rx="4.687161"
|
||||||
|
sodipodi:ry="4.687161"
|
||||||
|
d="m -20.658227,4.6003618 c 0,2.5886475 -2.098514,4.687161 -4.687161,4.687161 -2.588648,0 -4.687161,-2.0985135 -4.687161,-4.687161 0,-2.5886475 2.098513,-4.68716094 4.687161,-4.68716094 2.588647,0 4.687161,2.09851344 4.687161,4.68716094 z"
|
||||||
|
transform="matrix(0.93157895,0,0,0.93157895,36.267022,1012.5729)" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="fill:#000000;stroke:none"
|
||||||
|
id="path3915-2-0"
|
||||||
|
sodipodi:cx="-25.345388"
|
||||||
|
sodipodi:cy="4.6003618"
|
||||||
|
sodipodi:rx="4.687161"
|
||||||
|
sodipodi:ry="4.687161"
|
||||||
|
d="m -20.658227,4.6003618 c 0,2.5886475 -2.098514,4.687161 -4.687161,4.687161 -2.588648,0 -4.687161,-2.0985135 -4.687161,-4.687161 0,-2.5886475 2.098513,-4.68716094 4.687161,-4.68716094 2.588647,0 4.687161,2.09851344 4.687161,4.68716094 z"
|
||||||
|
transform="matrix(0.93157895,0,0,0.93157895,47.958425,1012.5729)" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="fill:#000000;stroke:none"
|
||||||
|
id="path3915-5-53"
|
||||||
|
sodipodi:cx="-25.345388"
|
||||||
|
sodipodi:cy="4.6003618"
|
||||||
|
sodipodi:rx="4.687161"
|
||||||
|
sodipodi:ry="4.687161"
|
||||||
|
d="m -20.658227,4.6003618 c 0,2.5886475 -2.098514,4.687161 -4.687161,4.687161 -2.588648,0 -4.687161,-2.0985135 -4.687161,-4.687161 0,-2.5886475 2.098513,-4.68716094 4.687161,-4.68716094 2.588647,0 4.687161,2.09851344 4.687161,4.68716094 z"
|
||||||
|
transform="matrix(0.93157895,0,0,0.93157895,59.649833,1012.5729)" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 8 KiB |
BIN
resources/document-open.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
resources/document-save.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
resources/edit-clear.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
resources/edit-undo.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
resources/go-next.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/go-previous.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/image-x-generic.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
15
resources/intro.html
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<h2>Welcome to Pastie 0.1</h2>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
Seminar <b>Digital Image Processing and Content Analysis</b> WS 2014/15<br/>
|
||||||
|
Institute of Imaging & Computer Vision (LfB)<br/>
|
||||||
|
RWTH Aachen University<br/>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
Written by Steffen Vogel
|
||||||
|
<ul>
|
||||||
|
<li>Mail: <a href="mailto:steffen.vogel@rwth-aachen.de">steffen.vogel@rwth-aachen.de</a></li>
|
||||||
|
<li>Web: <a href="http://www.steffenvogel.de">www.steffenvogel.de</a></li>
|
||||||
|
</ul><br>
|
||||||
|
|
||||||
|
<em>This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version.</em><br/>
|
BIN
resources/list-add.png
Normal file
After Width: | Height: | Size: 601 B |
BIN
resources/list-remove.png
Normal file
After Width: | Height: | Size: 317 B |
64
resources/matbr.svg
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="210mm"
|
||||||
|
height="297mm"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.5 r10040"
|
||||||
|
sodipodi:docname="Neues Dokument 1">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="3.959798"
|
||||||
|
inkscape:cx="111.80375"
|
||||||
|
inkscape:cy="932.59156"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1278"
|
||||||
|
inkscape:window-height="750"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="24"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Ebene 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:2.4879477;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
d="m 98.478771,74.270877 5.722049,0 0,64.924503 -5.722049,0"
|
||||||
|
id="path2985"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccc"
|
||||||
|
inkscape:export-filename="/home/stv0g/workspace/rwth-dbv/code/pastie/resources/matbr_right.png"
|
||||||
|
inkscape:export-xdpi="230"
|
||||||
|
inkscape:export-ydpi="230" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2 KiB |
BIN
resources/matbr_left.png
Normal file
After Width: | Height: | Size: 245 B |
BIN
resources/matbr_right.png
Normal file
After Width: | Height: | Size: 260 B |
BIN
resources/media-playback-start.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
resources/media-playback-stop.png
Normal file
After Width: | Height: | Size: 571 B |
BIN
resources/perspective.png
Normal file
After Width: | Height: | Size: 914 B |
BIN
resources/system-log-out.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
resources/view-refresh.png
Normal file
After Width: | Height: | Size: 2 KiB |
86
source.cpp
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
#include <QDir>
|
||||||
|
#include <QtDebug>
|
||||||
|
|
||||||
|
#include <opencv2/core.hpp>
|
||||||
|
|
||||||
|
#include "source.h"
|
||||||
|
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
Source::Source() :
|
||||||
|
VideoCapture(CAP_ANY)
|
||||||
|
{
|
||||||
|
if (!isOpened())
|
||||||
|
throw Exception();
|
||||||
|
|
||||||
|
setSize(Size(640, 480));
|
||||||
|
setFPS(15);
|
||||||
|
|
||||||
|
connect(&tmr, SIGNAL(timeout()), this, SLOT(tick()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Size Source::getSize()
|
||||||
|
{
|
||||||
|
return Size(
|
||||||
|
get(CAP_PROP_FRAME_WIDTH),
|
||||||
|
get(CAP_PROP_FRAME_HEIGHT)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Source::setSize(const Size s)
|
||||||
|
{
|
||||||
|
set(CAP_PROP_FRAME_WIDTH, s.width);
|
||||||
|
return set(CAP_PROP_FRAME_HEIGHT, s.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
double Source::getFPS()
|
||||||
|
{
|
||||||
|
return fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Source::setFPS(double f)
|
||||||
|
{
|
||||||
|
fps = f;
|
||||||
|
|
||||||
|
if (tmr.isActive())
|
||||||
|
tmr.start(1000.0 / fps);
|
||||||
|
|
||||||
|
return set(CAP_PROP_FPS, fps);
|
||||||
|
}
|
||||||
|
|
||||||
|
Image * Source::getSnapshot()
|
||||||
|
{
|
||||||
|
static unsigned no;
|
||||||
|
|
||||||
|
Mat mat;
|
||||||
|
QString fileName = QString("%1/snapshot_%2.png")
|
||||||
|
.arg(QDir::tempPath()).arg(no++);
|
||||||
|
|
||||||
|
read(mat);
|
||||||
|
|
||||||
|
return new Image(mat, fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Source::play(bool run)
|
||||||
|
{
|
||||||
|
if (run)
|
||||||
|
tmr.start(1000.0 / fps);
|
||||||
|
else
|
||||||
|
tmr.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Source::tick()
|
||||||
|
{
|
||||||
|
static bool running;
|
||||||
|
|
||||||
|
if (running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
running = true;
|
||||||
|
|
||||||
|
if (read(last.original))
|
||||||
|
emit newImage(&last);
|
||||||
|
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
46
source.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef SOURCE_H
|
||||||
|
#define SOURCE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <opencv2/videoio.hpp>
|
||||||
|
|
||||||
|
#include "image.h"
|
||||||
|
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
class Source :
|
||||||
|
public QObject,
|
||||||
|
public VideoCapture
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Source();
|
||||||
|
|
||||||
|
Size getSize();
|
||||||
|
bool setSize(const Size s);
|
||||||
|
|
||||||
|
double getFPS();
|
||||||
|
bool setFPS(double f);
|
||||||
|
|
||||||
|
Image * getSnapshot();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void play(bool);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void newImage(Image *img);
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void tick();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Image last;
|
||||||
|
QTimer tmr;
|
||||||
|
|
||||||
|
double fps;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SOURCE_H
|
81
tabcalibration.cpp
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
#include <opencv2/core.hpp>
|
||||||
|
|
||||||
|
#include "filters/pattern.h"
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "imagelist.h"
|
||||||
|
#include "tabcalibration.h"
|
||||||
|
#include "ui_tabcalibration.h"
|
||||||
|
|
||||||
|
extern Camera *cam;
|
||||||
|
extern ImageList *images;
|
||||||
|
extern FilterList *filters;
|
||||||
|
extern MainWindow *mwindow;
|
||||||
|
|
||||||
|
TabCalibration::TabCalibration(QWidget *parent) :
|
||||||
|
QWidget(parent),
|
||||||
|
ui(new Ui::TabCalibration)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
connect(ui->btnCalibrate, &QPushButton::clicked, this, &TabCalibration::doCalibration);
|
||||||
|
connect(ui->btnPerspective, &QPushButton::clicked, this, &TabCalibration::doPerspective);
|
||||||
|
connect(ui->btnReset, &QPushButton::clicked, this, &TabCalibration::resetCalibration);
|
||||||
|
}
|
||||||
|
|
||||||
|
TabCalibration::~TabCalibration()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabCalibration::doPerspective()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabCalibration::doCalibration()
|
||||||
|
{
|
||||||
|
int index = ui->cmbBoardPattern->currentIndex();
|
||||||
|
float spacing = ui->spinBoardSpacing->value();
|
||||||
|
|
||||||
|
Size size = Size(ui->spinBoardSizeX->value(), ui->spinBoardSizeY->value());
|
||||||
|
Pattern *pattern = new Pattern(size, spacing, Pattern::Type(index));
|
||||||
|
|
||||||
|
filters->add(pattern);
|
||||||
|
|
||||||
|
if (cam->calibrate(images->selectedImages().toStdList(), pattern))
|
||||||
|
showResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabCalibration::resetCalibration()
|
||||||
|
{
|
||||||
|
filters->reset();
|
||||||
|
cam->reset();
|
||||||
|
|
||||||
|
showResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabCalibration::showResults()
|
||||||
|
{
|
||||||
|
/* Reprojection Error */
|
||||||
|
ui->lblAvgReprErr->setText(QString::number(cam->getAvgReprErr()));
|
||||||
|
|
||||||
|
/* Distortion coefficients */
|
||||||
|
Mat mat = cam->getDistCoeffs();
|
||||||
|
ui->lblDistCoeff_0->setText(QString::number(mat.at<float>(0), 'g', 4));
|
||||||
|
ui->lblDistCoeff_1->setText(QString::number(mat.at<float>(1), 'g', 4));
|
||||||
|
ui->lblDistCoeff_2->setText(QString::number(mat.at<float>(2), 'g', 4));
|
||||||
|
ui->lblDistCoeff_3->setText(QString::number(mat.at<float>(3), 'g', 4));
|
||||||
|
ui->lblDistCoeff_4->setText(QString::number(mat.at<float>(4), 'g', 4));
|
||||||
|
|
||||||
|
/* Camera Matrix */
|
||||||
|
mat = cam->getMatrix();
|
||||||
|
ui->lblMatrix_0_0->setText(QString::number(mat.at<float>(0, 0), 'g', 4));
|
||||||
|
ui->lblMatrix_0_1->setText(QString::number(mat.at<float>(0, 1), 'g', 4));
|
||||||
|
ui->lblMatrix_0_2->setText(QString::number(mat.at<float>(0, 2), 'g', 4));
|
||||||
|
ui->lblMatrix_1_0->setText(QString::number(mat.at<float>(1, 0), 'g', 4));
|
||||||
|
ui->lblMatrix_1_1->setText(QString::number(mat.at<float>(1, 1), 'g', 4));
|
||||||
|
ui->lblMatrix_1_2->setText(QString::number(mat.at<float>(1, 2), 'g', 4));
|
||||||
|
ui->lblMatrix_2_0->setText(QString::number(mat.at<float>(2, 0), 'g', 4));
|
||||||
|
ui->lblMatrix_2_1->setText(QString::number(mat.at<float>(2, 1), 'g', 4));
|
||||||
|
ui->lblMatrix_2_2->setText(QString::number(mat.at<float>(2, 2), 'g', 4));
|
||||||
|
}
|
30
tabcalibration.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef TABCALIBRATION_H
|
||||||
|
#define TABCALIBRATION_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class TabCalibration;
|
||||||
|
}
|
||||||
|
|
||||||
|
class TabCalibration : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
TabCalibration(QWidget *parent = 0);
|
||||||
|
~TabCalibration();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void doCalibration();
|
||||||
|
void doPerspective();
|
||||||
|
void resetCalibration();
|
||||||
|
void showResults();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::TabCalibration *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TABCALIBRATION_H
|
870
tabcalibration.ui
Normal file
|
@ -0,0 +1,870 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>TabCalibration</class>
|
||||||
|
<widget class="QWidget" name="TabCalibration">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>532</width>
|
||||||
|
<height>543</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>12</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="widget_9" native="true">
|
||||||
|
<layout class="QFormLayout" name="formLayout_7">
|
||||||
|
<property name="fieldGrowthPolicy">
|
||||||
|
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||||
|
</property>
|
||||||
|
<property name="formAlignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_32">
|
||||||
|
<property name="text">
|
||||||
|
<string>Pattern</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="cmbBoardPattern">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string comment="chess">Chessboard</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/chess.png</normaloff>:/icons/resources/chess.png</iconset>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string comment="circ">Circles Symmetric</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/circ.png</normaloff>:/icons/resources/circ.png</iconset>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string comment="circa">Circles Asymmetric</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/acirc.png</normaloff>:/icons/resources/acirc.png</iconset>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_29">
|
||||||
|
<property name="text">
|
||||||
|
<string>Board Size</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QWidget" name="widget_10" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<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="QSpinBox" name="spinBoardSizeX">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_30">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>16</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>x</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="spinBoardSizeY">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="label_31">
|
||||||
|
<property name="text">
|
||||||
|
<string>Spacing</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QWidget" name="widget_11" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<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="QDoubleSpinBox" name="spinBoardSpacing">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>114</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>156</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>25.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="widget_5" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnCalibrate">
|
||||||
|
<property name="text">
|
||||||
|
<string>Calibrate</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/calibrate.png</normaloff>:/icons/resources/calibrate.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnPerspective">
|
||||||
|
<property name="text">
|
||||||
|
<string>Perspective</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/perspective.png</normaloff>:/icons/resources/perspective.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="btnReset">
|
||||||
|
<property name="text">
|
||||||
|
<string>Reset</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="images.qrc">
|
||||||
|
<normaloff>:/icons/resources/edit-undo.png</normaloff>:/icons/resources/edit-undo.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>124</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="grpResults">
|
||||||
|
<property name="title">
|
||||||
|
<string>Results</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="widget_12" native="true">
|
||||||
|
<layout class="QFormLayout" name="formLayout_4">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_34">
|
||||||
|
<property name="text">
|
||||||
|
<string>Average Reprojection Error:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLabel" name="lblAvgReprErr">
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Cam Matrix:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="matMatrix" native="true">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_24">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>5</width>
|
||||||
|
<height>60</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="images.qrc">:/math/resources/matbr_left.png</pixmap>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="widget_6" native="true">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>100</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLabel" name="lblMatrix_0_1">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="lblMatrix_0_0">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>1</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLabel" name="lblMatrix_2_1">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="lblMatrix_1_0">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="lblMatrix_1_1">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>1</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="lblMatrix_2_0">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QLabel" name="lblMatrix_1_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QLabel" name="lblMatrix_2_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>1</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QLabel" name="lblMatrix_0_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>25</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_25">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>5</width>
|
||||||
|
<height>60</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="images.qrc">:/math/resources/matbr_right.png</pixmap>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_33">
|
||||||
|
<property name="text">
|
||||||
|
<string>Distortion Coefficients:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="matDistCoeff" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_26">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>5</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="images.qrc">:/math/resources/matbr_left.png</pixmap>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="widget_8" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lblDistCoeff_2">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lblDistCoeff_0">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lblDistCoeff_3">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lblDistCoeff_1">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lblDistCoeff_4">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_40">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>5</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="images.qrc">:/math/resources/matbr_right.png</pixmap>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="widget_7" native="true">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="images.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
99
tabcamera.cpp
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
#include <opencv2/videoio.hpp>
|
||||||
|
|
||||||
|
#include <QtDebug>
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "camera.h"
|
||||||
|
#include "source.h"
|
||||||
|
#include "imagelist.h"
|
||||||
|
|
||||||
|
#include "tabcamera.h"
|
||||||
|
#include "ui_tabcamera.h"
|
||||||
|
|
||||||
|
extern Source *source;
|
||||||
|
extern Camera *cam;
|
||||||
|
extern ImageList *images;
|
||||||
|
extern FilterList *filters;
|
||||||
|
|
||||||
|
TabCamera::TabCamera(QWidget *parent) :
|
||||||
|
QWidget(parent),
|
||||||
|
ui(new Ui::TabCamera)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
ui->cmbCamResolution->setCurrentText(
|
||||||
|
QString("%1x%2").arg(source->getSize().width)
|
||||||
|
.arg(source->getSize().height)
|
||||||
|
);
|
||||||
|
ui->cmbCamFPS->setCurrentText(
|
||||||
|
QString::number(source->getFPS())
|
||||||
|
);
|
||||||
|
|
||||||
|
connect(ui->sldCamBrightness, &QSlider::sliderReleased, this, &TabCamera::changeSetting);
|
||||||
|
connect(ui->sldCamContrast, &QSlider::sliderReleased, this, &TabCamera::changeSetting);
|
||||||
|
connect(ui->sldCamExposure, &QSlider::sliderReleased, this, &TabCamera::changeSetting);
|
||||||
|
connect(ui->sldCamFocus, &QSlider::sliderReleased, this, &TabCamera::changeSetting);
|
||||||
|
connect(ui->sldCamGain, &QSlider::sliderReleased, this, &TabCamera::changeSetting);
|
||||||
|
connect(ui->sldCamGamma, &QSlider::sliderReleased, this, &TabCamera::changeSetting);
|
||||||
|
connect(ui->sldCamHue, &QSlider::sliderReleased, this, &TabCamera::changeSetting);
|
||||||
|
connect(ui->sldCamSharpness, &QSlider::sliderReleased, this, &TabCamera::changeSetting);
|
||||||
|
|
||||||
|
connect(ui->cmbCamFPS, &QComboBox::currentTextChanged, this, &TabCamera::changeFPS);
|
||||||
|
connect(ui->cmbCamResolution, &QComboBox::currentTextChanged, this, &TabCamera::changeResolution);
|
||||||
|
connect(ui->btnSnapshot, &QPushButton::clicked, this, &TabCamera::doSnapshot);
|
||||||
|
connect(ui->btnPlay, &QPushButton::clicked, source, &Source::play);
|
||||||
|
}
|
||||||
|
|
||||||
|
TabCamera::~TabCamera()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabCamera::changeResolution(QString resolution)
|
||||||
|
{
|
||||||
|
QStringList wh = resolution.split('x');
|
||||||
|
|
||||||
|
bool success = source->setSize(Size(wh[0].toInt(), wh[1].toInt()));
|
||||||
|
if (!success)
|
||||||
|
qWarning() << "Camera did not accept new resolution: " << resolution;
|
||||||
|
|
||||||
|
filters->reset();
|
||||||
|
cam->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabCamera::changeFPS(QString fps)
|
||||||
|
{
|
||||||
|
bool success = source->setFPS(fps.toDouble());
|
||||||
|
if (!success)
|
||||||
|
qWarning() << "Camera did not accept new FPS: " << fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabCamera::changeSetting()
|
||||||
|
{
|
||||||
|
QSlider *sld = qobject_cast<QSlider *>(sender());
|
||||||
|
|
||||||
|
int prop = getCVCap(sld);
|
||||||
|
double value = (double) sld->value() / 1000;
|
||||||
|
|
||||||
|
bool success = source->set(prop, value);
|
||||||
|
if (!success)
|
||||||
|
qWarning() << "Camera did not accept property " << prop << " with value " << value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TabCamera::getCVCap(QWidget *w)
|
||||||
|
{
|
||||||
|
if (w == ui->sldCamBrightness) return CAP_PROP_BRIGHTNESS;
|
||||||
|
else if (w == ui->sldCamContrast) return CAP_PROP_CONTRAST;
|
||||||
|
else if (w == ui->sldCamExposure) return CAP_PROP_EXPOSURE;
|
||||||
|
else if (w == ui->sldCamFocus) return CAP_PROP_FOCUS;
|
||||||
|
else if (w == ui->sldCamGain) return CAP_PROP_GAIN;
|
||||||
|
else if (w == ui->sldCamGamma) return CAP_PROP_GAMMA;
|
||||||
|
else if (w == ui->sldCamHue) return CAP_PROP_HUE;
|
||||||
|
else if (w == ui->sldCamSharpness) return CAP_PROP_SHARPNESS;
|
||||||
|
else return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabCamera::doSnapshot()
|
||||||
|
{
|
||||||
|
images->add(source->getSnapshot());
|
||||||
|
}
|