Added Neural network code
@@ -1,9 +1,11 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.12
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AdvancedVision", "AdvancedVision.vcxproj", "{D07114EF-4EC2-45EE-944D-5A269C142C0F}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AdvancedVision", "AdvancedVision.vcxproj", "{E2412F90-006E-4A20-B924-F7D795DB8241}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NeuralDetector", "..\NeuralDetector\NeuralDetector.vcxproj", "{E74AD02B-6B3F-431B-8D7E-DBFED7E6B671}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -13,19 +15,24 @@ Global
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D07114EF-4EC2-45EE-944D-5A269C142C0F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D07114EF-4EC2-45EE-944D-5A269C142C0F}.Debug|x64.Build.0 = Debug|x64
|
||||
{D07114EF-4EC2-45EE-944D-5A269C142C0F}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{D07114EF-4EC2-45EE-944D-5A269C142C0F}.Debug|x86.Build.0 = Debug|Win32
|
||||
{D07114EF-4EC2-45EE-944D-5A269C142C0F}.Release|x64.ActiveCfg = Release|x64
|
||||
{D07114EF-4EC2-45EE-944D-5A269C142C0F}.Release|x64.Build.0 = Release|x64
|
||||
{D07114EF-4EC2-45EE-944D-5A269C142C0F}.Release|x86.ActiveCfg = Release|Win32
|
||||
{D07114EF-4EC2-45EE-944D-5A269C142C0F}.Release|x86.Build.0 = Release|Win32
|
||||
{E2412F90-006E-4A20-B924-F7D795DB8241}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E2412F90-006E-4A20-B924-F7D795DB8241}.Debug|x64.Build.0 = Debug|x64
|
||||
{E2412F90-006E-4A20-B924-F7D795DB8241}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{E2412F90-006E-4A20-B924-F7D795DB8241}.Debug|x86.Build.0 = Debug|Win32
|
||||
{E2412F90-006E-4A20-B924-F7D795DB8241}.Release|x64.ActiveCfg = Release|x64
|
||||
{E2412F90-006E-4A20-B924-F7D795DB8241}.Release|x64.Build.0 = Release|x64
|
||||
{E2412F90-006E-4A20-B924-F7D795DB8241}.Release|x86.ActiveCfg = Release|Win32
|
||||
{E2412F90-006E-4A20-B924-F7D795DB8241}.Release|x86.Build.0 = Release|Win32
|
||||
{E74AD02B-6B3F-431B-8D7E-DBFED7E6B671}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E74AD02B-6B3F-431B-8D7E-DBFED7E6B671}.Debug|x64.Build.0 = Debug|x64
|
||||
{E74AD02B-6B3F-431B-8D7E-DBFED7E6B671}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{E74AD02B-6B3F-431B-8D7E-DBFED7E6B671}.Debug|x86.Build.0 = Debug|Win32
|
||||
{E74AD02B-6B3F-431B-8D7E-DBFED7E6B671}.Release|x64.ActiveCfg = Release|x64
|
||||
{E74AD02B-6B3F-431B-8D7E-DBFED7E6B671}.Release|x64.Build.0 = Release|x64
|
||||
{E74AD02B-6B3F-431B-8D7E-DBFED7E6B671}.Release|x86.ActiveCfg = Release|Win32
|
||||
{E74AD02B-6B3F-431B-8D7E-DBFED7E6B671}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {718B94D4-63F0-4DFC-84A7-C7CA7AF5ACA9}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
@@ -19,36 +19,35 @@
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{d07114ef-4ec2-45ee-944d-5a269c142c0f}</ProjectGuid>
|
||||
<ProjectGuid>{E2412F90-006E-4A20-B924-F7D795DB8241}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>AdvancedVision</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@@ -84,11 +83,10 @@
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>D:\Code\OpenCV\install\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>D:\Code\OpenCV\install\include;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
</ClCompile>
|
||||
@@ -101,11 +99,10 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>D:\Code\OpenCV\install\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>D:\Code\OpenCV\install\include;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
</ClCompile>
|
||||
@@ -118,58 +115,65 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>D:\Code\OpenCV\install\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>D:\Code\OpenCV\install\include;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>opencv_world330.lib;opencv_world330d.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>D:\Code\OpenCV\install\x64\vc14\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>opencv_world330.lib;opencv_world330d.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>D:\Code\OpenCV\install\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>D:\Code\OpenCV\install\include;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>opencv_world330.lib;opencv_world330d.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>D:\Code\OpenCV\install\x64\vc14\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>opencv_world330.lib;opencv_world330d.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="allContoursTestprogramma.cpp" />
|
||||
<ClCompile Include="avansvisionlib.cpp" />
|
||||
<ClCompile Include="avansvisionlib20.cpp" />
|
||||
<ClCompile Include="BoundingBox.cpp" />
|
||||
<ClCompile Include="BPN.cpp" />
|
||||
<ClCompile Include="Calibrate.cpp" />
|
||||
<ClCompile Include="FloodFill.cpp" />
|
||||
<ClCompile Include="Main.cpp" />
|
||||
<ClCompile Include="MooreBoundaryTrackingAlgorithm.cpp" />
|
||||
<ClCompile Include="Source.cpp" />
|
||||
<ClCompile Include="NeuralNetwork.cpp" />
|
||||
<ClCompile Include="perceptron.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="avansvisionlib.h" />
|
||||
<ClInclude Include="allContoursTestprogramma.h" />
|
||||
<ClInclude Include="avansvisionlib20.h" />
|
||||
<ClInclude Include="BoundingBox.h" />
|
||||
<ClInclude Include="BPN.h" />
|
||||
<ClInclude Include="Calibrate.h" />
|
||||
<ClInclude Include="FloodFill.h" />
|
||||
<ClInclude Include="Main.h" />
|
||||
<ClInclude Include="MooreBoundaryTrackingAlgorithm.h" />
|
||||
<ClInclude Include="NeuralNetwork.h" />
|
||||
<ClInclude Include="perceptron.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
||||
@@ -13,29 +13,74 @@
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\Features">
|
||||
<UniqueIdentifier>{95b73545-78c3-479d-878f-c51a63f4f3bf}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Features">
|
||||
<UniqueIdentifier>{70ee2ada-2a6b-4960-8b07-1bbdb13f0f8a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Source.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="allContoursTestprogramma.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="avansvisionlib.cpp">
|
||||
<ClCompile Include="avansvisionlib20.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BPN.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="perceptron.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NeuralNetwork.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BoundingBox.cpp">
|
||||
<Filter>Source Files\Features</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FloodFill.cpp">
|
||||
<Filter>Source Files\Features</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MooreBoundaryTrackingAlgorithm.cpp">
|
||||
<Filter>Source Files\Features</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Calibrate.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="avansvisionlib.h">
|
||||
<ClInclude Include="avansvisionlib20.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Main.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="perceptron.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="allContoursTestprogramma.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BPN.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NeuralNetwork.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BoundingBox.h">
|
||||
<Filter>Header Files\Features</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FloodFill.h">
|
||||
<Filter>Header Files\Features</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MooreBoundaryTrackingAlgorithm.h">
|
||||
<Filter>Header Files\Features</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Calibrate.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
// Demo: Training of a Neural Network / Back-Propagation algorithm
|
||||
// Jan Oostindie, Avans Hogeschool, dd 6-12-2016
|
||||
// email: jac.oostindie@avans.nl
|
||||
|
||||
#include "BPN.h"
|
||||
|
||||
|
||||
// Maximale fout die toegestaan wordt in de output voor de training input
|
||||
const double MAX_OUTPUT_ERROR = 1E-10;
|
||||
|
||||
// maximaal aantal runs dat uitgevoerd wordt bij het trainen
|
||||
const int MAXRUNS = 10000;
|
||||
|
||||
int run(int argc, char** argv)
|
||||
{
|
||||
// IT, OT: input trainingset, output trainingset
|
||||
Mat ITset, OTset;
|
||||
|
||||
// V0, W0 : weightfactor matrices
|
||||
// dV0, dW0 : weightfactor correction matrices
|
||||
Mat V0, W0, dW0, dV0;
|
||||
|
||||
// default number of hiddenNeurons. The definite number is user input
|
||||
// inputNeurons and outputNeurons are implicitly determined via
|
||||
// the trainingset, i.e.: inputNeurons = ITset.cols ; outputNeurons = OTset.cols;
|
||||
int hiddenNeurons = 2;
|
||||
|
||||
cout << endl << "Load testtrainingset..." << endl << endl;
|
||||
//loadTrainingSet1(ITset, OTset);
|
||||
loadBinaryTrainingSet1(ITset, OTset);
|
||||
|
||||
cout << "Training Input " << endl << endl;
|
||||
cout << ITset << endl << endl;
|
||||
cout << "Training Output " << endl << endl;
|
||||
cout << OTset << endl << endl;
|
||||
|
||||
cout << " ===> BPN format: " << endl <<
|
||||
"BPN Inputlayer = " << ITset.cols << " neurons" << endl <<
|
||||
"BPN Outputlayer = " << OTset.cols << " neurons" << endl << endl;
|
||||
cout << "Please choose a number of hidden neurons: ";
|
||||
cin >> hiddenNeurons;
|
||||
cout << "Thank you!" << endl << endl << endl;
|
||||
|
||||
cout << "Initialize BPN ..." << endl;
|
||||
initializeBPN(ITset.cols, hiddenNeurons, OTset.cols, V0, dV0, W0, dW0);
|
||||
//testBPN(ITset, OTset, V0, dV0, W0, dW0);
|
||||
|
||||
cout << "initial values of weight matrices V0 and W0" << endl;
|
||||
cout << "*******************************************" << endl;
|
||||
cout << V0 << endl << endl << W0 << endl << endl;
|
||||
cout << "Press ENTER => ";
|
||||
string dummy;
|
||||
getline(cin, dummy);
|
||||
getline(cin, dummy);
|
||||
|
||||
// IT: current training input of the inputlayer
|
||||
// OT: desired training output of the BPN
|
||||
// OH: output of the hiddenlayer
|
||||
// OO: output of the outputlayer
|
||||
Mat IT, OT, OH, OO;
|
||||
|
||||
// outputError0: error on output for the current input and weighfactors V0, W0
|
||||
// outputError1: error on output for the current input and new calculated
|
||||
// weighfactors, i.e. V1, W1
|
||||
double outputError0, outputError1, sumSqrDiffError = MAX_OUTPUT_ERROR + 1;
|
||||
Mat V1, W1;
|
||||
|
||||
int runs = 0;
|
||||
while ((sumSqrDiffError > MAX_OUTPUT_ERROR) && (runs < MAXRUNS)) {
|
||||
|
||||
sumSqrDiffError = 0;
|
||||
|
||||
for (int inputSetRowNr = 0; inputSetRowNr < ITset.rows; inputSetRowNr++) {
|
||||
|
||||
IT = transpose(getRow(ITset, inputSetRowNr));
|
||||
|
||||
OT = transpose(getRow(OTset, inputSetRowNr));
|
||||
|
||||
calculateOutputHiddenLayer(IT, V0, OH);
|
||||
|
||||
calculateOutputBPN(OH, W0, OO);
|
||||
|
||||
adaptVW(OT, OO, OH, IT, W0, dW0, V0, dV0, W1, V1);
|
||||
|
||||
calculateOutputBPNError(OO, OT, outputError0);
|
||||
|
||||
calculateOutputBPNError(BPN(IT, V1, W1), OT, outputError1);
|
||||
|
||||
sumSqrDiffError += (outputError1 - outputError0) * (outputError1 - outputError0);
|
||||
|
||||
V0 = V1;
|
||||
W0 = W1;
|
||||
}
|
||||
cout << "sumSqrDiffError = " << sumSqrDiffError << endl;
|
||||
runs++;
|
||||
}
|
||||
|
||||
cout << "BPN Training is ready!" << endl << endl;
|
||||
cout << "Runs = " << runs << endl << endl;
|
||||
|
||||
Mat inputVectorTrainingSet, outputVectorTrainingSet, outputVectorBPN;
|
||||
|
||||
// druk voor elke input vector uit de trainingset de output vector uit trainingset af
|
||||
// tezamen met de output vector die het getrainde BPN (zie V0, W0) genereerd bij de
|
||||
// betreffende input vector.
|
||||
cout << setw(16) << " " << "Training Input" << setw(12) << "|" << " Expected Output "
|
||||
<< setw(1) << "|" << " Output BPN " << setw(6) << "|" << endl << endl;
|
||||
for (int row = 0; row < ITset.rows; row++) {
|
||||
|
||||
// haal volgende inputvector op uit de training set
|
||||
inputVectorTrainingSet = transpose(getRow(ITset, row));
|
||||
|
||||
// druk de inputvector af in een regel afgesloten met |
|
||||
for (int r = 0; r < inputVectorTrainingSet.rows; r++)
|
||||
cout << setw(8) << getEntry(inputVectorTrainingSet, r, 0);
|
||||
cout << setw(2) << "|";
|
||||
|
||||
// haal bijbehorende outputvector op uit de training set
|
||||
outputVectorTrainingSet = transpose(getRow(OTset, row));
|
||||
|
||||
// druk de outputvector van de training set af in dezelfde regel afgesloten met |
|
||||
for (int r = 0; r < outputVectorTrainingSet.rows; r++)
|
||||
cout << setw(8) << round(getEntry(outputVectorTrainingSet, r, 0));
|
||||
cout << setw(2) << "|";
|
||||
|
||||
// bepaal de outputvector die het getrainde BPN oplevert
|
||||
// bij de inputvector uit de trainingset
|
||||
outputVectorBPN = BPN(inputVectorTrainingSet, V0, W0);
|
||||
|
||||
// druk de output vector van het BPN af in dezelfde regel afgesloten met |
|
||||
for (int r = 0; r < outputVectorBPN.rows; r++)
|
||||
cout << setw(8) << round(getEntry(outputVectorBPN, r, 0));
|
||||
cout << setw(2) << "|";
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
cout << endl << endl << "Press ENTER for exit";
|
||||
getline(cin, dummy);
|
||||
getline(cin, dummy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv/cv.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include "avansvisionlib20.h" // versie 2.0 (!)
|
||||
|
||||
int run(int argc, char ** argv);
|
||||
@@ -80,6 +80,7 @@ int BoundingBox::split(const vector<vector<Point>> & contours, const Mat &image,
|
||||
Rect r = Rect(center.x - (largest.width / 2), center.y - (largest.height / 2),largest.width, largest.height);
|
||||
Mat roi(image, r);
|
||||
|
||||
//imshow(name, roi);
|
||||
imwrite("output/" + name + "_" + to_string(nr) + ".bmp", roi);
|
||||
|
||||
nr++;
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
// Demonstratie: camera callibratie met schaakbord patroon
|
||||
// saven van de callibratie data in een yml-file
|
||||
// Jan Oostindie, dd 16-3-2015
|
||||
// bron: www.aishack.in
|
||||
|
||||
#include "Calibrate.h"
|
||||
|
||||
int calibrateCamera() {
|
||||
// The number of boards you want to capture, the number of internal corners horizontally
|
||||
// and the number of internal corners vertically (That's just how the algorithm works).
|
||||
int numBoards = 10;
|
||||
int numCornersHor = 9;
|
||||
int numCornersVer = 6;
|
||||
|
||||
// We also create some additional variables that we'll be using later on.
|
||||
int numSquares = numCornersHor * numCornersVer;
|
||||
Size board_sz = Size(numCornersHor, numCornersVer);
|
||||
|
||||
// We want live feed for our calibration!
|
||||
VideoCapture capture(1);
|
||||
|
||||
if (!capture.isOpened()) { //check if video device has been initialised
|
||||
cout << "cannot open camera";
|
||||
}
|
||||
|
||||
// - object_points is the physical position of the corners (in 3D space).
|
||||
// This has to be measured by us.
|
||||
// - image_points is the location of the corners in the image (in 2 dimensions).
|
||||
// - Once the program has actual physical locations and locations on the image, it can calculate
|
||||
// the relation between the two. Because we'll use a chessboard, these points have a definite
|
||||
// relations between them (they lie on straight lines and on squares).
|
||||
// - So the "expected" - "actual" relation can be used to correct the distortions in the image.
|
||||
vector<vector<Point3f>> object_points;
|
||||
vector<vector<Point2f>> image_points;
|
||||
|
||||
// Next, we create a list of corners. This will temporarily hold the current snapshot's chessboard corners.
|
||||
// keep track of the number of successfully captured chessboards
|
||||
vector<Point2f> corners;
|
||||
int successes = 0;
|
||||
|
||||
// - Create a list of coordinates (0,0,0), (0,1,0), (0,2,0)...(1,4,0)... so on.
|
||||
// Each corresponds to a particular vertex.
|
||||
// - You're essentially setting up the units of calibration.
|
||||
// Suppose the squares in your chessboards were 30 mm in size and you supplied these
|
||||
// coordinates as (0,0,0), (0, 30, 0), etc, you'd get all unknowns in millimeters.
|
||||
vector<Point3f> obj;
|
||||
for (int j = 0; j < numSquares; j++)
|
||||
obj.push_back(Point3f(j / numCornersHor, j%numCornersHor, 0.0f));
|
||||
|
||||
// Then we create two images and get the first snapshot from the camera:
|
||||
Mat image;
|
||||
Mat gray_image;
|
||||
capture >> image;
|
||||
|
||||
// As long as the number of successful entries has been less than the number required,
|
||||
// we keep looping:
|
||||
while (successes < numBoards)
|
||||
{
|
||||
// convert to gray scale
|
||||
cvtColor(image, gray_image, CV_BGR2GRAY);
|
||||
|
||||
// And we're here. The key functions:
|
||||
// findChessboardCorners tries to find a chessboard in the image.
|
||||
// IF found THEN the rough corners are returned.
|
||||
bool found = findChessboardCorners(image, board_sz, corners, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
|
||||
if (found)
|
||||
{
|
||||
// cornerSubPix refines the found corners.
|
||||
// De rough corners returned by findChessbooardCorners and the gray_image are input,
|
||||
// the refined corners are output.
|
||||
cornerSubPix(gray_image, corners, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
|
||||
|
||||
// draw the refined corners on the image i.e. chessboard.
|
||||
drawChessboardCorners(gray_image, board_sz, corners, found);
|
||||
}
|
||||
|
||||
// show results
|
||||
imshow("orginal", image);
|
||||
imshow("gray image", gray_image);
|
||||
|
||||
capture >> image;
|
||||
|
||||
int key = waitKey(1);
|
||||
|
||||
// Leave the program by pressing ESC-key
|
||||
if (key == 27) return 0;
|
||||
|
||||
// spacebar and chessboard found ==> save the snap
|
||||
if (key == ' ' && found != 0)
|
||||
{
|
||||
image_points.push_back(corners);
|
||||
object_points.push_back(obj);
|
||||
|
||||
printf("Snap stored!");
|
||||
|
||||
successes++;
|
||||
|
||||
if (successes >= numBoards)
|
||||
break;
|
||||
}
|
||||
} // while
|
||||
|
||||
// Next, we get ready to do the calibration. We declare variables that will hold the unknowns:
|
||||
// Matrix intrinsic contains cx,cy,fx,fy
|
||||
// Matrix disCoeffs contains the distortion coefficients: 3 numbers radial distortion and 2 numbers tangential distortion
|
||||
Mat intrinsic = Mat(3, 3, CV_32FC1);
|
||||
Mat distCoeffs;
|
||||
vector<Mat> rvecs;
|
||||
vector<Mat> tvecs;
|
||||
|
||||
// We modify the intrinsic matrix with whatever we know.
|
||||
// The camera's aspect ratio is 1 (that's usually the case...
|
||||
// i.e. fx = fy = f. If not, change it as required.
|
||||
// Elements (0,0) and (1,1) are the focal lengths along the X and Y axis.
|
||||
intrinsic.ptr<float>(0)[0] = 1;
|
||||
intrinsic.ptr<float>(1)[1] = 1;
|
||||
|
||||
// Determine the intrinsic matrix, distortion coefficients and the rotation+translation vectors.
|
||||
// Note: The calibrateCamera function converts all matrices into 64F format even if you
|
||||
// initialize it to 32F.
|
||||
calibrateCamera(object_points, image_points, image.size(), intrinsic, distCoeffs, rvecs, tvecs);
|
||||
|
||||
cout << endl << endl << "intrinsic = " << intrinsic << endl << endl;
|
||||
cout << "distCoeffs = " << distCoeffs << endl;
|
||||
|
||||
/***** saven van de callibratie data *****/
|
||||
|
||||
// YML-file aanmaken
|
||||
FileStorage fs("ueyecallib.yml", FileStorage::WRITE);
|
||||
|
||||
// wegschrijven van callibratie data naar de YML-file
|
||||
fs << "intrinsic" << intrinsic << "distCoeffs" << distCoeffs;
|
||||
|
||||
// de file afsluiten
|
||||
fs.release();
|
||||
|
||||
Mat imageUndistorted;
|
||||
Mat cimage;
|
||||
bool finished = false;
|
||||
|
||||
while (!finished)
|
||||
{
|
||||
capture >> cimage;
|
||||
undistort(cimage, imageUndistorted, intrinsic, distCoeffs);
|
||||
|
||||
imshow("undistorted", imageUndistorted);
|
||||
|
||||
if (waitKey(100) >= 0)
|
||||
{
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
|
||||
destroyAllWindows();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void setCalibrationAndTakePhotos() {
|
||||
//lees callibratiedata uit
|
||||
// YML-file met callibratie data openen
|
||||
FileStorage fs("ueyecallib.yml", FileStorage::READ);
|
||||
|
||||
// callibratie data ophalen
|
||||
Mat intrinsic, distCoeffs;
|
||||
fs["intrinsic"] >> intrinsic;
|
||||
fs["distCoeffs"] >> distCoeffs;
|
||||
|
||||
// callibratie matrices tonen op het scherm
|
||||
cout << "intrinsic matrix: " << intrinsic << endl;
|
||||
cout << "distortion coeffs: " << distCoeffs << endl;
|
||||
|
||||
// sluiten van de YML-file
|
||||
fs.release();
|
||||
|
||||
/***** callibratie data gebruiken *****/
|
||||
|
||||
// Now that we have the distortion coefficients, we can undistort the images.
|
||||
// Here's a small loop that will do this:
|
||||
Mat imageUndistorted;
|
||||
|
||||
VideoCapture capture = VideoCapture(1);
|
||||
Mat image;
|
||||
bool finished = false;
|
||||
int run = 1;
|
||||
|
||||
//get filename
|
||||
std::string filename;
|
||||
std::cout << "Enter filename: ";
|
||||
std::getline(std::cin, filename);
|
||||
|
||||
while (!finished)
|
||||
{
|
||||
|
||||
Mat imageUndistorted;
|
||||
Mat cimage;
|
||||
bool done = false;
|
||||
while (!done)
|
||||
{
|
||||
capture >> cimage;
|
||||
undistort(cimage, imageUndistorted, intrinsic, distCoeffs);
|
||||
|
||||
imshow("undistorted", imageUndistorted);
|
||||
|
||||
if (waitKey(100) >= 0)
|
||||
{
|
||||
done = true;
|
||||
destroyWindow("undistorted");
|
||||
}
|
||||
}
|
||||
|
||||
capture >> image;
|
||||
undistort(image, imageUndistorted, intrinsic, distCoeffs);
|
||||
|
||||
// De afbeelding converteren naar een grijswaarde afbeelding
|
||||
Mat gray_image;
|
||||
cvtColor(imageUndistorted, gray_image, CV_BGR2GRAY);
|
||||
|
||||
// Gray image thresholden
|
||||
Mat binaryImage;
|
||||
threshold(gray_image, binaryImage, 165, 1, CV_THRESH_BINARY_INV);
|
||||
|
||||
// Alvorens bewerkingen uit te voeren op het beeld converteren we deze
|
||||
// naar een Mat object met grotere diepte (depth), t.w. 16 bits signed
|
||||
Mat binary16S;
|
||||
binaryImage.convertTo(binary16S, CV_16S);
|
||||
|
||||
// haal de contouren uit het binary image
|
||||
vector<vector<Point>> contours;
|
||||
int aantal = allContours(binary16S, contours);
|
||||
|
||||
cout << "Found " << aantal << " contours" << endl;
|
||||
|
||||
// Creeer een witte image
|
||||
IplImage* iplimage = cvCreateImage(cvSize(binary16S.cols, binary16S.rows), IPL_DEPTH_8U, 3);
|
||||
Mat contourImage = cvarrToMat(iplimage);
|
||||
contourImage = Scalar(255, 255, 255);
|
||||
|
||||
// teken de contouren op de witte image
|
||||
drawContours(contourImage, contours, -1, CV_RGB(255, 0, 0));
|
||||
|
||||
imshow("Contour", contourImage);
|
||||
|
||||
waitKey(0);
|
||||
|
||||
//Split images
|
||||
FloodFill::largest(contours, image, filename);
|
||||
|
||||
cout << "Finished writing object to disk" << endl;
|
||||
|
||||
waitKey(0);
|
||||
|
||||
destroyWindow("Contour");
|
||||
|
||||
run++;
|
||||
}
|
||||
}
|
||||
|
||||
int startCalibrate()
|
||||
{
|
||||
//calibrateCamera();
|
||||
|
||||
setCalibrationAndTakePhotos();
|
||||
cout << "Program finished" << endl;
|
||||
waitKey(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2\imgproc\imgproc.hpp>
|
||||
#include <opencv2/calib3d/calib3d.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "avansvisionlib20.h"
|
||||
#include "MooreBoundaryTrackingAlgorithm.h"
|
||||
#include "BoundingBox.h"
|
||||
#include "FloodFill.h"
|
||||
|
||||
|
||||
int calibrateCamera();
|
||||
|
||||
void setCalibrationAndTakePhotos();
|
||||
|
||||
int startCalibrate();
|
||||
@@ -22,6 +22,9 @@ int FloodFill::enclosedPixels(const vector<Point>& contourVec, vector<Point> & r
|
||||
regionPixels.push_back(p);
|
||||
st.push(p);
|
||||
|
||||
double runs = 0;
|
||||
double maxruns = 4000000;
|
||||
|
||||
while (st.size() > 0)
|
||||
{
|
||||
Point p = st.top();
|
||||
@@ -45,6 +48,14 @@ int FloodFill::enclosedPixels(const vector<Point>& contourVec, vector<Point> & r
|
||||
st.push(check);
|
||||
}
|
||||
}
|
||||
|
||||
runs++;
|
||||
|
||||
if (runs > maxruns)
|
||||
{
|
||||
cout << "Reached max number of runs" << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//floodfill(contourVec, regionPixels, p);
|
||||
@@ -202,11 +213,73 @@ int FloodFill::split(const vector<vector<Point>> & contours, const Mat &image, s
|
||||
resultImage.at<Vec3b>(Point(p.x - topx, p.y - topy)) = image.at<Vec3b>(p);
|
||||
}
|
||||
|
||||
imshow("Test", resultImage);
|
||||
waitKey(0);
|
||||
|
||||
//imshow(name, resultImage);
|
||||
imwrite("output/" + name + "_" + to_string(i) + ".bmp", resultImage);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int FloodFill::largest(const vector<vector<Point>> & contours, const Mat &image, string filename)
|
||||
{
|
||||
//Create filenames
|
||||
std::string base_filename = filename.substr(filename.find_last_of("/\\") + 1);
|
||||
std::string::size_type const p(base_filename.find_last_of('.'));
|
||||
std::string name = base_filename.substr(0, p);
|
||||
|
||||
vector<vector<Point>> bounds;
|
||||
BoundingBox::allBoundingBoxes(contours, bounds);
|
||||
|
||||
//Find largest bounding box
|
||||
Size largest = Size(0, 0);
|
||||
int total = 0;
|
||||
int bin = -1;
|
||||
for (int i = 0; i < bounds.size(); i++)
|
||||
{
|
||||
vector<Point> box = bounds[i];
|
||||
|
||||
int height = abs(box[2].y - box[1].y);
|
||||
int width = abs(box[1].x - box[0].x);
|
||||
int size = height + width;
|
||||
|
||||
if (height > largest.height)
|
||||
largest.height = height;
|
||||
if (width > largest.width)
|
||||
largest.width = width;
|
||||
|
||||
if (size > total)
|
||||
{
|
||||
total = size;
|
||||
bin = i;
|
||||
}
|
||||
}
|
||||
|
||||
vector<Point> region;
|
||||
enclosedPixels(contours[bin], region);
|
||||
|
||||
// Creeer een witte image
|
||||
IplImage* iplimage = cvCreateImage(cvSize(largest.width, largest.height), IPL_DEPTH_8U, 3);
|
||||
Mat resultImage = cvarrToMat(iplimage);
|
||||
resultImage = Scalar(255, 255, 255);
|
||||
|
||||
Point center = Point((bounds[bin][0].x + bounds[bin][2].x) / 2, (bounds[bin][0].y + bounds[bin][2].y) / 2);
|
||||
int topx = center.x - (largest.width / 2);
|
||||
int topy = center.y - (largest.height / 2);
|
||||
|
||||
//Kopieren van pixels
|
||||
for (Point p : region)
|
||||
{
|
||||
resultImage.at<Vec3b>(Point(p.x - topx, p.y - topy)) = image.at<Vec3b>(p);
|
||||
}
|
||||
for (Point p : contours[bin])
|
||||
{
|
||||
resultImage.at<Vec3b>(Point(p.x - topx, p.y - topy)) = image.at<Vec3b>(p);
|
||||
}
|
||||
|
||||
|
||||
//imshow(name, resultImage);
|
||||
imwrite("output/" + name + "_" + to_string(bin) + ".bmp", resultImage);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -20,5 +20,6 @@ public:
|
||||
static Point findStartPoint(vector<Point> vec);
|
||||
static int floodfill(const vector<Point> & contourVec, vector<Point> & regionPixels, Point &p);
|
||||
static int split(const vector<vector<Point>> & contours, const Mat &image, string filename);
|
||||
static int largest(const vector<vector<Point>> & contours, const Mat &image, string filename);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#include "Main.h"
|
||||
#include "avansvisionlib20.h"
|
||||
#include "NeuralNetwork.h"
|
||||
#include "Calibrate.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
startCalibrate();
|
||||
|
||||
Mat in, out;
|
||||
|
||||
// input of trainingset (without bias)
|
||||
// remark: nummber of columns == number of inputneurons of the BPN
|
||||
in = (Mat_<double>(8, 2) <<
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 1,
|
||||
0, 1,
|
||||
1, 0,
|
||||
1, 0,
|
||||
1, 1,
|
||||
1, 1);
|
||||
|
||||
// output of trainingset
|
||||
// remark: nummber of columns == number of outputneurons of the BPN
|
||||
out = (Mat_<double>(8, 1) <<
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0);
|
||||
|
||||
run(in, out);
|
||||
|
||||
cout << "Press enter to exit" << endl;
|
||||
cin.ignore();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2\imgproc\imgproc.hpp>
|
||||
#include <opencv/cv.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
int main(int argc, char * argv[]);
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "MooreBoundaryTrackingAlgorithm.h"
|
||||
#include "avansvisionlib.h"
|
||||
#include "avansvisionlib20.h"
|
||||
|
||||
//direction values
|
||||
//starting at position 0. Definition of relative positions:
|
||||
@@ -49,10 +49,11 @@ int allContours(Mat binaryImage, vector<vector<Point>>& contourVecVec)
|
||||
|
||||
} while (b0 != firstb0 && b1 != firstb1);
|
||||
|
||||
cout << "Klaar met het vinden van contouren" << endl;
|
||||
|
||||
if(contourVec.size() > 4)
|
||||
if (contourVec.size() > 4)
|
||||
{
|
||||
cout << "Klaar met het vinden van contouren" << endl;
|
||||
contourVecVec.push_back(contourVec);
|
||||
}
|
||||
}
|
||||
|
||||
return numberOfBlobs; //number of objects
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
// Demo: Training of a Neural Network / Back-Propagation algorithm
|
||||
// Jan Oostindie, Avans Hogeschool, dd 6-12-2016
|
||||
// email: jac.oostindie@avans.nl
|
||||
|
||||
#include "NeuralNetwork.h"
|
||||
|
||||
// Maximale fout die toegestaan wordt in de output voor de training input
|
||||
const double MAX_OUTPUT_ERROR = 1E-10;
|
||||
|
||||
// maximaal aantal runs dat uitgevoerd wordt bij het trainen
|
||||
const int MAXRUNS = 10000;
|
||||
|
||||
Mat run(Mat ITset, Mat OTset)
|
||||
{
|
||||
// V0, W0 : weightfactor matrices
|
||||
// dV0, dW0 : weightfactor correction matrices
|
||||
Mat V0, W0, dW0, dV0;
|
||||
|
||||
// default number of hiddenNeurons. The definite number is user input
|
||||
// inputNeurons and outputNeurons are implicitly determined via
|
||||
// the trainingset, i.e.: inputNeurons = ITset.cols ; outputNeurons = OTset.cols;
|
||||
int hiddenNeurons = 5;
|
||||
|
||||
//loadTrainingSet1(ITset, OTset);
|
||||
loadBinaryTrainingSet1(ITset, OTset);
|
||||
initializeBPN(ITset.cols, hiddenNeurons, OTset.cols, V0, dV0, W0, dW0);
|
||||
//testBPN(ITset, OTset, V0, dV0, W0, dW0);
|
||||
|
||||
|
||||
// IT: current training input of the inputlayer
|
||||
// OT: desired training output of the BPN
|
||||
// OH: output of the hiddenlayer
|
||||
// OO: output of the outputlayer
|
||||
Mat IT, OT, OH, OO;
|
||||
|
||||
// outputError0: error on output for the current input and weighfactors V0, W0
|
||||
// outputError1: error on output for the current input and new calculated
|
||||
// weighfactors, i.e. V1, W1
|
||||
double outputError0, outputError1, sumSqrDiffError = MAX_OUTPUT_ERROR + 1;
|
||||
Mat V1, W1;
|
||||
|
||||
cout << "Starting neural training..." << endl;
|
||||
|
||||
int runs = 0;
|
||||
while ((sumSqrDiffError > MAX_OUTPUT_ERROR) && (runs < MAXRUNS)) {
|
||||
|
||||
sumSqrDiffError = 0;
|
||||
|
||||
for (int inputSetRowNr = 0; inputSetRowNr < ITset.rows; inputSetRowNr++) {
|
||||
|
||||
IT = transpose(getRow(ITset, inputSetRowNr));
|
||||
|
||||
OT = transpose(getRow(OTset, inputSetRowNr));
|
||||
|
||||
calculateOutputHiddenLayer(IT, V0, OH);
|
||||
|
||||
calculateOutputBPN(OH, W0, OO);
|
||||
|
||||
adaptVW(OT, OO, OH, IT, W0, dW0, V0, dV0, W1, V1);
|
||||
|
||||
calculateOutputBPNError(OO, OT, outputError0);
|
||||
|
||||
calculateOutputBPNError(BPN(IT, V1, W1), OT, outputError1);
|
||||
|
||||
sumSqrDiffError += (outputError1 - outputError0) * (outputError1 - outputError0);
|
||||
|
||||
V0 = V1;
|
||||
W0 = W1;
|
||||
}
|
||||
runs++;
|
||||
}
|
||||
|
||||
cout << "Training complete in " << runs << " runs" << endl;
|
||||
|
||||
Mat inputVectorTrainingSet, outputVectorTrainingSet, outputVectorBPN;
|
||||
|
||||
// druk voor elke input vector uit de trainingset de output vector uit trainingset af
|
||||
// tezamen met de output vector die het getrainde BPN (zie V0, W0) genereerd bij de
|
||||
// betreffende input vector.
|
||||
for (int row = 0; row < ITset.rows; row++) {
|
||||
|
||||
// haal volgende inputvector op uit de training set
|
||||
inputVectorTrainingSet = transpose(getRow(ITset, row));
|
||||
|
||||
// haal bijbehorende outputvector op uit de training set
|
||||
outputVectorTrainingSet = transpose(getRow(OTset, row));
|
||||
|
||||
// bepaal de outputvector die het getrainde BPN oplevert
|
||||
// bij de inputvector uit de trainingset
|
||||
outputVectorBPN = BPN(inputVectorTrainingSet, V0, W0);
|
||||
|
||||
// druk de output vector van het BPN af in dezelfde regel afgesloten met |
|
||||
for (int r = 0; r < outputVectorBPN.rows; r++)
|
||||
cout << setw(8) << round(getEntry(outputVectorBPN, r, 0));
|
||||
cout << setw(2) << "|";
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
return outputVectorBPN;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv/cv.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include "avansvisionlib20.h" // versie 2.0 (!)
|
||||
|
||||
Mat run(Mat in, Mat out);
|
||||
@@ -1,33 +1,79 @@
|
||||
#include <opencv2/objdetect.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <cmath>
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv/cv.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
int test1(int argc, char** argv);
|
||||
int test2();
|
||||
int test3();
|
||||
|
||||
int main2(int argc, char** argv)
|
||||
{
|
||||
Mat image = imread("input/Week2/basisfiguren.jpg", CV_LOAD_IMAGE_COLOR);
|
||||
if (!image.data)
|
||||
return test3();
|
||||
}
|
||||
|
||||
int test1(int argc, char** argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
cout << " Usage: display_image ImageToLoadAndDisplay" << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Mat image;
|
||||
image = imread(argv[1], IMREAD_COLOR); // Read the file
|
||||
|
||||
if (!image.data) // Check for invalid input
|
||||
{
|
||||
cout << "Could not open or find the image" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Mat gray_image;
|
||||
cvtColor(image, gray_image, CV_BGR2GRAY);
|
||||
|
||||
imshow("Source", image);
|
||||
imshow("Gray image", gray_image);
|
||||
|
||||
waitKey(0);
|
||||
namedWindow("Display window", WINDOW_AUTOSIZE); // Create a window for display.
|
||||
imshow("Display window", image); // Show our image inside it.
|
||||
|
||||
waitKey(0); // Wait for a keystroke in the window
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int test2()
|
||||
{
|
||||
int c;
|
||||
IplImage* color_img;
|
||||
CvCapture* cv_cap = cvCaptureFromCAM(0);
|
||||
cvNamedWindow("Video", 0); // create window
|
||||
for (;;) {
|
||||
color_img = cvQueryFrame(cv_cap); // get frame
|
||||
if (color_img != 0)
|
||||
cvShowImage("Video", color_img); // show frame
|
||||
c = cvWaitKey(10); // wait 10 ms or for key stroke
|
||||
if (c == 27)
|
||||
break; // if ESC, break and quit
|
||||
}
|
||||
/* clean up */
|
||||
cvReleaseCapture(&cv_cap);
|
||||
cvDestroyWindow("Video");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test3()
|
||||
{
|
||||
VideoCapture stream1(0); //0 is the id of video device.0 if you have only one camera.
|
||||
|
||||
if (!stream1.isOpened()) { //check if video device has been initialised
|
||||
cout << "cannot open camera";
|
||||
}
|
||||
|
||||
//unconditional loop
|
||||
while (true) {
|
||||
Mat cameraFrame;
|
||||
stream1.read(cameraFrame);
|
||||
imshow("cam", cameraFrame);
|
||||
if (waitKey(30) >= 0)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,16 +11,17 @@
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "avansvisionlib.h"
|
||||
#include "avansvisionlib20.h"
|
||||
#include "MooreBoundaryTrackingAlgorithm.h"
|
||||
#include "BoundingBox.h"
|
||||
#include "FloodFill.h"
|
||||
#include "allContoursTestprogramma.h"
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main2(int argc, char *argv[])
|
||||
{
|
||||
// zie: project properties - configuration properties - debugging - command arguments
|
||||
if (argc != 2)
|
||||
@@ -65,7 +66,7 @@ int main(int argc, char *argv[])
|
||||
// Stel een threshold in. Laad evt de figuur eerst in VisionLab om een goede
|
||||
// threshold te bepalen.
|
||||
// ! Comment this line out when using rummikub images
|
||||
threshold(gray_image, binaryImage, 165, 1, CV_THRESH_BINARY_INV);
|
||||
threshold(gray_image, binaryImage, 220, 1, CV_THRESH_BINARY_INV);
|
||||
|
||||
// Alvorens bewerkingen uit te voeren op het beeld converteren we deze
|
||||
// naar een Mat object met grotere diepte (depth), t.w. 16 bits signed
|
||||
@@ -80,9 +81,9 @@ int main(int argc, char *argv[])
|
||||
int aantal = allContours(binary16S, contours); // <<<<*** De opdracht is dus om deze functie te maken ***
|
||||
|
||||
// druk alle punten van alle gevonden contouren af
|
||||
string line;
|
||||
cout << "Aantal gevonden contouren = " << aantal << endl;
|
||||
getline(cin, line);
|
||||
cin.get();
|
||||
|
||||
/*
|
||||
for (int i = 0; i < contours.size(); i++) {
|
||||
cout << "*** Contour " << i + 1 << " ***" << endl;
|
||||
@@ -101,14 +102,16 @@ int main(int argc, char *argv[])
|
||||
|
||||
cout << "Aantal gevonden boundaries = " << aantalB << endl;
|
||||
|
||||
|
||||
/*
|
||||
|
||||
cout << "Fill" << endl;
|
||||
vector<Point> region;
|
||||
Point center = FloodFill::findStartPoint(contours[0]);
|
||||
cout << "Center point: " << center.x << ", " << center.y << endl;
|
||||
FloodFill::enclosedPixels(contours[0], region);
|
||||
*/
|
||||
vector<vector<Point>> regions;
|
||||
for (vector<Point> contour : contours)
|
||||
{
|
||||
vector<Point> region;
|
||||
FloodFill::enclosedPixels(contour, region);
|
||||
regions.push_back(region);
|
||||
}
|
||||
|
||||
|
||||
// Creeer een witte image
|
||||
IplImage* iplimage = cvCreateImage(cvSize(binary16S.cols, binary16S.rows), IPL_DEPTH_8U, 3);
|
||||
@@ -118,31 +121,39 @@ int main(int argc, char *argv[])
|
||||
// teken de contouren op de witte image
|
||||
drawContours(contourImage, contours, -1, CV_RGB(255, 0, 0));
|
||||
drawContours(contourImage, bounds, -1, CV_RGB(0, 0, 255));
|
||||
drawContours(contourImage, regions, -1, CV_RGB(0, 255, 0));
|
||||
|
||||
/*
|
||||
for (Point p : region)
|
||||
for (vector<Point> region : regions)
|
||||
{
|
||||
circle(contourImage, p, 1, CV_RGB(0, 255, 0));
|
||||
for (Point p : region)
|
||||
{
|
||||
circle(contourImage, p, 1, CV_RGB(0, 255, 0));
|
||||
}
|
||||
}*/
|
||||
|
||||
// druk het image met de contouren af
|
||||
imshow("Found contours", contourImage);
|
||||
waitKey(0);
|
||||
|
||||
//BoundingBox::split(contours, image, argv[1]);
|
||||
|
||||
//Split images
|
||||
FloodFill::split(contours, image, argv[1]);
|
||||
|
||||
//haal bending energy waarde op
|
||||
|
||||
/*
|
||||
cout << "Bending Energy" << endl << "-----------" << endl;
|
||||
|
||||
for (int i = 0; i < contours.size(); i++)
|
||||
{
|
||||
cout << "[" << i << "] " << getBendingEnergy(contours[i]) << endl;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
waitKey(0);
|
||||
cout << "End program with any key" << endl;
|
||||
cin.get();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
// avansvisionlib - Growing Visionlibrary of Avans based on OpenCV 2.4.10
|
||||
// Goal: deep understanding of vision algorithms by means of developing own (new) algorithms.
|
||||
// deep understanding of neural networks
|
||||
//
|
||||
// Copyright Jan Oostindie, version 2.0 dd 5-12-2016 (= Neural Network (BPN) added to version 1.0 dd 5-11-2016.)
|
||||
// Contains basic functions to perform calculations on matrices/images of class Mat. Including BLOB labeling functions
|
||||
// Contains a BPN neural network.
|
||||
// Note: Students of Avans are free to use this library in projects and for own vision competence development. Others may ask permission to use it by means
|
||||
// of sending an email to Jan Oostindie, i.e. jac.oostindie@avans.nl
|
||||
#pragma once
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv/cv.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
// remark: a function call with a Mat-object parameter is a call by reference
|
||||
|
||||
/*********************** PROTOTYPES of the function library ************************/
|
||||
|
||||
// func: setup a specified entry (i,j) of a matrix m with a specific value
|
||||
// pre: (i < m.rows) & (j < m.cols)
|
||||
void setEntry(Mat m, int i, int j, double value);
|
||||
|
||||
// func: get the value of a specified entry (i,j) of a matrix m
|
||||
// pre: (i < m.rows) & (j < m.cols)
|
||||
// return: <return_value> == m(i,j)
|
||||
double getEntry(Mat m, int i, int j);
|
||||
|
||||
// func: calculate product of a row and column of equal length
|
||||
// pre: (row.cols == col.rows) & (row.rows == 1) & (col.cols == 1)
|
||||
double inproduct(Mat row, Mat col);
|
||||
|
||||
// func: prints matrix m in the console
|
||||
// pre: true
|
||||
void printMatrix(Mat m);
|
||||
|
||||
// func: select and get a row of a matrix m. rowNr contains the row number
|
||||
// pre: 0 < rowNr < m.rows
|
||||
// return: <result matrix> contains the selected row
|
||||
Mat getRow(Mat m, int rowNr);
|
||||
|
||||
// func: get a column of a matrix m. colNr contains the column number
|
||||
// pre: 0 < colNr < m.cols
|
||||
// return: <result matrix> contains the selected column
|
||||
Mat getCol(Mat m, int colNr);
|
||||
|
||||
// func: multiply two matrices a and b
|
||||
// pre: (a.cols == b.rows)
|
||||
// return: <result matrix>.rows == b.rows & <result matrix>.cols == b.cols
|
||||
Mat multiply(Mat a, Mat b);
|
||||
|
||||
// pre: matrices have equal dimensions i.e. (a.cols == b.cols) & (a.rows == b.rows)
|
||||
// return: <result matrix>(i,j) == a(i,j) + b(i,j) for all (0,0) <= (i,j) < (a.rows,a.cols)
|
||||
Mat add(Mat a, Mat b);
|
||||
|
||||
// func: transposes a matrix
|
||||
// return: <return_matrix>(i,j) = m(j,i) & <return_matrix>.rows = m.cols & <return_matrix>.cols = m.rows
|
||||
Mat transpose(Mat m);
|
||||
|
||||
// func: sets all entries of a matrix to a certain value
|
||||
// pre: true
|
||||
void setValue(Mat m, double value);
|
||||
|
||||
// func: generates a randomvalue between min and max
|
||||
// pre: true
|
||||
double generateRandomValue(double min, double max);
|
||||
|
||||
|
||||
// func: sets all entries of a matrix to a random value
|
||||
// pre: true
|
||||
void setRandomValue(Mat m, double min, double max);
|
||||
|
||||
|
||||
|
||||
/*********************************** Image operaties ****************************************/
|
||||
// NB images are supposed to have 1 channel (B/W image) and depth 16 bits signed (CV_16S)
|
||||
/********************************************************************************************/
|
||||
|
||||
// func: setup a specified entry (i,j) of a matrix m with a specific value
|
||||
// pre: (i < m.rows) & (j < m.cols)
|
||||
void setEntryImage(Mat m, int i, int j, _int16 value);
|
||||
|
||||
// func: get the value of a specified entry (i,j) of a matrix m
|
||||
// pre: (i < m.rows) & (j < m.cols)
|
||||
// return: <return_value> == m(i,j)
|
||||
_int16 getEntryImage(Mat m, int i, int j);
|
||||
|
||||
// func: calculate product of a row and column of equal length
|
||||
// pre: (row.cols == col.rows) & (row.rows == 1) & (col.cols == 1)
|
||||
_int16 inproductImage(Mat row, Mat col);
|
||||
|
||||
// func: select and get a row of a matrix m. rowNr contains the row number
|
||||
// pre: 0 < rowNr < m.rows
|
||||
// return: <result matrix> contains the selected row
|
||||
Mat getRowImage(Mat m, int rowNr);
|
||||
|
||||
// func: get a column of a matrix m. colNr contains the column number
|
||||
// pre: 0 < colNr < m.cols
|
||||
// return: <result matrix> contains the selected column
|
||||
Mat getColImage(Mat m, int colNr);
|
||||
|
||||
// func: multiply two matrices a and b
|
||||
// pre: (a.cols == b.rows)
|
||||
// return: <result matrix>.rows == b.rows & <result matrix>.cols == b.cols
|
||||
Mat multiplyImage(Mat a, Mat b);
|
||||
|
||||
// pre: matrices have equal dimensions i.e. (a.cols == b.cols) & (a.rows == b.rows)
|
||||
// return: <result matrix>(i,j) == a(i,j) + b(i,j) for all (0,0) <= (i,j) < (a.rows,a.cols)
|
||||
Mat addImage(Mat a, Mat b);
|
||||
|
||||
|
||||
// func: searches the maximum pixel value in the image
|
||||
// return: maximum pixel value
|
||||
_int16 maxPixelImage(Mat m);
|
||||
|
||||
// func: searches the minimum pixel value in the image
|
||||
// return: minimum pixel value
|
||||
_int16 minPixelImage(Mat m);
|
||||
|
||||
// func: determines the range of the image, i.e. the minimum
|
||||
// and maximum pixel value in the image
|
||||
// post: range = minPixelValue, maxPixelValue
|
||||
void getPixelRangeImage(Mat m, _int16 &minPixelValue, _int16 &maxPixelValue);
|
||||
|
||||
// func: transform scale the image
|
||||
// return: maximum pixel value
|
||||
void stretchImage(Mat m, _int16 minPixelValue, _int16 maxPixelValue);
|
||||
|
||||
// func: shows a 16S image on the screen. All values mapped on the interval 0-255
|
||||
/// pre: m is a 16S image (depth 16 bits, signed)
|
||||
void show16SImageStretch(Mat m, string windowTitle = "show16SImageStretch");
|
||||
|
||||
|
||||
// func: shows a 16S image on the screen. All values clipped to the interval 0-255
|
||||
// i.e. value < 0 => 0; 0 <= value <= 255 => value ; value > 255 => 255
|
||||
/// pre: m is a 16S image (depth 16 bits, signed)
|
||||
void show16SImageClip(Mat m, string windowTitle = "show16SImageClip");
|
||||
|
||||
|
||||
|
||||
// func: histogram gamma correction
|
||||
// pre: image has depth 8 bits unsigned and 1 or 3 channels
|
||||
// post: entry(i,j) = 255*power(entry@pre(i,j)/255)^gamma
|
||||
void gammaCorrection(Mat image, float gamma);
|
||||
|
||||
|
||||
// func: makes a administration used for labeling blobs.
|
||||
// the function adds a edge of 1 pixel wide tot a binary image, all with value 0.
|
||||
// All 1's are made -1. The result is returned.
|
||||
// This function is used by function labelBLOBs
|
||||
// pre : binaryImage has depth 16 bits signed int. Contains only values 0 and 1.
|
||||
// return_matrix: All "1" are made "-1" meaning value 1 and unvisited.
|
||||
Mat makeAdmin(Mat binaryImage);
|
||||
|
||||
|
||||
// func: Searches the next blob after position (row,col)
|
||||
// post: if return_value == 1 then (row,col) contains the position
|
||||
// where the next blob starts.
|
||||
// return_value: true => blob found ; starting position is (row,col)
|
||||
// false => no blob found ; (row, col) == (-1, -1)
|
||||
bool findNextBlob(Mat admin, int & row, int & col);
|
||||
|
||||
|
||||
// func: searches the first 1 when rotating around the pixel (currX,currY),
|
||||
// starting at position 0. Definition of relative positions:
|
||||
// 7 0 1
|
||||
// 6 X 2
|
||||
// 5 4 3
|
||||
void findNext1(Mat admin, int & currX, int & currY, int & next1);
|
||||
|
||||
// func: gets the entry of a neighbour pixel with relative position nr.
|
||||
// Definition of relative positions nr:
|
||||
// 7 0 1
|
||||
// 6 X 2
|
||||
// 5 4 3
|
||||
_int16 getEntryNeighbour(const Mat & admin, int x, int y, int nr);
|
||||
|
||||
|
||||
// func: determines if there are more than 1 adjacent 1's
|
||||
bool moreNext1(const Mat & admin, int x, int y);
|
||||
|
||||
|
||||
|
||||
// func: labels all pixels of one blob which starts at position (row,col) with blobNr.
|
||||
// This function is used by function labelBLOB's which labels all blobs.
|
||||
// return_value: area of the blob
|
||||
// Evaluation: This function uses a iterative algorithm in which a special labeling technique is
|
||||
// is used which gives the opportunity to trace all individiual pixels. This makes it
|
||||
// possible for example to save only these pixels on disk or to translate the object in
|
||||
// in the image.
|
||||
// The disadvantagae however is that the algorithm is more complicated an maybe a little bit
|
||||
// slower than the recursive variant.
|
||||
int labelIter(Mat & admin, int row, int col, int blobNr);
|
||||
|
||||
|
||||
// func: labels all pixels of one blob which starts at position (row,col) with blobNr.
|
||||
// return_value: area of the blob
|
||||
// Evaluation: This function uses a recursive algorithm which has the advantage that it is easy and trasparent.
|
||||
// The disadvantagae however is that it claims a lot of spacee on the stack. I.e. every found
|
||||
// pixel results in a function call which in case of large blobs causes a stack overflow.
|
||||
int labelRecursive(Mat & admin, int row, int col, int blobNr);
|
||||
|
||||
// func: retrieves a labeledImage from the labeling administration
|
||||
// pre : admin is contains labeled pixels with neighbour number information.
|
||||
// post: labeledImage: binary 8-connected pixels with value 1 in binaryImage are
|
||||
// labeled with the number of the object they belong to.
|
||||
void retrieveLabeledImage(const Mat & admin, Mat & labeledImage);
|
||||
|
||||
// func: labeling of all blobs in a binary image
|
||||
// pre : binaryImage has depth 16 bits signed int. Contains only values 0 and 1.
|
||||
// post: labeledImage: binary 8-connected pixels with value 1 in binaryImage are
|
||||
// labeled with the number of the object they belong to.
|
||||
// return_value: the total number of objects.
|
||||
int labelBLOBs(Mat binaryImage, Mat & labeledImage);
|
||||
|
||||
|
||||
// func: labeling of all blobs in a binary image with a area in [threshAreaMin,threshAreaMax]. Default
|
||||
// threshold is [1,INT_MAX]. Alle gathered data during the labeling proces is returned,
|
||||
// i.e. the positions of the firstpixel of each blob, the position of the blobs (i.e. the
|
||||
// centres of gravity) and the area's of all blobs.
|
||||
// pre : binaryImage has depth 16 bits signed int. Contains only values 0 and 1.
|
||||
// post: labeledImage: binary 8-connected pixels with value 1 in binaryImage are
|
||||
// labeled with the number of the object they belong to.
|
||||
// areaVec: contains all area's of the blobs. The index corresponds to the number
|
||||
// of the blobs. Index 0 has no meaning.
|
||||
// return_value: the total number of objects.
|
||||
int labelBLOBsInfo(Mat binaryImage, Mat & labeledImage,
|
||||
vector<Point2d *> & firstpixelVec, vector<Point2d *> & posVec,
|
||||
vector<int> & areaVec,
|
||||
int threshAreaMin = 1, int threshAreaMax = INT_MAX);
|
||||
|
||||
|
||||
/*****************************************************************************************************************************************************/
|
||||
/*BEGIN********************************************** BACK PROPAGATION NEURAL NETWORK ****************************************************************/
|
||||
/*****************************************************************************************************************************************************/
|
||||
|
||||
// func: loads an example of a training set
|
||||
// pre: true
|
||||
// post: ITset input training set. Each row contains a number of features.
|
||||
// OTset output training set. Each row contains the expected output belonging to the corresponding row of features in the input training set.
|
||||
//
|
||||
// TRAININGSET: I0 because of bias V0
|
||||
//
|
||||
// setnr I0 I1 I2 I3 I4 O1 O2
|
||||
// 1 1.0 0.4 -0.7 0.1 0.71 0.0 0.0
|
||||
// 2 1.0 0.3 -0.5 0.05 0.34 0.0 0.0
|
||||
// 3 1.0 0.6 0.1 0.3 0.12 0.0 1.0
|
||||
// 4 1.0 0.2 0.4 0.25 0.34 0.0 1.0
|
||||
// 5 1.0 -0.2 0.12 0.56 1.0 1.0 0.0
|
||||
// 6 1.0 0.1 -0.34 0.12 0.56 1.0 0.0
|
||||
// 7 1.0 -0.6 0.12 0.56 1.0 1.0 1.0
|
||||
// 8 1.0 0.56 -0.2 0.12 0.56 1.0 1.0
|
||||
void loadTrainingSet1(Mat & ITset, Mat & OTset);
|
||||
|
||||
|
||||
// func: loads an example of a training set in which only binary numbers are used.
|
||||
// pre: true
|
||||
// post: ITset input training set. Each row contains a number of binary numbers.
|
||||
// OTset output training set. Each row contains the expected output belonging to the corresponding row of binary numbers in the input training set.
|
||||
//
|
||||
// TRAININGSET binary function O1 = (I1 OR I2) AND I3
|
||||
// without bias
|
||||
// setnr I1 I2 I3 O1
|
||||
// 1 0 0 0 0
|
||||
// 2 0 0 1 0
|
||||
// 3 0 1 0 0
|
||||
// 4 0 1 1 1
|
||||
// 5 1 0 0 0
|
||||
// 6 1 0 1 1
|
||||
// 7 1 1 0 0
|
||||
// 8 1 1 1 1
|
||||
void loadBinaryTrainingSet1(Mat & ITset, Mat & OTset);
|
||||
|
||||
|
||||
// func: Initialization of the (1) weigthmatrices V0 and W0 and (2) of the delta matrices dV0 and dW0.
|
||||
// pre: inputNeurons, hiddenNeurons and outputNeurons define the Neural Network.
|
||||
// (from these numbers the dimensions of the weightmatrices can be determined)
|
||||
// post: V0 and W0 have random values between 0.1 and 0.9
|
||||
void initializeBPN(int inputNeurons, int hiddenNeurons, int outputNeurons,
|
||||
Mat & V0, Mat & dV0, Mat & W0, Mat & dW0);
|
||||
|
||||
|
||||
// Test of a BPN with all values defined explicitly.
|
||||
// pre: true
|
||||
// post: IT is the input training set ; OT is the corresponding output training set. ; V0, W0 are the weight matrices of a BPN with 1 hidden layer;
|
||||
// dV0, dW0 are the initial delta matrices of the weight factor matrices.
|
||||
void testBPN(Mat & IT, Mat & OT, Mat & V0, Mat & dV0, Mat & W0, Mat & dW0);
|
||||
|
||||
// func: Given an inputvector of the inputlayer and a weightmatrix V calculates the outputvector of the hiddenlayer
|
||||
// pre: II is input of the inputlayer. V = matrix with weightfactors between inputlayer and the hiddenlayer.
|
||||
// post: OH is the outputvector of the hidden layer
|
||||
void calculateOutputHiddenLayer(Mat II, Mat V, Mat & OH);
|
||||
|
||||
|
||||
// func: Given the outputvector of the hiddenlayer and a weigthmatrix W calculates the outputvector of the outputlayer
|
||||
// pre: OH is the outputvector of the hiddenlayer. W = matrix with weightfactors between hiddenlayer and the outputlayer.
|
||||
// post: OO is the outputvector of the output layer
|
||||
void calculateOutputBPN(Mat OH, Mat W, Mat & OO);
|
||||
|
||||
|
||||
// func: Calculates the total error Error = 1/2*Sigma(OTi-OOi)^2.
|
||||
// OTi is the expected output according to the trainingvector i
|
||||
// OOi is the calculated output from the current neural network of the traininngvector i
|
||||
// pre: OO is the outputvector of the outputlayer. OT is the expected outputvector from the trainingset
|
||||
// post: OO is the outputvector of the output layer
|
||||
void calculateOutputBPNError(Mat OO, Mat OT, double & outputError);
|
||||
|
||||
|
||||
// func: calculates the updates of the weight factor matrices V0 and W0 on basics of the calculated output matrix and the expected output matrix.
|
||||
// A back propagation algorithm is used.
|
||||
// pre: OT is the expected outputvector from the trainingset ; OO is the calculated outputvector of the outputlayer ;
|
||||
// OH is the calculated output of the hiddenlayer ; OI is the output of the inputlayer (normaly equal to the input of the inputlayer)
|
||||
// V0 is the weight matrix between the input layer and the hidden layer ; W0 is the weight matrix between the hiddenlayer and the output layer.
|
||||
// dV0, dW0 are the correction matrices.
|
||||
// post: V is the adapted weight matrix between the inputlayer and the hidden layer ; W is the weight matrix between the hiddenlayer and the output layer.
|
||||
void adaptVW(Mat OT, Mat OO, Mat OH, Mat OI, Mat W0, Mat dW0, Mat V0, Mat dV0, Mat & W, Mat & V,
|
||||
double ALPHA = 1.0, double ETHA = 0.6);
|
||||
|
||||
|
||||
// func: given an inputvector calculates the output of a BPN with weigth matrices V and W.
|
||||
// pre: II is the input vector of the BPN ;
|
||||
// V is the weight factor matrix between the input layer and the hidden layer
|
||||
// W is the weight factor matrix between the hidden layer and the output layer
|
||||
// return: output vector
|
||||
Mat BPN(Mat II, Mat V, Mat W);
|
||||
|
||||
|
||||
/*****************************************************************************************************************************************************/
|
||||
/*END********************************************** BACK PROPAGATION NEURAL NETWORK ******************************************************************/
|
||||
/*****************************************************************************************************************************************************/
|
||||
|
||||
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 484 KiB |
|
After Width: | Height: | Size: 484 KiB |
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 9.8 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 237 KiB |
|
After Width: | Height: | Size: 237 KiB |
@@ -0,0 +1,140 @@
|
||||
/* Functionaliteit: Werking van een Neuron (Perceptron)
|
||||
|
||||
W1*I1 + w2*I2 = input
|
||||
|
||||
input > threshold = > output = 1
|
||||
|
||||
input < threshold = > output = 0
|
||||
|
||||
aanpassing w1, w2 en threshold op basis van een gelabeld paar(I1, I2, correctoutput)
|
||||
|
||||
aanpassing threshold = -(correctoutput – output)
|
||||
|
||||
aanpassing W1 = aanpassing threshold * I1
|
||||
|
||||
aanpassing W2 = aanpassing threshold * I2
|
||||
|
||||
Jan Oostindie
|
||||
Avans Hogeschool
|
||||
Breda
|
||||
email: jac.oostindie@avanns.nl
|
||||
dd 9-9-2016
|
||||
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "perceptron.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
double perceptronOutput(double x1, double x2, double x3, double W1, double W2, double W3, double threshold) {
|
||||
// bereken input
|
||||
double input = W1*x1 + W2*x2 + W3*x3;
|
||||
|
||||
// bepaal output
|
||||
if (input > threshold) return 1.0;
|
||||
else return 0.0;
|
||||
} // perceptronOutput
|
||||
|
||||
|
||||
void run() {
|
||||
|
||||
const int rows = 8;
|
||||
|
||||
// waarheidstabel AND functie
|
||||
double tabel[rows][4] = { { 0.0, 0.0, 0.0, 0.0 },
|
||||
{ 0.0, 0.0, 1.0, 0.0 },
|
||||
{ 0.0, 1.0, 0.0, 0.0 },
|
||||
{ 0.0, 1.0, 1.0, 0.0 },
|
||||
{ 1.0, 0.0, 0.0, 0.0 },
|
||||
{ 1.0, 0.0, 1.0, 0.0 },
|
||||
{ 1.0, 1.0, 0.0, 1.0 },
|
||||
{ 1.0, 1.0, 1.0, 1.0 } };
|
||||
|
||||
// startwaarden van de weegfactoren (willekeurig)
|
||||
double W1 = 1003;
|
||||
double W2 = 456;
|
||||
double W3 = 738;
|
||||
|
||||
// startwaarde van de threshold (willekeurig)
|
||||
double threshold = 185;
|
||||
|
||||
// input en output variabele
|
||||
double input, output, deltaOutput;
|
||||
|
||||
// aanpassingen
|
||||
double deltaThreshold = 0.0, deltaW1 = 0.0, deltaW2 = 0.0, deltaW3 = 0.0;
|
||||
|
||||
// boolean flag wordt gehezen als output meer dan EPSILON afwijkt van verwachte output
|
||||
bool flag = false;
|
||||
const int EPSILON = 0.000001;
|
||||
|
||||
// waarheidstabel afdrukken
|
||||
cout << "Waarheidstabel waarvoor het perceptron wordt getraind" << endl;
|
||||
for (int rij = 0; rij < rows; rij++) {
|
||||
cout << setw(3) << tabel[rij][0] << setw(3) << tabel[rij][1] << setw(3) << tabel[rij][2] << setw(3) << tabel[rij][3] << endl;
|
||||
cout << endl;
|
||||
}
|
||||
cout << "Press ENTER to continue" << endl;
|
||||
cin.ignore();
|
||||
|
||||
int aantalRuns = 0;
|
||||
do {
|
||||
// voer een run uit
|
||||
flag = false;
|
||||
for (int rij = 0; rij < rows; rij++) {
|
||||
|
||||
// bereken actuele output van het nog ongetrainde perceptron
|
||||
output = perceptronOutput(tabel[rij][0], tabel[rij][1], tabel[rij][2], W1, W2, W3, threshold);
|
||||
|
||||
// bereken de afwijking van de actuele output t.o.v. verwachte output
|
||||
deltaOutput = (output - tabel[rij][3]);
|
||||
|
||||
if (abs(deltaOutput) > EPSILON) {
|
||||
|
||||
flag = true;
|
||||
|
||||
// berekening aanpassing W1 en W2
|
||||
deltaW1 = -deltaOutput*tabel[rij][0];
|
||||
deltaW2 = -deltaOutput*tabel[rij][1];
|
||||
deltaW3 = -deltaOutput*tabel[rij][2];
|
||||
|
||||
// threshold, W1 en W2 aanpassen
|
||||
threshold += deltaOutput;
|
||||
W1 += deltaW1;
|
||||
W2 += deltaW2;
|
||||
W3 += deltaW3;
|
||||
|
||||
} // if
|
||||
|
||||
} // for
|
||||
|
||||
cout << "Runs " << ++aantalRuns <<
|
||||
" Threshold = " << threshold << endl;
|
||||
}
|
||||
while (flag);
|
||||
|
||||
cout << "Berekende threshold = " << threshold << endl;
|
||||
cout << "Berekende W1 = " << W1 << endl;
|
||||
cout << "Berekende W2 = " << W2 << endl;
|
||||
cout << "Berekende W3 = " << W3 << endl;
|
||||
cout << "Press ENTER to continue" << endl;
|
||||
cin.ignore();
|
||||
|
||||
// genereer waarheidstabel met getrainde perceptron
|
||||
cout << "waarheidstabel gegenereerd met perceptron => " << endl;
|
||||
for (int rij = 0; rij < rows; rij++) {
|
||||
cout << setw(3) << tabel[rij][0] << setw(3) << tabel[rij][1] << setw(3) << tabel[rij][2] << setw(3) << perceptronOutput(tabel[rij][0], tabel[rij][1], tabel[rij][2], W1, W2, W3, threshold) << endl;
|
||||
}
|
||||
|
||||
cout << "Press ENTER to continue" << endl;
|
||||
cin.ignore();
|
||||
|
||||
} // main
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
double perceptronOutput(double x1, double x2, double x3, double W1, double W2, double W3, double threshold);
|
||||
|
||||
void run();
|
||||
@@ -0,0 +1,15 @@
|
||||
%YAML:1.0
|
||||
---
|
||||
intrinsic: !!opencv-matrix
|
||||
rows: 3
|
||||
cols: 3
|
||||
dt: d
|
||||
data: [ 5.9775286050661805e+02, 0., 3.2072411619271747e+02, 0.,
|
||||
5.9771212606858990e+02, 2.3945023396597830e+02, 0., 0., 1. ]
|
||||
distCoeffs: !!opencv-matrix
|
||||
rows: 1
|
||||
cols: 5
|
||||
dt: d
|
||||
data: [ -2.1240784744163693e-01, 1.5432560677868865e-01,
|
||||
-1.4662305986052036e-03, 5.8131805718548036e-04,
|
||||
-4.7909930415801667e-02 ]
|
||||
@@ -0,0 +1,198 @@
|
||||
#include "Camera.h"
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
Camera::Camera(int port)
|
||||
{
|
||||
Camera::port = port;
|
||||
capture = VideoCapture(port);
|
||||
|
||||
if (!capture.isOpened())
|
||||
{
|
||||
cout << "Failed to open camera on port " << port << endl;
|
||||
}
|
||||
|
||||
//lees callibratiedata uit
|
||||
// YML-file met callibratie data openen
|
||||
FileStorage fs(filename, FileStorage::READ);
|
||||
|
||||
// callibratie data ophalen
|
||||
fs["intrinsic"] >> intrinsic;
|
||||
fs["distCoeffs"] >> distCoeffs;
|
||||
|
||||
// sluiten van de YML-file
|
||||
fs.release();
|
||||
}
|
||||
|
||||
Camera::~Camera()
|
||||
{
|
||||
}
|
||||
|
||||
bool Camera::Calibrate()
|
||||
{
|
||||
// The number of boards you want to capture, the number of internal corners horizontally
|
||||
// and the number of internal corners vertically (That's just how the algorithm works).
|
||||
int numBoards = 10;
|
||||
int numCornersHor = 9;
|
||||
int numCornersVer = 7;
|
||||
|
||||
// We also create some additional variables that we'll be using later on.
|
||||
int numSquares = numCornersHor * numCornersVer;
|
||||
Size board_sz = Size(numCornersHor, numCornersVer);
|
||||
|
||||
// We want live feed for our calibration!
|
||||
|
||||
if (!capture.isOpened()) { //check if video device has been initialised
|
||||
cout << "cannot open camera";
|
||||
}
|
||||
|
||||
// - object_points is the physical position of the corners (in 3D space).
|
||||
// This has to be measured by us.
|
||||
// - image_points is the location of the corners in the image (in 2 dimensions).
|
||||
// - Once the program has actual physical locations and locations on the image, it can calculate
|
||||
// the relation between the two. Because we'll use a chessboard, these points have a definite
|
||||
// relations between them (they lie on straight lines and on squares).
|
||||
// - So the "expected" - "actual" relation can be used to correct the distortions in the image.
|
||||
vector<vector<Point3f>> object_points;
|
||||
vector<vector<Point2f>> image_points;
|
||||
|
||||
// Next, we create a list of corners. This will temporarily hold the current snapshot's chessboard corners.
|
||||
// keep track of the number of successfully captured chessboards
|
||||
vector<Point2f> corners;
|
||||
int successes = 0;
|
||||
|
||||
// - Create a list of coordinates (0,0,0), (0,1,0), (0,2,0)...(1,4,0)... so on.
|
||||
// Each corresponds to a particular vertex.
|
||||
// - You're essentially setting up the units of calibration.
|
||||
// Suppose the squares in your chessboards were 30 mm in size and you supplied these
|
||||
// coordinates as (0,0,0), (0, 30, 0), etc, you'd get all unknowns in millimeters.
|
||||
vector<Point3f> obj;
|
||||
for (int j = 0; j < numSquares; j++)
|
||||
obj.push_back(Point3f(j / numCornersHor, j%numCornersHor, 0.0f));
|
||||
|
||||
// Then we create two images and get the first snapshot from the camera:
|
||||
Mat image;
|
||||
Mat gray_image;
|
||||
capture >> image;
|
||||
|
||||
// As long as the number of successful entries has been less than the number required,
|
||||
// we keep looping:
|
||||
while (successes < numBoards)
|
||||
{
|
||||
// convert to gray scale
|
||||
cvtColor(image, gray_image, CV_BGR2GRAY);
|
||||
|
||||
// And we're here. The key functions:
|
||||
// findChessboardCorners tries to find a chessboard in the image.
|
||||
// IF found THEN the rough corners are returned.
|
||||
bool found = findChessboardCorners(image, board_sz, corners, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
|
||||
if (found)
|
||||
{
|
||||
// cornerSubPix refines the found corners.
|
||||
// De rough corners returned by findChessbooardCorners and the gray_image are input,
|
||||
// the refined corners are output.
|
||||
cornerSubPix(gray_image, corners, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
|
||||
|
||||
// draw the refined corners on the image i.e. chessboard.
|
||||
drawChessboardCorners(gray_image, board_sz, corners, found);
|
||||
}
|
||||
|
||||
// show results
|
||||
imshow("orginal", image);
|
||||
imshow("gray image", gray_image);
|
||||
|
||||
capture >> image;
|
||||
|
||||
int key = waitKey(1);
|
||||
|
||||
// Leave the program by pressing ESC-key
|
||||
if (key == 27) return 0;
|
||||
|
||||
// spacebar and chessboard found ==> save the snap
|
||||
if (key == ' ' && found != 0)
|
||||
{
|
||||
image_points.push_back(corners);
|
||||
object_points.push_back(obj);
|
||||
|
||||
successes++;
|
||||
|
||||
cout << "Stored snap " << successes << "/" << numBoards << endl;
|
||||
|
||||
if (successes >= numBoards)
|
||||
break;
|
||||
}
|
||||
} // while
|
||||
|
||||
// Next, we get ready to do the calibration. We declare variables that will hold the unknowns:
|
||||
// Matrix intrinsic contains cx,cy,fx,fy
|
||||
// Matrix disCoeffs contains the distortion coefficients: 3 numbers radial distortion and 2 numbers tangential distortion
|
||||
intrinsic = Mat(3, 3, CV_32FC1);
|
||||
distCoeffs;
|
||||
vector<Mat> rvecs;
|
||||
vector<Mat> tvecs;
|
||||
|
||||
// We modify the intrinsic matrix with whatever we know.
|
||||
// The camera's aspect ratio is 1 (that's usually the case...
|
||||
// i.e. fx = fy = f. If not, change it as required.
|
||||
// Elements (0,0) and (1,1) are the focal lengths along the X and Y axis.
|
||||
intrinsic.ptr<float>(0)[0] = 1;
|
||||
intrinsic.ptr<float>(1)[1] = 1;
|
||||
|
||||
// Determine the intrinsic matrix, distortion coefficients and the rotation+translation vectors.
|
||||
// Note: The calibrateCamera function converts all matrices into 64F format even if you
|
||||
// initialize it to 32F.
|
||||
calibrateCamera(object_points, image_points, image.size(), intrinsic, distCoeffs, rvecs, tvecs);
|
||||
|
||||
/***** saven van de callibratie data *****/
|
||||
|
||||
// YML-file aanmaken
|
||||
FileStorage fs(filename, FileStorage::WRITE);
|
||||
|
||||
// wegschrijven van callibratie data naar de YML-file
|
||||
fs << "intrinsic" << intrinsic << "distCoeffs" << distCoeffs;
|
||||
|
||||
// de file afsluiten
|
||||
fs.release();
|
||||
destroyAllWindows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Mat Camera::getImage()
|
||||
{
|
||||
Mat imageUndistorted;
|
||||
Mat image;
|
||||
Mat RGB_img;
|
||||
|
||||
capture >> image;
|
||||
|
||||
undistort(image, imageUndistorted, intrinsic, distCoeffs);
|
||||
|
||||
Rect region_of_interest = Rect(10, 10, image.cols - 20, image.rows - 20);
|
||||
Mat image_roi = imageUndistorted(region_of_interest);
|
||||
|
||||
return image_roi;
|
||||
}
|
||||
|
||||
Mat Camera::takeImage()
|
||||
{
|
||||
Mat image;
|
||||
|
||||
bool finished = false;
|
||||
|
||||
while (!finished)
|
||||
{
|
||||
image = getImage();
|
||||
|
||||
imshow("Live feed", image);
|
||||
|
||||
if (waitKey(100) > 0)
|
||||
{
|
||||
finished = true;
|
||||
destroyWindow("Live feed");
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2\imgproc\imgproc.hpp>
|
||||
#include <opencv2/calib3d/calib3d.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "avansvisionlib20.h"
|
||||
|
||||
class Camera
|
||||
{
|
||||
public:
|
||||
Camera(int port);
|
||||
~Camera();
|
||||
bool Calibrate();
|
||||
Mat getImage();
|
||||
Mat takeImage();
|
||||
private:
|
||||
const string filename = "calibration.yml";
|
||||
int port = 0;
|
||||
VideoCapture capture;
|
||||
Mat intrinsic, distCoeffs;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
#include "FeatureExtractor.h"
|
||||
|
||||
|
||||
|
||||
FeatureExtractor::FeatureExtractor(vector<Point> contour)
|
||||
{
|
||||
FeatureExtractor::contour = contour;
|
||||
|
||||
rect = minAreaRect(contour);
|
||||
}
|
||||
|
||||
|
||||
FeatureExtractor::~FeatureExtractor()
|
||||
{
|
||||
}
|
||||
|
||||
void FeatureExtractor::Extract(Mat &ref)
|
||||
{
|
||||
double ar = AspectRatio();
|
||||
double cr = Circularity();
|
||||
double bendingEnergy = getBendingEnergy();
|
||||
double convexHullBendingEnergy = getConvexHullBendingEnergy();
|
||||
double radius = getMinEnclosingCircleRadius();
|
||||
double perimeter = getPerimeter();
|
||||
double numDefects = convexDefects();
|
||||
|
||||
//ref = (Mat_<double>(1, 7) << 1.0, convexHullBendingEnergy / 100.0, ar, cr, bendingEnergy / 10000.0, , perimeter / 10000.0);
|
||||
ref = (Mat_<double>(1, 5) << 1.0, ar, cr / 10.0, convexHullBendingEnergy / 100.0, numDefects / 100.0);
|
||||
}
|
||||
|
||||
double FeatureExtractor::AspectRatio()
|
||||
{
|
||||
double ar = 0;
|
||||
|
||||
if(rect.size.width > rect.size.height)
|
||||
ar = (rect.size.height / rect.size.width);
|
||||
else
|
||||
ar = (rect.size.width / rect.size.height);
|
||||
|
||||
return ar;
|
||||
}
|
||||
|
||||
double FeatureExtractor::Circularity()
|
||||
{
|
||||
double radius = getMinEnclosingCircleRadius();
|
||||
double carea = radius * radius * M_PI;
|
||||
double rectarea = rect.size.width * rect.size.height;
|
||||
double cir = carea / rectarea;
|
||||
|
||||
return cir;
|
||||
}
|
||||
|
||||
RotatedRect FeatureExtractor::Rectangle()
|
||||
{
|
||||
return rect;
|
||||
}
|
||||
|
||||
double FeatureExtractor::getMinEnclosingCircleRadius()
|
||||
{
|
||||
float radius;
|
||||
Point2f center;
|
||||
minEnclosingCircle(contour, center, radius);
|
||||
|
||||
double rad = (double)radius;
|
||||
|
||||
return rad;
|
||||
}
|
||||
|
||||
double FeatureExtractor::getPerimeter()
|
||||
{
|
||||
double per = arcLength(contour, true);
|
||||
|
||||
return per;
|
||||
}
|
||||
|
||||
double FeatureExtractor::getBendingEnergy()
|
||||
{
|
||||
double energy = 0;
|
||||
int dir = 0;
|
||||
int prevdir = 0;
|
||||
|
||||
Point previousPoint = contour[contour.size() - 1];
|
||||
|
||||
for (Point p : contour)
|
||||
{
|
||||
dir = discoverNextRelativeDirection(previousPoint, p);
|
||||
energy += (dir - prevdir + 8) % 8;
|
||||
prevdir = dir;
|
||||
previousPoint = p;
|
||||
}
|
||||
|
||||
return energy;
|
||||
}
|
||||
|
||||
double FeatureExtractor::getConvexHullBendingEnergy() {
|
||||
|
||||
vector<Point> convex;
|
||||
convexHull(contour, convex);
|
||||
double energy = 0;
|
||||
int dir = 0;
|
||||
int prevdir = 0;
|
||||
|
||||
Point previousPoint = convex[convex.size() - 1];
|
||||
|
||||
for (Point p : convex)
|
||||
{
|
||||
dir = discoverNextRelativeDirection(previousPoint, p);
|
||||
energy += (dir - prevdir + 8) % 8;
|
||||
prevdir = dir;
|
||||
previousPoint = p;
|
||||
}
|
||||
|
||||
return energy;
|
||||
}
|
||||
|
||||
int FeatureExtractor::discoverNextRelativeDirection(const cv::Point &pos, const cv::Point &target)
|
||||
{
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int dir = i;
|
||||
|
||||
int newX = pos.x + rotateX[dir];
|
||||
int newY = pos.y + rotateY[dir];
|
||||
|
||||
if (target.x == newX && target.y == newY)
|
||||
return dir;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
double FeatureExtractor::convexDefects()
|
||||
{
|
||||
vector<int> hullsI(contour.size()); // Indices to contour points
|
||||
vector<Vec4i> defects;
|
||||
convexHull(contour, hullsI, false);
|
||||
convexityDefects(contour, hullsI, defects);
|
||||
|
||||
return (double)defects.size();
|
||||
}
|
||||
|
||||
void FeatureExtractor::findContour(Mat &image, vector<Point> &contour)
|
||||
{
|
||||
Mat canny_output;
|
||||
vector<vector<Point> > contours;
|
||||
vector<Vec4i> hierarchy;
|
||||
|
||||
Canny(image, canny_output, 20, 150, 3);
|
||||
findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
|
||||
|
||||
int large = 0;
|
||||
int contouridx = -1;
|
||||
|
||||
for (int i = 0; i < contours.size(); i++)
|
||||
{
|
||||
double a = arcLength(contours[i], false);
|
||||
|
||||
if (a > large)
|
||||
{
|
||||
large = a;
|
||||
contouridx = i;
|
||||
}
|
||||
}
|
||||
|
||||
contour = contours[contouridx];
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
#define _USE_MATH_DEFINES
|
||||
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <math.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
class FeatureExtractor
|
||||
{
|
||||
public:
|
||||
FeatureExtractor(vector<Point> contour);
|
||||
~FeatureExtractor();
|
||||
|
||||
void Extract(Mat& ref);
|
||||
|
||||
double AspectRatio();
|
||||
double Circularity();
|
||||
RotatedRect Rectangle();
|
||||
double getMinEnclosingCircleRadius();
|
||||
double getPerimeter();
|
||||
double getBendingEnergy();
|
||||
double getConvexHullBendingEnergy();
|
||||
double convexDefects();
|
||||
|
||||
static void findContour(Mat &image, vector<Point> &contour);
|
||||
private:
|
||||
vector<Point> contour;
|
||||
RotatedRect rect;
|
||||
int rotateX[8] = { 0, 1, 1, 1, 0, -1, -1, -1 };
|
||||
int rotateY[8] = { -1, -1, 0, 1, 1, 1, 0, -1 };
|
||||
int discoverNextRelativeDirection(const cv::Point &pos, const cv::Point &target);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include "Training.h"
|
||||
#include "Camera.h"
|
||||
#include "FeatureExtractor.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
int run();
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Camera cam(1);
|
||||
Training tr;
|
||||
|
||||
cout << "Welcome to Jarvis" << endl;
|
||||
cout << "Would you like to calibrate the camera (c), take pictures (p), train the network (t) or run the neural network (r)?" << endl;
|
||||
|
||||
char c;
|
||||
cin >> c;
|
||||
|
||||
switch (c) {
|
||||
case 'c':
|
||||
cam.Calibrate();
|
||||
break;
|
||||
case 'p':
|
||||
tr.CreateTrainingSet();
|
||||
break;
|
||||
case 't':
|
||||
tr.LoadTrainingSet();
|
||||
break;
|
||||
case 'r':
|
||||
run();
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
cout << "The program has finished, press enter to exit" << endl;
|
||||
cin.ignore();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int run()
|
||||
{
|
||||
Camera cam = Camera(1);
|
||||
NeuralNetwork bpn;
|
||||
bpn.Read();
|
||||
|
||||
while (true)
|
||||
{
|
||||
//Take picture and pre-process
|
||||
Mat image, gray_image, binaryImage;
|
||||
|
||||
image = cam.takeImage();
|
||||
cvtColor(image, gray_image, CV_BGR2GRAY);
|
||||
|
||||
//Find contour
|
||||
vector<Point> contour;
|
||||
FeatureExtractor::findContour(gray_image, contour);
|
||||
|
||||
//Extrax features
|
||||
FeatureExtractor ext = FeatureExtractor(contour);
|
||||
Mat descriptors = Mat_<double>();
|
||||
|
||||
ext.Extract(descriptors);
|
||||
|
||||
descriptors = transpose(descriptors);
|
||||
|
||||
string cls;
|
||||
bpn.Predict(descriptors, cls);
|
||||
|
||||
cout << "It\'s a " << cls << endl;
|
||||
|
||||
// teken de contouren
|
||||
Point2f vertices2f[4];
|
||||
ext.Rectangle().points(vertices2f);
|
||||
|
||||
// Convert them so we can use them in a fillConvexPoly
|
||||
Point vertices[4];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
vertices[i] = vertices2f[i];
|
||||
}
|
||||
|
||||
// Now we can fill the rotated rectangle with our specified color
|
||||
fillConvexPoly(image, vertices, 4, Scalar(0, 0, 255));
|
||||
|
||||
vector<vector<Point>> contours;
|
||||
contours.push_back(contour);
|
||||
drawContours(image, contours, -1, CV_RGB(0, 255, 0), 4);
|
||||
putText(image, cls, cvPoint(15, 30),
|
||||
FONT_HERSHEY_COMPLEX, 1.0, cvScalar(0, 0, 0), 1, CV_AA);
|
||||
|
||||
imshow("Neural detection", image);
|
||||
|
||||
waitKey(0);
|
||||
|
||||
destroyAllWindows();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Creeer een witte image
|
||||
IplImage* iplimage = cvCreateImage(cvSize(binaryImage.cols, binaryImage.rows), IPL_DEPTH_8U, 3);
|
||||
Mat contourImage = cvarrToMat(iplimage);
|
||||
contourImage = Scalar(255, 255, 255);
|
||||
|
||||
// teken de contouren op de witte image
|
||||
vector<vector<Point>> contours;
|
||||
contours.push_back(contour);
|
||||
|
||||
Point2f vertices2f[4];
|
||||
ext.Rectangle().points(vertices2f);
|
||||
|
||||
// Convert them so we can use them in a fillConvexPoly
|
||||
Point vertices[4];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
vertices[i] = vertices2f[i];
|
||||
}
|
||||
|
||||
// Now we can fill the rotated rectangle with our specified color
|
||||
fillConvexPoly(contourImage, vertices, 4, Scalar(0, 255, 0));
|
||||
drawContours(contourImage, contours, -1, CV_RGB(255, 0, 0));
|
||||
|
||||
imshow("Features", contourImage);
|
||||
waitKey(0);
|
||||
*/
|
||||
@@ -0,0 +1,177 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{E74AD02B-6B3F-431B-8D7E-DBFED7E6B671}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>NeuralDetector</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>D:\Code\OpenCV\install\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>D:\Code\OpenCV\install\include;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>D:\Code\OpenCV\install\x64\vc14\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>opencv_world330d.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>D:\Code\OpenCV\install\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalUsingDirectories>D:\Code\OpenCV\install\include;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>D:\Code\OpenCV\install\x64\vc14\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>opencv_world330d.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>D:\Code\OpenCV\install\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>D:\Code\OpenCV\install\x64\vc14\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>opencv_world330.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>D:\Code\OpenCV\install\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>D:\Code\OpenCV\install\x64\vc14\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>opencv_world330.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="avansvisionlib20.cpp" />
|
||||
<ClCompile Include="Camera.cpp" />
|
||||
<ClCompile Include="FeatureExtractor.cpp" />
|
||||
<ClCompile Include="NeuralNetwork.cpp" />
|
||||
<ClCompile Include="Main.cpp" />
|
||||
<ClCompile Include="Training.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="avansvisionlib20.h" />
|
||||
<ClInclude Include="Camera.h" />
|
||||
<ClInclude Include="FeatureExtractor.h" />
|
||||
<ClInclude Include="NeuralNetwork.h" />
|
||||
<ClInclude Include="OpenNetwork.h" />
|
||||
<ClInclude Include="Training.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="avansvisionlib20.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NeuralNetwork.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Camera.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FeatureExtractor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Training.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="avansvisionlib20.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NeuralNetwork.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Camera.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FeatureExtractor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Training.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="OpenNetwork.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,222 @@
|
||||
// Demo: Training of a Neural Network / Back-Propagation algorithm
|
||||
// Jan Oostindie, Avans Hogeschool, dd 6-12-2016
|
||||
// email: jac.oostindie@avans.nl
|
||||
|
||||
#include "NeuralNetwork.h"
|
||||
|
||||
NeuralNetwork::NeuralNetwork()
|
||||
{
|
||||
V0 = Mat();
|
||||
W0 = Mat();
|
||||
}
|
||||
|
||||
NeuralNetwork::~NeuralNetwork()
|
||||
{
|
||||
}
|
||||
|
||||
Mat NeuralNetwork::Train(Mat& ITset, Mat& OTset)
|
||||
{
|
||||
// V0, W0 : weightfactor matrices
|
||||
// dV0, dW0 : weightfactor correction matrices
|
||||
Mat dW0, dV0;
|
||||
|
||||
// default number of hiddenNeurons. The definite number is user input
|
||||
// inputNeurons and outputNeurons are implicitly determined via
|
||||
// the trainingset, i.e.: inputNeurons = ITset.cols ; outputNeurons = OTset.cols;
|
||||
int hiddenNeurons = 8;
|
||||
|
||||
//loadTrainingSet1(ITset, OTset);
|
||||
initializeBPN(ITset.cols, hiddenNeurons, OTset.cols, V0, dV0, W0, dW0);
|
||||
//testBPN(ITset, OTset, V0, dV0, W0, dW0);
|
||||
|
||||
|
||||
// IT: current training input of the inputlayer
|
||||
// OT: desired training output of the BPN
|
||||
// OH: output of the hiddenlayer
|
||||
// OO: output of the outputlayer
|
||||
Mat IT, OT, OH, OO;
|
||||
|
||||
// outputError0: error on output for the current input and weighfactors V0, W0
|
||||
// outputError1: error on output for the current input and new calculated
|
||||
// weighfactors, i.e. V1, W1
|
||||
double outputError0, outputError1, sumSqrDiffError = MAX_OUTPUT_ERROR + 1;
|
||||
Mat V1, W1;
|
||||
|
||||
cout << endl << "Starting neural training..." << endl;
|
||||
|
||||
int runs = 0;
|
||||
while ((sumSqrDiffError > MAX_OUTPUT_ERROR) && (runs < MAXRUNS)) {
|
||||
|
||||
sumSqrDiffError = 0;
|
||||
|
||||
for (int inputSetRowNr = 0; inputSetRowNr < ITset.rows; inputSetRowNr++) {
|
||||
|
||||
IT = transpose(getRow(ITset, inputSetRowNr));
|
||||
|
||||
OT = transpose(getRow(OTset, inputSetRowNr));
|
||||
|
||||
calculateOutputHiddenLayer(IT, V0, OH);
|
||||
|
||||
calculateOutputBPN(OH, W0, OO);
|
||||
|
||||
adaptVW(OT, OO, OH, IT, W0, dW0, V0, dV0, W1, V1);
|
||||
|
||||
calculateOutputBPNError(OO, OT, outputError0);
|
||||
|
||||
calculateOutputBPNError(BPN(IT, V1, W1), OT, outputError1);
|
||||
|
||||
sumSqrDiffError += (outputError1 - outputError0) * (outputError1 - outputError0);
|
||||
|
||||
V0 = V1;
|
||||
W0 = W1;
|
||||
}
|
||||
runs++;
|
||||
|
||||
if (runs % 1000 == 0)
|
||||
cout << "Completed " << runs << " runs, still working on it.. (" << sumSqrDiffError << ")" << endl;
|
||||
}
|
||||
|
||||
cout << "Training complete in " << runs << " runs" << endl;
|
||||
|
||||
Mat inputVectorTrainingSet, outputVectorTrainingSet, outputVectorBPN;
|
||||
|
||||
// druk voor elke input vector uit de trainingset de output vector uit trainingset af
|
||||
// tezamen met de output vector die het getrainde BPN (zie V0, W0) genereerd bij de
|
||||
// betreffende input vector.
|
||||
for (int row = 0; row < ITset.rows; row++) {
|
||||
|
||||
// haal volgende inputvector op uit de training set
|
||||
inputVectorTrainingSet = transpose(getRow(ITset, row));
|
||||
|
||||
// haal bijbehorende outputvector op uit de training set
|
||||
outputVectorTrainingSet = transpose(getRow(OTset, row));
|
||||
|
||||
// bepaal de outputvector die het getrainde BPN oplevert
|
||||
// bij de inputvector uit de trainingset
|
||||
outputVectorBPN = BPN(inputVectorTrainingSet, V0, W0);
|
||||
}
|
||||
|
||||
write();
|
||||
|
||||
return outputVectorBPN;
|
||||
}
|
||||
|
||||
void NeuralNetwork::Predict(Mat& ITset, string& name)
|
||||
{
|
||||
Mat output;
|
||||
output = transpose(BPN(ITset, V0, W0));
|
||||
|
||||
mat_class(output, name);
|
||||
}
|
||||
|
||||
void NeuralNetwork::Read()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
void NeuralNetwork::write()
|
||||
{
|
||||
for (pair<int, string> p : classes)
|
||||
cout << p.first << " - " << p.second << endl;
|
||||
|
||||
FileStorage fs("factors.yml", FileStorage::WRITE);
|
||||
fs << "W0" << W0 << "V0" << V0;
|
||||
fs.release();
|
||||
|
||||
FileStorage fs2("classes.yml", FileStorage::WRITE);
|
||||
|
||||
fs2 << "classes" << "{:";
|
||||
|
||||
for (pair<int, string> p : classes)
|
||||
{
|
||||
string el = "e" + to_string(p.first);
|
||||
fs2 << el << p.second;
|
||||
}
|
||||
|
||||
fs2 << "}";
|
||||
|
||||
fs2.release();
|
||||
}
|
||||
|
||||
void NeuralNetwork::load()
|
||||
{
|
||||
FileStorage fs("factors.yml", FileStorage::READ);
|
||||
|
||||
fs["W0"] >> W0;
|
||||
fs["V0"] >> V0;
|
||||
|
||||
fs.release();
|
||||
|
||||
FileStorage fs2("classes.yml", FileStorage::READ);
|
||||
|
||||
classes.clear();
|
||||
|
||||
FileNode cls = fs2["classes"];
|
||||
FileNodeIterator it = cls.begin(), it_end = cls.end();
|
||||
int idx = 0;
|
||||
|
||||
// iterate through a sequence using FileNodeIterator
|
||||
for (; it != it_end; ++it, idx++)
|
||||
{
|
||||
cv::FileNode item = *it;
|
||||
std::string key = item.name();
|
||||
string value = (string)item;
|
||||
|
||||
classes.insert(pair<int, string>(idx, value));
|
||||
}
|
||||
|
||||
cout << endl << "Available classes: " << endl;
|
||||
|
||||
for (pair<int, string> p : classes)
|
||||
cout << p.first << " - " << p.second << endl;
|
||||
|
||||
cout << endl;
|
||||
|
||||
fs2.release();
|
||||
}
|
||||
|
||||
void NeuralNetwork::getClass(const string& name, Mat& ref)
|
||||
{
|
||||
save_class(name, ref);
|
||||
}
|
||||
|
||||
void NeuralNetwork::save_class(const string& name, Mat& ref)
|
||||
{
|
||||
for (pair<int, string> p : classes)
|
||||
{
|
||||
if (p.second == name)
|
||||
{
|
||||
class_mat(p.first, ref);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
classes.insert(pair<int, string>(classidx, name));
|
||||
class_mat(classidx, ref);
|
||||
classidx++;
|
||||
}
|
||||
|
||||
void NeuralNetwork::class_mat(int index, Mat& ref)
|
||||
{
|
||||
ref = cv::Mat::zeros(cv::Size(numclasses, 1), CV_32F);
|
||||
ref.at<float>(index) = 1;
|
||||
}
|
||||
|
||||
void NeuralNetwork::mat_class(Mat& ref, string& name)
|
||||
{
|
||||
double maxvalue = 0;
|
||||
int index = 0;
|
||||
|
||||
for (int i = 0; i < ref.cols; i++)
|
||||
{
|
||||
double temp = getEntry(ref, 0, i);
|
||||
|
||||
if (temp > maxvalue)
|
||||
{
|
||||
maxvalue = temp;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
name = classes[index] + " " + to_string(maxvalue*100) + "%";
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv/cv.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "avansvisionlib20.h" // versie 2.0 (!)
|
||||
|
||||
class NeuralNetwork
|
||||
{
|
||||
public:
|
||||
NeuralNetwork();
|
||||
~NeuralNetwork();
|
||||
Mat Train(Mat& in, Mat& out);
|
||||
void Predict(Mat& ITset, string& name);
|
||||
void Read();
|
||||
void getClass(const string& name, Mat& ref);
|
||||
private:
|
||||
Mat V0, W0;
|
||||
const int MAXRUNS = 30000;
|
||||
const double MAX_OUTPUT_ERROR = 1E-11;
|
||||
void write();
|
||||
void load();
|
||||
|
||||
const int numclasses = 10;
|
||||
map<int, string> classes;
|
||||
int classidx = 0;
|
||||
void save_class(const string& name, Mat& ref);
|
||||
void class_mat(int index, Mat& ref);
|
||||
void mat_class(Mat& ref, string& name);
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
class OpenNetwork
|
||||
{
|
||||
public:
|
||||
OpenNetwork();
|
||||
~OpenNetwork();
|
||||
};
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
#include "Training.h"
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
|
||||
Training::Training()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
Training::~Training()
|
||||
{
|
||||
}
|
||||
|
||||
void Training::CreateTrainingSet()
|
||||
{
|
||||
Camera cam = Camera(1);
|
||||
bool running = true;
|
||||
|
||||
while (running)
|
||||
{
|
||||
string in;
|
||||
cout << "Ready for next category" << endl;
|
||||
cout << "Please specifiy name or type exit to stop: ";
|
||||
cin >> in;
|
||||
|
||||
if (in == "exit")
|
||||
{
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
|
||||
bool takingPhotos = true;
|
||||
int i = 0;
|
||||
|
||||
while (takingPhotos)
|
||||
{
|
||||
Mat image;
|
||||
image = cam.getImage();
|
||||
|
||||
imshow("Live feed", image);
|
||||
|
||||
int key = waitKey(100);
|
||||
switch (key)
|
||||
{
|
||||
case 32:
|
||||
imwrite("training/" + in + "_" + to_string(i) + ".bmp", image);
|
||||
cout << "Image taken #" << i << endl;
|
||||
i++;
|
||||
break;
|
||||
case 27:
|
||||
destroyWindow("Live feed");
|
||||
takingPhotos = false;
|
||||
running = false;
|
||||
break;
|
||||
case 110:
|
||||
destroyWindow("Live feed");
|
||||
takingPhotos = false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Training::LoadTrainingSet()
|
||||
{
|
||||
NeuralNetwork bpn;
|
||||
|
||||
Mat ITset = Mat_<double>();
|
||||
Mat OTset = Mat_<double>();
|
||||
|
||||
vector<string> files;
|
||||
string dir = "training/";
|
||||
|
||||
read_directory(dir, files);
|
||||
|
||||
cout << "Found " << files.size()-2 << " files in " << dir << endl;
|
||||
|
||||
random_shuffle(files.begin(), files.end());
|
||||
|
||||
for (string file : files)
|
||||
{
|
||||
string loc = dir + file;
|
||||
|
||||
Mat image;
|
||||
image = imread(loc, CV_LOAD_IMAGE_COLOR);
|
||||
|
||||
if (!image.data)
|
||||
continue;
|
||||
|
||||
cout << "Loaded " << file << endl;
|
||||
|
||||
string classname;
|
||||
class_name(file, classname);
|
||||
|
||||
Mat gray_image, binaryImage;
|
||||
cvtColor(image, gray_image, CV_BGR2GRAY);
|
||||
threshold(gray_image, binaryImage, 200, 1, CV_THRESH_BINARY_INV);
|
||||
|
||||
//Extract Features
|
||||
vector<Point> contour;
|
||||
FeatureExtractor::findContour(gray_image, contour);
|
||||
FeatureExtractor ftext = FeatureExtractor(contour);
|
||||
|
||||
Mat descriptors;
|
||||
ftext.Extract(descriptors);
|
||||
Mat output;
|
||||
bpn.getClass(classname, output);
|
||||
|
||||
ITset.push_back<double>(descriptors);
|
||||
OTset.push_back<double>(output);
|
||||
}
|
||||
|
||||
destroyAllWindows();
|
||||
|
||||
cout << "Finished loading all files" << endl;
|
||||
|
||||
bpn.Train(ITset, OTset);
|
||||
|
||||
cout << "Training complete" << endl;
|
||||
|
||||
cin.ignore();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Training::read_directory(const string& name, vector<string> &v)
|
||||
{
|
||||
string pattern = name;
|
||||
pattern.append("\\*");
|
||||
WIN32_FIND_DATA data;
|
||||
HANDLE hFind;
|
||||
if ((hFind = FindFirstFile(pattern.c_str() , &data)) != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
v.push_back(data.cFileName);
|
||||
} while (FindNextFile(hFind, &data) != 0);
|
||||
FindClose(hFind);
|
||||
}
|
||||
}
|
||||
|
||||
void Training::class_name(const string& name, string& classname)
|
||||
{
|
||||
string::size_type const p(name.find_last_of('_'));
|
||||
classname = name.substr(0, p);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#include "Camera.h"
|
||||
#include "FeatureExtractor.h"
|
||||
#include "NeuralNetwork.h"
|
||||
|
||||
class Training
|
||||
{
|
||||
public:
|
||||
Training();
|
||||
~Training();
|
||||
|
||||
void CreateTrainingSet();
|
||||
void LoadTrainingSet();
|
||||
private:
|
||||
void read_directory(const string& name, vector<string> &v);
|
||||
void class_name(const string& name, string& classname);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,335 @@
|
||||
// avansvisionlib - Growing Visionlibrary of Avans based on OpenCV 2.4.10
|
||||
// Goal: deep understanding of vision algorithms by means of developing own (new) algorithms.
|
||||
// deep understanding of neural networks
|
||||
//
|
||||
// Copyright Jan Oostindie, version 2.0 dd 5-12-2016 (= Neural Network (BPN) added to version 1.0 dd 5-11-2016.)
|
||||
// Contains basic functions to perform calculations on matrices/images of class Mat. Including BLOB labeling functions
|
||||
// Contains a BPN neural network.
|
||||
// Note: Students of Avans are free to use this library in projects and for own vision competence development. Others may ask permission to use it by means
|
||||
// of sending an email to Jan Oostindie, i.e. jac.oostindie@avans.nl
|
||||
#pragma once
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv/cv.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
// remark: a function call with a Mat-object parameter is a call by reference
|
||||
|
||||
/*********************** PROTOTYPES of the function library ************************/
|
||||
|
||||
// func: setup a specified entry (i,j) of a matrix m with a specific value
|
||||
// pre: (i < m.rows) & (j < m.cols)
|
||||
void setEntry(Mat m, int i, int j, double value);
|
||||
|
||||
// func: get the value of a specified entry (i,j) of a matrix m
|
||||
// pre: (i < m.rows) & (j < m.cols)
|
||||
// return: <return_value> == m(i,j)
|
||||
double getEntry(Mat m, int i, int j);
|
||||
|
||||
// func: calculate product of a row and column of equal length
|
||||
// pre: (row.cols == col.rows) & (row.rows == 1) & (col.cols == 1)
|
||||
double inproduct(Mat row, Mat col);
|
||||
|
||||
// func: prints matrix m in the console
|
||||
// pre: true
|
||||
void printMatrix(Mat m);
|
||||
|
||||
// func: select and get a row of a matrix m. rowNr contains the row number
|
||||
// pre: 0 < rowNr < m.rows
|
||||
// return: <result matrix> contains the selected row
|
||||
Mat getRow(Mat m, int rowNr);
|
||||
|
||||
// func: get a column of a matrix m. colNr contains the column number
|
||||
// pre: 0 < colNr < m.cols
|
||||
// return: <result matrix> contains the selected column
|
||||
Mat getCol(Mat m, int colNr);
|
||||
|
||||
// func: multiply two matrices a and b
|
||||
// pre: (a.cols == b.rows)
|
||||
// return: <result matrix>.rows == b.rows & <result matrix>.cols == b.cols
|
||||
Mat multiply(Mat a, Mat b);
|
||||
|
||||
// pre: matrices have equal dimensions i.e. (a.cols == b.cols) & (a.rows == b.rows)
|
||||
// return: <result matrix>(i,j) == a(i,j) + b(i,j) for all (0,0) <= (i,j) < (a.rows,a.cols)
|
||||
Mat add(Mat a, Mat b);
|
||||
|
||||
// func: transposes a matrix
|
||||
// return: <return_matrix>(i,j) = m(j,i) & <return_matrix>.rows = m.cols & <return_matrix>.cols = m.rows
|
||||
Mat transpose(Mat m);
|
||||
|
||||
// func: sets all entries of a matrix to a certain value
|
||||
// pre: true
|
||||
void setValue(Mat m, double value);
|
||||
|
||||
// func: generates a randomvalue between min and max
|
||||
// pre: true
|
||||
double generateRandomValue(double min, double max);
|
||||
|
||||
|
||||
// func: sets all entries of a matrix to a random value
|
||||
// pre: true
|
||||
void setRandomValue(Mat m, double min, double max);
|
||||
|
||||
|
||||
|
||||
/*********************************** Image operaties ****************************************/
|
||||
// NB images are supposed to have 1 channel (B/W image) and depth 16 bits signed (CV_16S)
|
||||
/********************************************************************************************/
|
||||
|
||||
// func: setup a specified entry (i,j) of a matrix m with a specific value
|
||||
// pre: (i < m.rows) & (j < m.cols)
|
||||
void setEntryImage(Mat m, int i, int j, _int16 value);
|
||||
|
||||
// func: get the value of a specified entry (i,j) of a matrix m
|
||||
// pre: (i < m.rows) & (j < m.cols)
|
||||
// return: <return_value> == m(i,j)
|
||||
_int16 getEntryImage(Mat m, int i, int j);
|
||||
|
||||
// func: calculate product of a row and column of equal length
|
||||
// pre: (row.cols == col.rows) & (row.rows == 1) & (col.cols == 1)
|
||||
_int16 inproductImage(Mat row, Mat col);
|
||||
|
||||
// func: select and get a row of a matrix m. rowNr contains the row number
|
||||
// pre: 0 < rowNr < m.rows
|
||||
// return: <result matrix> contains the selected row
|
||||
Mat getRowImage(Mat m, int rowNr);
|
||||
|
||||
// func: get a column of a matrix m. colNr contains the column number
|
||||
// pre: 0 < colNr < m.cols
|
||||
// return: <result matrix> contains the selected column
|
||||
Mat getColImage(Mat m, int colNr);
|
||||
|
||||
// func: multiply two matrices a and b
|
||||
// pre: (a.cols == b.rows)
|
||||
// return: <result matrix>.rows == b.rows & <result matrix>.cols == b.cols
|
||||
Mat multiplyImage(Mat a, Mat b);
|
||||
|
||||
// pre: matrices have equal dimensions i.e. (a.cols == b.cols) & (a.rows == b.rows)
|
||||
// return: <result matrix>(i,j) == a(i,j) + b(i,j) for all (0,0) <= (i,j) < (a.rows,a.cols)
|
||||
Mat addImage(Mat a, Mat b);
|
||||
|
||||
|
||||
// func: searches the maximum pixel value in the image
|
||||
// return: maximum pixel value
|
||||
_int16 maxPixelImage(Mat m);
|
||||
|
||||
// func: searches the minimum pixel value in the image
|
||||
// return: minimum pixel value
|
||||
_int16 minPixelImage(Mat m);
|
||||
|
||||
// func: determines the range of the image, i.e. the minimum
|
||||
// and maximum pixel value in the image
|
||||
// post: range = minPixelValue, maxPixelValue
|
||||
void getPixelRangeImage(Mat m, _int16 &minPixelValue, _int16 &maxPixelValue);
|
||||
|
||||
// func: transform scale the image
|
||||
// return: maximum pixel value
|
||||
void stretchImage(Mat m, _int16 minPixelValue, _int16 maxPixelValue);
|
||||
|
||||
// func: shows a 16S image on the screen. All values mapped on the interval 0-255
|
||||
/// pre: m is a 16S image (depth 16 bits, signed)
|
||||
void show16SImageStretch(Mat m, string windowTitle = "show16SImageStretch");
|
||||
|
||||
|
||||
// func: shows a 16S image on the screen. All values clipped to the interval 0-255
|
||||
// i.e. value < 0 => 0; 0 <= value <= 255 => value ; value > 255 => 255
|
||||
/// pre: m is a 16S image (depth 16 bits, signed)
|
||||
void show16SImageClip(Mat m, string windowTitle = "show16SImageClip");
|
||||
|
||||
|
||||
|
||||
// func: histogram gamma correction
|
||||
// pre: image has depth 8 bits unsigned and 1 or 3 channels
|
||||
// post: entry(i,j) = 255*power(entry@pre(i,j)/255)^gamma
|
||||
void gammaCorrection(Mat image, float gamma);
|
||||
|
||||
|
||||
// func: makes a administration used for labeling blobs.
|
||||
// the function adds a edge of 1 pixel wide tot a binary image, all with value 0.
|
||||
// All 1's are made -1. The result is returned.
|
||||
// This function is used by function labelBLOBs
|
||||
// pre : binaryImage has depth 16 bits signed int. Contains only values 0 and 1.
|
||||
// return_matrix: All "1" are made "-1" meaning value 1 and unvisited.
|
||||
Mat makeAdmin(Mat binaryImage);
|
||||
|
||||
|
||||
// func: Searches the next blob after position (row,col)
|
||||
// post: if return_value == 1 then (row,col) contains the position
|
||||
// where the next blob starts.
|
||||
// return_value: true => blob found ; starting position is (row,col)
|
||||
// false => no blob found ; (row, col) == (-1, -1)
|
||||
bool findNextBlob(Mat admin, int & row, int & col);
|
||||
|
||||
|
||||
// func: searches the first 1 when rotating around the pixel (currX,currY),
|
||||
// starting at position 0. Definition of relative positions:
|
||||
// 7 0 1
|
||||
// 6 X 2
|
||||
// 5 4 3
|
||||
void findNext1(Mat admin, int & currX, int & currY, int & next1);
|
||||
|
||||
// func: gets the entry of a neighbour pixel with relative position nr.
|
||||
// Definition of relative positions nr:
|
||||
// 7 0 1
|
||||
// 6 X 2
|
||||
// 5 4 3
|
||||
_int16 getEntryNeighbour(const Mat & admin, int x, int y, int nr);
|
||||
|
||||
|
||||
// func: determines if there are more than 1 adjacent 1's
|
||||
bool moreNext1(const Mat & admin, int x, int y);
|
||||
|
||||
|
||||
|
||||
// func: labels all pixels of one blob which starts at position (row,col) with blobNr.
|
||||
// This function is used by function labelBLOB's which labels all blobs.
|
||||
// return_value: area of the blob
|
||||
// Evaluation: This function uses a iterative algorithm in which a special labeling technique is
|
||||
// is used which gives the opportunity to trace all individiual pixels. This makes it
|
||||
// possible for example to save only these pixels on disk or to translate the object in
|
||||
// in the image.
|
||||
// The disadvantagae however is that the algorithm is more complicated an maybe a little bit
|
||||
// slower than the recursive variant.
|
||||
int labelIter(Mat & admin, int row, int col, int blobNr);
|
||||
|
||||
|
||||
// func: labels all pixels of one blob which starts at position (row,col) with blobNr.
|
||||
// return_value: area of the blob
|
||||
// Evaluation: This function uses a recursive algorithm which has the advantage that it is easy and trasparent.
|
||||
// The disadvantagae however is that it claims a lot of spacee on the stack. I.e. every found
|
||||
// pixel results in a function call which in case of large blobs causes a stack overflow.
|
||||
int labelRecursive(Mat & admin, int row, int col, int blobNr);
|
||||
|
||||
// func: retrieves a labeledImage from the labeling administration
|
||||
// pre : admin is contains labeled pixels with neighbour number information.
|
||||
// post: labeledImage: binary 8-connected pixels with value 1 in binaryImage are
|
||||
// labeled with the number of the object they belong to.
|
||||
void retrieveLabeledImage(const Mat & admin, Mat & labeledImage);
|
||||
|
||||
// func: labeling of all blobs in a binary image
|
||||
// pre : binaryImage has depth 16 bits signed int. Contains only values 0 and 1.
|
||||
// post: labeledImage: binary 8-connected pixels with value 1 in binaryImage are
|
||||
// labeled with the number of the object they belong to.
|
||||
// return_value: the total number of objects.
|
||||
int labelBLOBs(Mat binaryImage, Mat & labeledImage);
|
||||
|
||||
|
||||
// func: labeling of all blobs in a binary image with a area in [threshAreaMin,threshAreaMax]. Default
|
||||
// threshold is [1,INT_MAX]. Alle gathered data during the labeling proces is returned,
|
||||
// i.e. the positions of the firstpixel of each blob, the position of the blobs (i.e. the
|
||||
// centres of gravity) and the area's of all blobs.
|
||||
// pre : binaryImage has depth 16 bits signed int. Contains only values 0 and 1.
|
||||
// post: labeledImage: binary 8-connected pixels with value 1 in binaryImage are
|
||||
// labeled with the number of the object they belong to.
|
||||
// areaVec: contains all area's of the blobs. The index corresponds to the number
|
||||
// of the blobs. Index 0 has no meaning.
|
||||
// return_value: the total number of objects.
|
||||
int labelBLOBsInfo(Mat binaryImage, Mat & labeledImage,
|
||||
vector<Point2d *> & firstpixelVec, vector<Point2d *> & posVec,
|
||||
vector<int> & areaVec,
|
||||
int threshAreaMin = 1, int threshAreaMax = INT_MAX);
|
||||
|
||||
|
||||
/*****************************************************************************************************************************************************/
|
||||
/*BEGIN********************************************** BACK PROPAGATION NEURAL NETWORK ****************************************************************/
|
||||
/*****************************************************************************************************************************************************/
|
||||
|
||||
// func: loads an example of a training set
|
||||
// pre: true
|
||||
// post: ITset input training set. Each row contains a number of features.
|
||||
// OTset output training set. Each row contains the expected output belonging to the corresponding row of features in the input training set.
|
||||
//
|
||||
// TRAININGSET: I0 because of bias V0
|
||||
//
|
||||
// setnr I0 I1 I2 I3 I4 O1 O2
|
||||
// 1 1.0 0.4 -0.7 0.1 0.71 0.0 0.0
|
||||
// 2 1.0 0.3 -0.5 0.05 0.34 0.0 0.0
|
||||
// 3 1.0 0.6 0.1 0.3 0.12 0.0 1.0
|
||||
// 4 1.0 0.2 0.4 0.25 0.34 0.0 1.0
|
||||
// 5 1.0 -0.2 0.12 0.56 1.0 1.0 0.0
|
||||
// 6 1.0 0.1 -0.34 0.12 0.56 1.0 0.0
|
||||
// 7 1.0 -0.6 0.12 0.56 1.0 1.0 1.0
|
||||
// 8 1.0 0.56 -0.2 0.12 0.56 1.0 1.0
|
||||
void loadTrainingSet1(Mat & ITset, Mat & OTset);
|
||||
|
||||
|
||||
// func: loads an example of a training set in which only binary numbers are used.
|
||||
// pre: true
|
||||
// post: ITset input training set. Each row contains a number of binary numbers.
|
||||
// OTset output training set. Each row contains the expected output belonging to the corresponding row of binary numbers in the input training set.
|
||||
//
|
||||
// TRAININGSET binary function O1 = (I1 OR I2) AND I3
|
||||
// without bias
|
||||
// setnr I1 I2 I3 O1
|
||||
// 1 0 0 0 0
|
||||
// 2 0 0 1 0
|
||||
// 3 0 1 0 0
|
||||
// 4 0 1 1 1
|
||||
// 5 1 0 0 0
|
||||
// 6 1 0 1 1
|
||||
// 7 1 1 0 0
|
||||
// 8 1 1 1 1
|
||||
void loadBinaryTrainingSet1(Mat & ITset, Mat & OTset);
|
||||
|
||||
|
||||
// func: Initialization of the (1) weigthmatrices V0 and W0 and (2) of the delta matrices dV0 and dW0.
|
||||
// pre: inputNeurons, hiddenNeurons and outputNeurons define the Neural Network.
|
||||
// (from these numbers the dimensions of the weightmatrices can be determined)
|
||||
// post: V0 and W0 have random values between 0.1 and 0.9
|
||||
void initializeBPN(int inputNeurons, int hiddenNeurons, int outputNeurons,
|
||||
Mat & V0, Mat & dV0, Mat & W0, Mat & dW0);
|
||||
|
||||
|
||||
// Test of a BPN with all values defined explicitly.
|
||||
// pre: true
|
||||
// post: IT is the input training set ; OT is the corresponding output training set. ; V0, W0 are the weight matrices of a BPN with 1 hidden layer;
|
||||
// dV0, dW0 are the initial delta matrices of the weight factor matrices.
|
||||
void testBPN(Mat & IT, Mat & OT, Mat & V0, Mat & dV0, Mat & W0, Mat & dW0);
|
||||
|
||||
// func: Given an inputvector of the inputlayer and a weightmatrix V calculates the outputvector of the hiddenlayer
|
||||
// pre: II is input of the inputlayer. V = matrix with weightfactors between inputlayer and the hiddenlayer.
|
||||
// post: OH is the outputvector of the hidden layer
|
||||
void calculateOutputHiddenLayer(Mat II, Mat V, Mat & OH);
|
||||
|
||||
|
||||
// func: Given the outputvector of the hiddenlayer and a weigthmatrix W calculates the outputvector of the outputlayer
|
||||
// pre: OH is the outputvector of the hiddenlayer. W = matrix with weightfactors between hiddenlayer and the outputlayer.
|
||||
// post: OO is the outputvector of the output layer
|
||||
void calculateOutputBPN(Mat OH, Mat W, Mat & OO);
|
||||
|
||||
|
||||
// func: Calculates the total error Error = 1/2*Sigma(OTi-OOi)^2.
|
||||
// OTi is the expected output according to the trainingvector i
|
||||
// OOi is the calculated output from the current neural network of the traininngvector i
|
||||
// pre: OO is the outputvector of the outputlayer. OT is the expected outputvector from the trainingset
|
||||
// post: OO is the outputvector of the output layer
|
||||
void calculateOutputBPNError(Mat OO, Mat OT, double & outputError);
|
||||
|
||||
|
||||
// func: calculates the updates of the weight factor matrices V0 and W0 on basics of the calculated output matrix and the expected output matrix.
|
||||
// A back propagation algorithm is used.
|
||||
// pre: OT is the expected outputvector from the trainingset ; OO is the calculated outputvector of the outputlayer ;
|
||||
// OH is the calculated output of the hiddenlayer ; OI is the output of the inputlayer (normaly equal to the input of the inputlayer)
|
||||
// V0 is the weight matrix between the input layer and the hidden layer ; W0 is the weight matrix between the hiddenlayer and the output layer.
|
||||
// dV0, dW0 are the correction matrices.
|
||||
// post: V is the adapted weight matrix between the inputlayer and the hidden layer ; W is the weight matrix between the hiddenlayer and the output layer.
|
||||
void adaptVW(Mat OT, Mat OO, Mat OH, Mat OI, Mat W0, Mat dW0, Mat V0, Mat dV0, Mat & W, Mat & V,
|
||||
double ALPHA = 1.0, double ETHA = 0.6);
|
||||
|
||||
|
||||
// func: given an inputvector calculates the output of a BPN with weigth matrices V and W.
|
||||
// pre: II is the input vector of the BPN ;
|
||||
// V is the weight factor matrix between the input layer and the hidden layer
|
||||
// W is the weight factor matrix between the hidden layer and the output layer
|
||||
// return: output vector
|
||||
Mat BPN(Mat II, Mat V, Mat W);
|
||||
|
||||
|
||||
/*****************************************************************************************************************************************************/
|
||||
/*END********************************************** BACK PROPAGATION NEURAL NETWORK ******************************************************************/
|
||||
/*****************************************************************************************************************************************************/
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
%YAML:1.0
|
||||
---
|
||||
intrinsic: !!opencv-matrix
|
||||
rows: 3
|
||||
cols: 3
|
||||
dt: d
|
||||
data: [ 7.7102786562030786e+04, 0., 3.2013752810898518e+02, 0.,
|
||||
1.1313075108780187e+05, 2.4041984682542122e+02, 0., 0., 1. ]
|
||||
distCoeffs: !!opencv-matrix
|
||||
rows: 1
|
||||
cols: 5
|
||||
dt: d
|
||||
data: [ -1.6033489811253014e+02, -3.6422783919263818e-02,
|
||||
-2.9072693275266626e-02, -3.5312598551078556e-01,
|
||||
-6.9187392701624002e-07 ]
|
||||
@@ -0,0 +1,4 @@
|
||||
%YAML:1.0
|
||||
---
|
||||
classes: { e0:weerstand, e1:irtrans, e2:switch, e3:reflsens, e4:irsens,
|
||||
e5:reedsens, e6:card, e7:led, e8:button, e9:rgbled }
|
||||
@@ -0,0 +1,70 @@
|
||||
%YAML:1.0
|
||||
---
|
||||
W0: !!opencv-matrix
|
||||
rows: 8
|
||||
cols: 10
|
||||
dt: d
|
||||
data: [ -4.8813774957793505e+00, -1.4851964864258784e+01,
|
||||
-4.5483958882918500e+00, 2.3423976029083846e+01,
|
||||
-2.7036296416086123e+00, -5.9289881679629190e+01,
|
||||
-3.6879635531940997e+00, -3.3153545804030564e+01,
|
||||
-1.4020142561256883e+00, -7.0336731756450614e+00,
|
||||
8.8357037082684666e+00, 1.2314510070259121e+01,
|
||||
-3.4472596296194356e+00, -1.1923745474347557e+01,
|
||||
-4.4282540281508034e+00, 2.4457028473557347e+01,
|
||||
3.6136991577659492e+00, -2.5827572663987759e+01,
|
||||
-1.3892967734397374e+01, -8.4284128215643772e-01,
|
||||
-1.5656959650996116e+01, -4.7792720274921949e+00,
|
||||
2.2975802354552862e+01, -6.2055876498801723e+00,
|
||||
-5.7482437173820735e+01, -4.6866402386216075e+00,
|
||||
-3.0466706366866589e+01, -7.0842282146302944e+00,
|
||||
-6.2597171792574171e+00, -7.2087129758066659e+00,
|
||||
-1.5425205894698555e+01, 4.3120273767387673e+01,
|
||||
-5.5453766803160338e+00, -3.9096843912958307e-01,
|
||||
-1.0403409583426930e+01, 2.5070656273447195e+01,
|
||||
-1.2109893602230631e+01, 2.9945425250036301e+01,
|
||||
-5.6642091074608834e+00, -3.0840158943557448e+01,
|
||||
2.5513648309284322e+00, -1.7087631494600185e+01,
|
||||
-1.4015650118577094e+01, -3.3031333903438806e+01,
|
||||
-1.7294407183796434e+00, -3.2643739919895147e+01,
|
||||
-1.9333188145064401e+01, -6.3934782960318515e+00,
|
||||
-1.8871662520667233e+01, -1.5080559598577183e+01,
|
||||
5.2874934032701137e-01, 2.5826625216358101e+00,
|
||||
8.3597510472828951e+00, -2.0854574479392202e-01,
|
||||
-1.0790385094292049e+01, -4.8203290529982112e+00,
|
||||
2.3059664039490269e+01, -1.5713643646359962e+01,
|
||||
-2.1086899521790972e+01, -6.1737512017926734e+00,
|
||||
-1.6040305572556772e+01, -3.1420416546297179e+01,
|
||||
-9.6651877009273299e+00, -9.3255536054811716e-01,
|
||||
-8.7417385800329424e+00, 1.4584107173942127e+00,
|
||||
-1.9611038941263057e+01, -6.9351624096848574e-01,
|
||||
-3.8496653692305358e+01, 3.1842200474091559e+01,
|
||||
-1.2903254663541592e+01, -1.4547573929553105e+01,
|
||||
-9.2829295697875889e+00, -1.0087144923614213e+01,
|
||||
2.0960410041424829e+01, -2.1442616606862913e+01,
|
||||
2.0254590030822840e+01, -2.9413976475212888e+00,
|
||||
3.4350620310034941e+01, -2.0392084844460520e+01 ]
|
||||
V0: !!opencv-matrix
|
||||
rows: 5
|
||||
cols: 8
|
||||
dt: d
|
||||
data: [ -6.5636286541558171e+00, 4.5330404221912382e+01,
|
||||
-1.1149842067895429e+01, 7.5086888359720900e+00,
|
||||
2.8132961939742511e+00, -3.2716268982804380e+01,
|
||||
2.4073267678846292e+01, -1.5426805055872450e+01,
|
||||
-2.3447511567066414e+01, -7.1071961568313483e+01,
|
||||
2.4376431377296260e+01, -5.2835959692878383e+01,
|
||||
1.5962714728971601e+01, 3.5537070580189244e+01,
|
||||
-2.9387489075397973e+01, 2.7081013867840458e+01,
|
||||
4.3302753434844213e+01, -1.0978817742962482e+02,
|
||||
-4.2383027486121954e+01, 6.8440729304108856e+01,
|
||||
-9.6243156066355802e+00, 2.9979769994501602e+01,
|
||||
-3.7724179920359870e+00, 9.9776059105303023e+00,
|
||||
5.0426955715121640e+00, -5.7015329865766313e+00,
|
||||
7.6021476153135108e+00, 1.4119669046625256e+00,
|
||||
-1.3832537537011591e+01, -7.8448492545467206e+00,
|
||||
-1.8009846302065957e+00, 4.3426637435861783e+00,
|
||||
1.6086554490069808e+01, 4.4710323658171866e+01,
|
||||
-8.9095095711932455e+00, -4.1369158011178691e+00,
|
||||
-9.9794096446219829e+00, 2.2801143768856548e+01,
|
||||
-4.2606068131615935e+01, -1.7282938175700217e+01 ]
|
||||
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
After Width: | Height: | Size: 836 KiB |