diff options
28 files changed, 1369 insertions, 578 deletions
diff --git a/Software/Visual_Studio/Build/Shortcuts/Machine Emulator.lnk b/Software/Visual_Studio/Build/Shortcuts/Machine Emulator.lnk Binary files differindex 09f542836..407543254 100644 --- a/Software/Visual_Studio/Build/Shortcuts/Machine Emulator.lnk +++ b/Software/Visual_Studio/Build/Shortcuts/Machine Emulator.lnk diff --git a/Software/Visual_Studio/Build/Shortcuts/Machine Studio.lnk b/Software/Visual_Studio/Build/Shortcuts/Machine Studio.lnk Binary files differindex 34c82a731..a09171af6 100644 --- a/Software/Visual_Studio/Build/Shortcuts/Machine Studio.lnk +++ b/Software/Visual_Studio/Build/Shortcuts/Machine Studio.lnk diff --git a/Software/Visual_Studio/Build/Shortcuts/Proto Compiler GUI.lnk b/Software/Visual_Studio/Build/Shortcuts/Proto Compiler GUI.lnk Binary files differindex 86ac8562d..02d854013 100644 --- a/Software/Visual_Studio/Build/Shortcuts/Proto Compiler GUI.lnk +++ b/Software/Visual_Studio/Build/Shortcuts/Proto Compiler GUI.lnk diff --git a/Software/Visual_Studio/Build/Shortcuts/Stubs Execution GUI.lnk b/Software/Visual_Studio/Build/Shortcuts/Stubs Execution GUI.lnk Binary files differindex b0950b3d7..bb5ebf9bf 100644 --- a/Software/Visual_Studio/Build/Shortcuts/Stubs Execution GUI.lnk +++ b/Software/Visual_Studio/Build/Shortcuts/Stubs Execution GUI.lnk diff --git a/Software/Visual_Studio/Build/Shortcuts/Transport Router.lnk b/Software/Visual_Studio/Build/Shortcuts/Transport Router.lnk Binary files differindex 5285bbf10..533808c11 100644 --- a/Software/Visual_Studio/Build/Shortcuts/Transport Router.lnk +++ b/Software/Visual_Studio/Build/Shortcuts/Transport Router.lnk diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj index 4cf1855ca..3c272892b 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj @@ -55,7 +55,9 @@ <Reference Include="MaterialDesignThemes.Wpf, Version=2.3.1.953, Culture=neutral, processorArchitecture=MSIL"> <HintPath>..\..\packages\MaterialDesignThemes.2.3.1.953\lib\net45\MaterialDesignThemes.Wpf.dll</HintPath> </Reference> - <Reference Include="Microsoft.SqlServer.AzureStorageEnum, Version=14.100.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL" /> + <Reference Include="Microsoft.SqlServer.AzureStorageEnum"> + <HintPath>..\..\Referenced Assemblies\SMO\Microsoft.SqlServer.AzureStorageEnum.dll</HintPath> + </Reference> <Reference Include="Microsoft.WindowsAzure.Storage, Version=4.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" /> <Reference Include="System" /> <Reference Include="System.ComponentModel.DataAnnotations" /> @@ -386,7 +388,7 @@ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> + <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> </VisualStudio> </ProjectExtensions> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj index 8d9255926..c94102df5 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj @@ -420,6 +420,10 @@ <Project>{5001990f-977b-48ff-b217-0236a5022ad8}</Project> <Name>Tango.Web</Name> </ProjectReference> + <ProjectReference Include="..\..\TCC\Tango.TCC.BL\Tango.TCC.BL.csproj"> + <Project>{f209fae8-73f9-441b-97f4-0844a0279390}</Project> + <Name>Tango.TCC.BL</Name> + </ProjectReference> <ProjectReference Include="..\Modules\MachineStudio.Dispensers\Tango.MachineStudio.Dispensers.csproj"> <Project>{f69da3a8-f823-461e-87cf-a9275abc0b15}</Project> <Name>Tango.MachineStudio.Dispensers</Name> @@ -520,6 +524,14 @@ <Resource Include="Images\settings.png" /> </ItemGroup> <ItemGroup> + <Content Include="..\..\Build\TCC\Debug\Tango.TCC.ColorDetector.dll"> + <Link>Tango.TCC.ColorDetector.dll</Link> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </Content> + <Content Include="..\..\Build\TCC\Debug\Tango.TCC.ColorDetector.pdb"> + <Link>Tango.TCC.ColorDetector.pdb</Link> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </Content> <Resource Include="Images\firmware_upgrade.png" /> <Resource Include="Images\external-bridge-emulator.png" /> <EmbeddedResource Include="..\..\Versioning\ChangeLog.txt"> diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest b/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest index d72e75011..efc5f8179 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/app.manifest @@ -16,7 +16,7 @@ Remove this element if your application requires this virtualization for backwards compatibility. --> - <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> + <!--<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />--> </requestedPrivileges> </security> </trustInfo> diff --git a/Software/Visual_Studio/Referenced Assemblies/SMO/Microsoft.SqlServer.AzureStorageEnum.dll b/Software/Visual_Studio/Referenced Assemblies/SMO/Microsoft.SqlServer.AzureStorageEnum.dll Binary files differnew file mode 100644 index 000000000..3ae79ac4e --- /dev/null +++ b/Software/Visual_Studio/Referenced Assemblies/SMO/Microsoft.SqlServer.AzureStorageEnum.dll diff --git a/Software/Visual_Studio/Referenced Assemblies/SMO/Microsoft.SqlServer.AzureStorageEnum.xml b/Software/Visual_Studio/Referenced Assemblies/SMO/Microsoft.SqlServer.AzureStorageEnum.xml new file mode 100644 index 000000000..ba89bf93d --- /dev/null +++ b/Software/Visual_Studio/Referenced Assemblies/SMO/Microsoft.SqlServer.AzureStorageEnum.xml @@ -0,0 +1,238 @@ +<?xml version="1.0"?> +<doc> + <assembly> + <name>Microsoft.SqlServer.AzureStorageEnum</name> + </assembly> + <members> + <member name="T:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorage"> + <summary> + This class implements the AzureStore level of the enumerator(root level). This level + represents the Azure Storage server. Urns are this level are of the form: AzureStorage[@Name='accountname'] + The following properties are exposed. + Name: The account name associated with this server. + Urn: The Urn of this enumerator object. + Uri: The base URI of the storage account. + </summary> + </member> + <member name="T:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumObject"> + <summary> + <para> + This is the base class of all enumerator objects in the Azure Storage hierarchy. + This abstract class provides implementations of the abstract entities in EnumObject, + and defines a number of additional abstract entities for subclasses to implement. + In short, subclasses have two responsibilities: contributing to a filter (via + AddFilter) or fulfilling a request for data (via GetDataImpl). Only the final + level of a request will be asked to fetch data. All intermediate levels will, at most, + contribute to a filter. We support filtering on only two dimensions: blobName name and containerName name. + </para> + <para> + For example, suppose we're given the urn: AzureStorage/Container[@Name='mycontainer']/Blob[@Name='myblob'] + The will result in three calls to the GetData method in EnumObject, once for each level of the urn + (AzureStorage, Container, Blob, in that order). The first call will no nothing, since no filter is + given on the first level. The second call will add 'mycontainer' to the containerName filter. + The third call will add 'myblob' to the blobName filter, then will issue a request to the storage + server for the attributes of the blobName 'myblob' in containerName 'mycontainer'. + </para> + <para> + This class also provides some convenience methods and properties. + </para> + </summary> + </member> + <member name="M:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumObject.#ctor"> + <summary> + Initializes a new instance of the AzureStorageEnumObject class, and adds properties + common to all storage enumerator objects. + </summary> + </member> + <member name="M:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumObject.GetData(Microsoft.SqlServer.Management.Sdk.Sfc.EnumResult)"> + <summary> + Implementation of the GetData method from EnumObject. The algorithm here is: + If we're at the first level of the urn, we construct a new AzureStorageEnumResult object. + This object will be passed to all subsequent calls. Next, if we're not at the final level + of the urn, and our level has a filter, we add that filter to the AzureStorageEnumResult + object. Lastly, if we're at the final level of the enumerator, we fetch data from the + storage server and package it into a DataTable. + </summary> + <param name="parent">The result from the parent request.</param> + <returns>An EnumResult for the current level. If we're on the final level, the result will contain a DataTable.</returns> + </member> + <member name="M:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumObject.AddFilter(Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumResult)"> + <summary> + Adds a filter to the given AzureStorageEnumResult. This is called from GetData when + a level specifies a filter. + </summary> + <param name="er">The current enumerator result.</param> + </member> + <member name="M:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumObject.PopulateDataTable(Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumResult,System.Data.DataTable)"> + <summary> + Populates a data table with a response to the current request, based on the + given AzureStorageEnumResult (which keeps track of all the filters added + across all levels). + </summary> + <param name="er">The current enumerator result.</param> + <param name="table">The table to populate.</param> + </member> + <member name="M:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumObject.AddStringProperty(System.String,Microsoft.SqlServer.Management.Sdk.Sfc.ObjectPropertyUsages)"> + <summary> + Adds a string property with the given usages to this enumerator object. This property + will be nonexpensive. + </summary> + <param name="name">The name of the property.</param> + <param name="usages">The usages of the property.</param> + </member> + <member name="M:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumObject.AddProperty(System.String,System.String,Microsoft.SqlServer.Management.Sdk.Sfc.ObjectPropertyUsages)"> + <summary> + Adds a property with the given type and usages to this enumerator object. This property will + be nonexpensive. + </summary> + <param name="name">The name of the property.</param> + <param name="type">The name of the type of the property (e.g. "System.String")</param> + <param name="usages">The usages of the property.</param> + </member> + <member name="M:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumObject.AddProperty(System.String,System.String,Microsoft.SqlServer.Management.Sdk.Sfc.ObjectPropertyUsages,System.Boolean)"> + <summary> + Adds a property with the given type and usages to this enumerator object. + If the expensive parameter is set to true, this property will be marked as expensive. + </summary> + <param name="name">The name of the property.</param> + <param name="type">The name of the type of the property (e.g. "System.String")</param> + <param name="usages">The usages of the property.</param> + <param name="expensive">Determines wheter this property is marked as expensive or not.</param> + </member> + <member name="M:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumObject.PrepareDataTable(Microsoft.SqlServer.Management.Sdk.Sfc.Request)"> + <summary> + Creates a data table with columns determined by the fields in the given Request object. + </summary> + <param name="req">A request to the enumerator.</param> + <returns>An data table with zero rows, and a column for each requested field in the given Request object.</returns> + </member> + <member name="P:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumObject.ResultTypes"> + <summary> + Returns the result types supported by this + </summary> + </member> + <member name="P:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumObject.StorageConnectionInfo"> + <summary> + Gets the storage connection info passed to this enumerator. + </summary> + </member> + <member name="P:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumObject.BlobClient"> + <summary> + Gets the blobName client associated with the connection info passed to this enumerator. + </summary> + </member> + <member name="F:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorage.UrnSkeleton"> + <summary> + The parameterized Urn for objects at this level. + </summary> + </member> + <member name="M:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorage.AddFilter(Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumResult)"> + <summary> + There is no filter at this level, so this is a NOOP. + </summary> + <param name="result">The AzureStorageEnumResult object for this enumerator query.</param> + </member> + <member name="T:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumResult"> + <summary> + The class is used to build up filters as we travel down the enumerator query. + At the last node, we apply any filters in this object to the query we send + to the azure storage server. + </summary> + </member> + <member name="M:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumResult.#ctor"> + <summary> + Initializes a new instance of the AzureStorageEnumResult class, with empty filters. + </summary> + </member> + <member name="P:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumResult.ContainerFilters"> + <summary> + Gets a list of container names we want to get data for. + </summary> + </member> + <member name="P:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumResult.BlobFilters"> + <summary> + Gets a list of blob names we want to get data for. + </summary> + </member> + <member name="T:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.Blob"> + <summary> + This class implements the blobName level of the Azure Storage enumerator. This is the + third level of the hierarchy. Urns are this level are of the form: + AzureStorage[@Name='accountname']/Container[@Name='mycontainer']/Blob[@Name='myblob'] + The following properties are exposed. + Name: The containerName name. + Urn: The Urn of this enumerator object. + Uri: The base URI of the containerName. + LastModifiedUtc: The base URI of the storage account. + Size: The size of the containerName. + </summary> + </member> + <member name="F:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.Blob.UrnSkeleton"> + <summary> + The parameterized Urn for objects at this level. + </summary> + </member> + <member name="M:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.Blob.AddFilter(Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumResult)"> + <summary> + At this level, we add any blob Name filters to the given AzureStorageEnumResult. + </summary> + <param name="er">The AzureStorageEnumResult object to which we add the filter.</param> + </member> + <member name="M:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.Blob.PopulateDataTable(Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumResult,System.Data.DataTable)"> + <summary> + At this level, we are fetching blob data, honoring any blob filters and container filters that are present. + </summary> + <param name="er">The AzureStorageEnumResult for this query.</param> + <param name="table">The data table to populate.</param> + </member> + <member name="M:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.Blob.AddRow(System.Data.DataTable,Microsoft.SqlServer.Management.Sdk.Sfc.Request,Microsoft.WindowsAzure.StorageClient.CloudBlob)"> + <summary> + Add a row to the given data table representing the given blob. We only + add the properties specified in the given Request. + </summary> + <param name="table">The data table to add a row to.</param> + <param name="req">A request to this enumerator.</param> + <param name="blob">The blob to add to the given table.</param> + </member> + <member name="T:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.Container"> + <summary> + This class implements the containerName level of the Azure Storage enumerator. This is the + second level of the hierarchy. Urns are this level are of the form: AzureStorage[@Name='accountname']/Container[@Name='mycontainer'] + The following properties are exposed. + Name: The containerName name. + Urn: The Urn of this enumerator object. + Uri: The base URI of the containerName. + LastModifiedUtc: The base URI of the storage account. + </summary> + </member> + <member name="F:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.Container.UrnSkeleton"> + <summary> + The parameterized Urn for objects at this level. + </summary> + </member> + <member name="M:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.Container.AddFilter(Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumResult)"> + <summary> + At this level, we add any container Name filters present to the given AzureStorageEnumResult. + </summary> + <param name="er">The AzureStorageEnumResult for this query.</param> + </member> + <member name="M:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.Container.PopulateDataTable(Microsoft.SqlServer.Management.Smo.AzureStorageEnum.AzureStorageEnumResult,System.Data.DataTable)"> + <summary> + Retrieve data for this request. At this level, we are fetching containerName data. + We must honor any containerName filters present. If there is no filter, we fetch + data for all containers. + </summary> + <param name="er">The AzureStorageEnumResult for this query.</param> + <param name="table">The data table to populate.</param> + </member> + <member name="M:Microsoft.SqlServer.Management.Smo.AzureStorageEnum.Container.AddRow(System.Data.DataTable,Microsoft.SqlServer.Management.Sdk.Sfc.Request,Microsoft.WindowsAzure.StorageClient.CloudBlobContainer)"> + <summary> + Add a row to the given data table representing the given container. We only + add the properties specified in the given Request. + </summary> + <param name="table">The data table to add a row to.</param> + <param name="req">A request to this enumerator.</param> + <param name="container">The container to add to the given table.</param> + </member> + </members> +</doc> diff --git a/Software/Visual_Studio/TCC/Tango.TCC.BL/Tango.TCC.BL.csproj b/Software/Visual_Studio/TCC/Tango.TCC.BL/Tango.TCC.BL.csproj index 7d677edc3..6b973e4f8 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.BL/Tango.TCC.BL.csproj +++ b/Software/Visual_Studio/TCC/Tango.TCC.BL/Tango.TCC.BL.csproj @@ -75,6 +75,10 @@ <Compile Include="Web\LoginResponse.cs" /> </ItemGroup> <ItemGroup> + <Content Include="..\..\Build\TCC\Debug\Tango.TCC.ColorDetector.pdb"> + <Link>Tango.TCC.ColorDetector.pdb</Link> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </Content> <Content Include="..\Benchmarks\benchmarks_rgb_lab.csv"> <Link>TCC\benchmarks_rgb_lab.csv</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> @@ -115,7 +119,7 @@ <ItemGroup> <Content Include="..\..\Build\TCC\Debug\Tango.TCC.ColorDetector.dll"> <Link>Tango.TCC.ColorDetector.dll</Link> - <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> </Content> <Content Include="..\..\Build\TCC\Debug\Tango.TCC.LoadTestLib.dll"> <Link>Tango.TCC.LoadTestLib.dll</Link> diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorConvert.cpp b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorConvert.cpp index 2f162087a..c5830dbd7 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorConvert.cpp +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorConvert.cpp @@ -53,6 +53,13 @@ ColorConvert::ColorConvert(Illum D, C_RGB_XYZ_Lab SourceWhite) m_SourceWhite = SourceWhite; CAT_BradfordMat(); } +ColorConvert::ColorConvert(C_RGB_XYZ_Lab DestWhite, C_RGB_XYZ_Lab SourceWhite) +{ + m_ReferenceWhite.Set(DestWhite.Get_x(), DestWhite.Get_y(), DestWhite.Get_z()); + m_InvReferenceWhite.Set((1.0 / m_ReferenceWhite.Get_x()), (1.0 / m_ReferenceWhite.Get_y()), (1.0 / m_ReferenceWhite.Get_z())); + m_SourceWhite = SourceWhite; + CAT_BradfordMat(); +} ColorConvert::ColorConvert(Illum DDest, Illum DSource) { diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorConvert.h b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorConvert.h index 1529982ec..dae9c09a3 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorConvert.h +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorConvert.h @@ -18,6 +18,7 @@ class ColorConvert ColorConvert (void); ColorConvert (Illum D, C_RGB_XYZ_Lab SourceWhite); + ColorConvert(C_RGB_XYZ_Lab DestWhite, C_RGB_XYZ_Lab SourceWhite); ColorConvert(Illum DDest, Illum DSource); ColorConvert (const ColorConvert &rhs); ColorConvert &operator = (const ColorConvert &rhs); diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.cpp b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.cpp index fe92c0f4c..1df7a14df 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.cpp +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.cpp @@ -9,74 +9,12 @@ #include "bitmap_image.hpp" #include "Utils.h" #include <stdio.h> - -//-----------------------------FILE READING-------------------------------------------------------------- -///FOR FILE READING #include <fstream> #include <iostream> #include <sstream> #include <string> #include <vector> -using namespace std; -using namespace cv; - -typedef vector <double> record_t; -typedef vector <record_t> data_t; -//----------------------------------------------------------------------------- -// Let's overload the stream input operator to read a list of CSV fields (which a CSV record). -// Remember, a record is a list of doubles separated by commas ','. -istream& operator >> (istream& ins, record_t& record) -{ - // make sure that the returned record contains only the stuff we read now - record.clear(); - - // read the entire line into a string (a CSV record is terminated by a newline) - string line; - getline(ins, line); - - // now we'll use a stringstream to separate the fields out of the line - stringstream ss(line); - string field; - while (getline(ss, field, ',')) - { - // for each field we wish to convert it to a double - // (since we require that the CSV contains nothing but floating-point values) - stringstream fs(field); - double f = 0.0; // (default value is 0.0) - fs >> f; - - // add the newly-converted field to the end of the record - record.push_back(f); - } - - // Now we have read a single line, converted into a list of fields, converted the fields - // from strings to doubles, and stored the results in the argument record, so - // we just return the argument stream as required for this kind of input overload function. - return ins; -} - -//----------------------------------------------------------------------------- -// Let's likewise overload the stream input operator to read a list of CSV records. -// This time it is a little easier, just because we only need to worry about reading -// records, and not fields. -istream& operator >> (istream& ins, data_t& data) -{ - // make sure that the returned data only contains the CSV data we read here - data.clear(); - - // For every record we can read from the file, append it to our resulting data - record_t record; - while (ins >> record) - { - data.push_back(record); - } - - // Again, return the argument stream as required for this kind of input stream overload. - return ins; -} - - -//-----------------------------FILE READING-------------------------------------------------------------- +#include "ColorDetectionMirta.h" ColorDetection::ColorDetection() { @@ -87,284 +25,8 @@ ColorDetection::~ColorDetection() } -#define RAND_BYTE (rand() % 256) - - -bool ColorDetection::DetectColor( - int caliberationTargetVersion, //Version of the sample target version (i.e the colored box) - int appVersion, // cellular version - const std::vector<COLORREF>& caliberationColors, - COLORREF sampleColor, - int& outAlgoVersion, - COLORREF& outDetectedColor, - std::string& outErrorString) -{ - data_t data; //Data that we receive from the mobile phone (caliberationColors) is a list of colors (9X9 i.e. 81 points) - data_t benchmarkdata; //this is the benchmark data set in other words the comparing table or LUT, this is a single non changing color matrix - data_t benchmarkdataLab; //Lab data of benchmark data based on measurements of the printed color chart - - //BENCHMARK DATASET-------------------------------------------------------------------------- - //Read the color benchmark it into data - this data should be exactly the data on the color chart - //this should be a one time operation, - //taking raw data in RGB from the image - this is a single non changing data - - outErrorString = "Started Detection..."; - - ifstream Benchmarkfile("D:\\home\\site\\wwwroot\\bin\\BENCHMARK.csv"); - Benchmarkfile >> benchmarkdata; - - if (!Benchmarkfile.eof()) { - cout << "Benchmark CSV file not found!\n"; - outErrorString = "Benchmark CSV file not found!\n"; - outDetectedColor = RGB(0, 0, 0); - return false; - } - Benchmarkfile.close(); - //Benchmark date is completely filled - //-------------------------------------------------------------------------- - int numberofrecords = benchmarkdata.size(); //i.e. 80 records in our case - - //Read BenchMarkDataLab - ifstream BenchmarkfileLab("D:\\home\\site\\wwwroot\\bin\\BenchMarkLab.csv"); - BenchmarkfileLab >> benchmarkdataLab; - - - if (!BenchmarkfileLab.eof()) - { - cout << "Benchmark data Lab CSV file not found!\n"; - outErrorString = "Benchmark data Lab CSV file not found!\n"; - outDetectedColor = RGB(2, 2, 2); - return false; - } - BenchmarkfileLab.close(); - //BenchmarkfileLab is completely filled - //-------------------------------------------------------------------------- - - unsigned columnsbenchmark = 0; - unsigned columnsdata = 0; - for (unsigned n = 0; n < numberofrecords; n++) - if (columnsbenchmark < benchmarkdata[n].size()) - columnsbenchmark = benchmarkdata[n].size(); - //read sampled data - for (unsigned n = 0; n < numberofrecords; n++) //110 records - { - record_t record; - record.push_back(GetBValue(caliberationColors[n])); - record.push_back(GetGValue(caliberationColors[n])); - record.push_back(GetRValue(caliberationColors[n])); - data.push_back(record); - } - - for (unsigned n = 0; n < numberofrecords; n++) //RGB of what is read - if (columnsdata < data[n].size()) - columnsdata = data[n].size(); - - - outErrorString = "Passed read sampled data..."; - - //-------------------------------------------------------------------------- - //We have now both the data and the benchmark and benchmarkdataLab in their appropriate formats - - //Eliminate fiducials from list, - //fiducials are placed at 0, 8, 72 - //Sampled data is placed at 80 - //int fid_index[4] = { 0, 8, 72, 80 }; - int fid_index[5] = { 0, 10, 99,101, 109 }; - int i_nonpInd = sizeof(fid_index) / sizeof(int); - //calculate distance to gray values matrix - int BMcols = 11; - int BMrows = 10; - if (numberofrecords != BMcols * BMrows) - return(false); - int m_interpPoints = 10; - MatrixXi m_dist2grayInd(numberofrecords - i_nonpInd, m_interpPoints); - VectorXi m_dist2GrayIndSample(m_interpPoints); - - DistanceMatrix(BMrows, BMcols, fid_index, i_nonpInd, m_dist2grayInd, m_dist2GrayIndSample); - // - /*FILE *fp; - fopen_s(&fp, "C:\\Mirta\\DistMat.txt", "w"); - for (int i = 0; i < m_dist2grayInd.rows(); ++i) - { - fprintf(fp, "%d\t", i); - for (int j = 0; j < m_dist2grayInd.cols(); ++j) - fprintf(fp, "%d\t", m_dist2grayInd(i, j)); - fprintf(fp, "\n"); - } - fprintf(fp, "s\t"); - for (int j = 0; j < m_dist2grayInd.cols(); ++j) - fprintf(fp, "%d\t", m_dist2GrayIndSample(j)); - fprintf(fp, "\n"); - fclose(fp); */ - // - MatrixXd GroundTruthData(numberofrecords - i_nonpInd, columnsbenchmark); - MatrixXd GroundTruthDataLab(numberofrecords - i_nonpInd, columnsbenchmark); - MatrixXd CamData(numberofrecords - i_nonpInd, columnsbenchmark); - VectorXd SampleColor(columnsbenchmark); - int ind = -1; - for (int i = 0; i < numberofrecords; ++i) - { - if (i != fid_index[0] && i != fid_index[1] && i != fid_index[2] && i != fid_index[3] && i != fid_index[4]) - { - ind++; - for (int j = 0; j < (int)columnsbenchmark; ++j) - { - //distance Matrix is already cleaned of fiducials and Sample - GroundTruthData(ind, j) = benchmarkdata[i][j]; - GroundTruthDataLab(ind, j) = benchmarkdataLab[i][j]; - CamData(ind, j) = data[i][j]; - } - } - } - // -/* FILE *fp1; - fopen_s(&fp1, "C:\\Mirta\\GTData.txt", "w"); - FILE *fp2; - fopen_s(&fp2, "C:\\Mirta\\GTLabData.txt", "w"); - FILE *fp3; - fopen_s(&fp3, "C:\\Mirta\\CamData.txt", "w"); - for (int i = 0; i < GroundTruthData.rows(); ++i) - { - fprintf(fp1, "%d\t", i); - fprintf(fp2, "%d\t", i); - fprintf(fp3, "%d\t", i); - for (int j = 0; j < GroundTruthData.cols(); ++j) - { - fprintf(fp1, "%f\t", GroundTruthData(i, j)); - fprintf(fp2, "%f\t", GroundTruthDataLab(i, j)); - fprintf(fp3, "%f\t", CamData(i, j)); - } - fprintf(fp1, "\n"); - fprintf(fp2, "\n"); - fprintf(fp3, "\n"); - } */ - // - for (int i = 0; i < (int)columnsbenchmark; ++i) - SampleColor(i) = data[fid_index[3]][i]; - // - /* fprintf(fp3, "s\t"); - for (int j = 0; j < GroundTruthData.cols(); ++j) - fprintf(fp3, "%f\t", SampleColor(j)); - fprintf(fp3, "\n"); - fclose(fp1); - fclose(fp2); - fclose(fp3); */ - // - Detect DetectSampledColor; - char *outErrorMsg = new char[1024]; - int retVal = DetectSampledColor.Init(GroundTruthData, GroundTruthDataLab, CamData, SampleColor, - m_dist2grayInd, m_dist2GrayIndSample, outErrorMsg); - - if (retVal < 0) - { - printf("Failed to initialize data\n"); - outDetectedColor = RGB(3, 3, 3); - return false; - } - VectorXd outResult(3); - VectorXd outResultLab(3); - - int ret = DetectSampledColor.MatchSampleColor(outResult, outResultLab, outErrorMsg); - - outDetectedColor = RGB(BYTE(round(outResult(0))), BYTE(round(outResult(1))), BYTE(round(outResult(2)))); - // outDetectedColor = RGB(4, 4, 4); - //Calculate rSquare and RMSE - double **RGBEst = new double*[numberofrecords - i_nonpInd]; - double **LabEst = new double*[numberofrecords - i_nonpInd]; - double **RespVec = new double*[numberofrecords - i_nonpInd]; - double **RespVecLab = new double*[numberofrecords - i_nonpInd]; - double SumME[3] = { 0.0, 0.0, 0.0 }; - double MeanBM[3] = { 0.0, 0.0, 0.0 }; - double SumSQBM[3] = { 0.0, 0.0, 0.0 }; - double SumMELab[3] = { 0.0, 0.0, 0.0 }; - double MeanBMLab[3] = { 0.0, 0.0, 0.0 }; - double SumSQBMLab[3] = { 0.0, 0.0, 0.0 }; - //FILE *fp; - //fp = fopen("C:\\Mirta\\Rsq.txt", "w"); - //fopen_s(&fp, "C:\\Mirta\\Rsq.txt", "w"); - MatrixXd RespVecLabM(numberofrecords, 3); - RespVecLabM = DetectSampledColor.GetBenchMarkDataLabRel(); - int ndist = m_dist2GrayIndSample.size(); - for (int i = 0; i < numberofrecords - i_nonpInd; ++i) - { - RGBEst[i] = new double[3]; - LabEst[i] = new double[3]; - RespVec[i] = new double[3]; - RespVecLab[i] = new double[3]; - for (int j = 0; j < (int)columnsbenchmark; ++j) - { - SampleColor(j) = CamData(i, j); - RespVec[i][j] = GroundTruthData(i, j); - RespVecLab[i][j] = RespVecLabM(i, j); - } - for (int j = 0; j < ndist; ++j) - m_dist2GrayIndSample(j) = m_dist2grayInd(i, j); - - retVal = DetectSampledColor.Init(GroundTruthData, GroundTruthDataLab, CamData, SampleColor, - m_dist2grayInd, m_dist2GrayIndSample, outErrorMsg); - ret = DetectSampledColor.MatchSampleColor(outResult, outResultLab, outErrorMsg); - for (int j = 0; j < 3; ++j) - { - RGBEst[i][j] = outResult(j); - LabEst[i][j] = outResultLab(j); - SumME[j] += (RGBEst[i][j] - RespVec[i][j])*(RGBEst[i][j] - RespVec[i][j]); - SumMELab[j] += (LabEst[i][j] - RespVecLab[i][j])*(LabEst[i][j] - RespVecLab[i][j]); - MeanBM[j] += RespVec[i][j]; - MeanBMLab[j] += RespVecLab[i][j]; - SumSQBM[j] += RespVec[i][j] * RespVec[i][j]; - SumSQBMLab[j] += RespVecLab[i][j] * RespVecLab[i][j]; - } - //fprintf(fp, "%f\t%f\t%f\t", RGBEst[i][0], RGBEst[i][1], RGBEst[i][2]); - //fprintf(fp, "%f\t%f\t%f\t", LabEst[i][0], LabEst[i][1], LabEst[i][2]); - //fprintf(fp, "%f\t%f\t%f\t", RespVec[i][0], RespVec[i][1], RespVec[i][2]); - //fprintf(fp, "%f\t%f\t%f\n", RespVecLab[i][0], RespVecLab[i][1], RespVecLab[i][2]); - } - for (int j = 0; j < 3; ++j) - { - MeanBM[j] /= (numberofrecords - i_nonpInd); - MeanBMLab[j] /= (numberofrecords - i_nonpInd); - } - - double RSquare = 0.0; - double RSquareLab = 0.0; - double SumTop = SumME[0] + SumME[1] + SumME[2]; - double SumTopLab = SumMELab[0] + SumMELab[1] + SumMELab[2]; - double SumBot1 = SumSQBM[0] + SumSQBM[1] + SumSQBM[2]; - double SumBot1Lab = SumSQBMLab[0] + SumSQBMLab[1] + SumSQBMLab[2]; - double SumBot2 = (numberofrecords - i_nonpInd)*(MeanBM[0] * MeanBM[0] + MeanBM[1] * MeanBM[1] + MeanBM[2] * MeanBM[2]); - double SumBot2Lab = (numberofrecords - i_nonpInd)*(MeanBMLab[0] * MeanBMLab[0] + MeanBMLab[1] * MeanBMLab[1] + MeanBMLab[2] * MeanBMLab[2]); - RSquare = 1 - (SumTop / (SumBot1 - SumBot2)); - RSquareLab = 1 - (SumTopLab / (SumBot1Lab - SumBot2Lab)); - if (RSquare < 0) - RSquare = 0.0; - if (RSquare > 1) - RSquare = 1.0; - double rmse = sqrt(SumTop / (numberofrecords - i_nonpInd)); - double rmseLab = sqrt(SumTopLab / (numberofrecords - i_nonpInd)); - //fprintf(fp, "%f\t%f\t%f\t%f\n", RSquare, RSquareLab, rmse, rmseLab); - for (int i = 0; i < (numberofrecords - i_nonpInd); ++i) - { - delete RGBEst[i]; - delete LabEst[i]; - delete RespVec[i]; - delete RespVecLab[i]; - } - - delete[] RGBEst; - delete[] LabEst; - delete[] RespVec; - delete[] RespVecLab; - delete[] outErrorMsg; - //fclose(fp); - - outAlgoVersion = 4; //Jan 9, 2018 - - outErrorString = "Done"; - - return true; -} - size_t ColorDetection::DetectColorNew(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer) +//includes CallDettectColor (old version) { try { @@ -464,14 +126,19 @@ size_t ColorDetection::DetectColorNew(uint8_t * input_buffer, size_t input_buffe } //Put original target color. - detectionOutput->rawcolor = initDetectionColor(target_mean.val[2], target_mean.val[1], target_mean.val[0]); + detectionOutput->rawcolor = initDetectionColor((int)target_mean.val[2], (int)target_mean.val[1], (int)target_mean.val[0]); //Get benchmarks... detectionInput->benchmarks[0]->red; detectionInput->benchmarks[0]->l; //Put processed target color. - detectionOutput->processedcolor = initDetectionColor(target_mean.val[2] + 10, target_mean.val[1] + 10, target_mean.val[0] + 10); + + ColorDetectionMirta mirtaDetection; + //ColorDetectionMirta was ColorDetection + // Detect was DetectColor + DetectionColor* result = mirtaDetection.CDetect(detectionInput->benchmarks, means, detectionInput->columns, detectionInput->rows, detectionInput->targetindex); + detectionOutput->processedcolor = result; detectionOutput->has_number = true; detectionOutput->number = detectionInput->number + 10; @@ -549,118 +216,3 @@ DetectionColor* ColorDetection::initDetectionColor(int r, int g, int b) return color; } -void ColorDetection::DistanceMatrix(int rows, int cols, int *nonpInd, int i_nonpInd, MatrixXi &m_dist2grayInd, VectorXi &m_dist2GrayIndSample) -{ - int i, j, k, l; - int indk1, indk2; - int totSize = cols * rows; - MatrixXi aa(rows, cols); - for (int i = 0; i < rows; i++) - for (j = 0; j < cols; j++) - aa(i, j) = i * cols + j; - - // int i_nonpInd = sizeof(nonpInd); - MatrixXd dist2gray(totSize, totSize); - dist2gray.setOnes(); - dist2gray = -dist2gray; - - //grays are positioned at card borders - for (i = 0; i < rows; i++) - for (j = 0; j < cols; j++) - { - for (k = 0; k < rows; k++) - { - indk1 = aa(k, 0); - indk2 = aa(k, cols - 1); - dist2gray(aa(i, j), indk1) = sqrt((i - k)*(i - k) + (j*j)); - dist2gray(aa(i, j), indk2) = sqrt((i - k)*(i - k) + (j - (cols - 1))*(j - (cols - 1))); - } - for (l = 0; l < cols; l++) - { - indk1 = aa(0, l); - indk2 = aa(rows - 1, l); - dist2gray(aa(i, j), indk1) = sqrt((i*i) + (j - l)*(j - l)); - dist2gray(aa(i, j), indk2) = sqrt((i - (rows - 1))*(i - (rows - 1)) + (j - l)*(j - l)); - } - } - - //Eliminate corners and Target index - VectorXd atmp(totSize); - VectorXd btmp(totSize); - - VectorXi atmpInd(totSize); - VectorXi btmpInd(totSize); - VectorXi ctmpInd(totSize); - VectorXi indb(totSize); - int tmpInd = 0; - int nElimFid = 0; - VectorXi PtType(totSize); - PtType.setZero(); - for (i = 0; i < i_nonpInd; ++i) - PtType(nonpInd[i]) = 1; - PtType(nonpInd[3]) = 2; - int PtInd = -1; - std::vector<VectorPair> IndVal; - for (i = 0; i < totSize; ++i) - { - if (PtType(i) == 0 || PtType(i) == 2) - { - if (PtType(i) == 0) - PtInd += 1; - tmpInd = -1; - for (j = 0; j < totSize; ++j) - { - if (dist2gray(i, j) > -1) - { - tmpInd++; - atmp(tmpInd) = dist2gray(i, j); - atmpInd(tmpInd) = j; - } - } - nElimFid = -1; - //eliminate fiducials and target, store in btmp - for (j = 0; j < tmpInd + 1; ++j) - { - if (atmpInd(j) >= 0 && PtType(atmpInd(j)) == 0) - { - nElimFid++; - btmp(nElimFid) = atmp(j); - btmpInd(nElimFid) = atmpInd(j); - } - } - - if (nElimFid > -1) - { - // shift indices to compensate for corners and target - IndVal.resize(nElimFid + 1); - for (int j = 0; j < nElimFid + 1; ++j) - { - IndVal[j].m_ID = j; - IndVal[j].m_val = btmp(j); - } - std::stable_sort(IndVal.begin(), IndVal.end(), ByDouble()); - //keep the first 10 indices - for (j = 0; j < 10; ++j) - { - ctmpInd(j) = btmpInd(IndVal[j].m_ID); - if (ctmpInd(j) >= nonpInd[0] && ctmpInd(j) < nonpInd[1]) - ctmpInd(j) = ctmpInd[j] - 1; - else if (ctmpInd(j) >= nonpInd[1] && ctmpInd(j) < nonpInd[2]) - ctmpInd(j) = ctmpInd(j) - 2; - else if (ctmpInd(j) >= nonpInd[2] && ctmpInd(j) < nonpInd[3]) - ctmpInd[j] = ctmpInd[j] - 3; - else if (ctmpInd(j) >= nonpInd[3] && ctmpInd(j) < nonpInd[4]) - ctmpInd(j) = ctmpInd(j) - 4; - else - ctmpInd(j) = ctmpInd(j) - 5; - if (PtType(i) == 0) - m_dist2grayInd(PtInd, j) = ctmpInd(j); - else - m_dist2GrayIndSample(j) = ctmpInd(j); - } - } - - } - } -} - diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.h b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.h index e9d4c2da7..56b008a32 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.h +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.h @@ -1,26 +1,12 @@ #pragma once -#include "Windows.h" #include "DetectionColor.pb-c.h" #include <string> #include <vector> -#include <Eigen/Dense> -using Eigen::MatrixXd; -using Eigen::VectorXd; -using Eigen::MatrixXi; -using Eigen::VectorXi; -#include "ConsolidateData.h" -#ifdef __ColorDetectionDll__ -#define ColorDetectionApi __declspec(dllexport) -#else -#define ColorDetectionApi __declspec(dllimport) -#endif - -class ColorDetectionApi ColorDetection +class ColorDetection { private: - void DistanceMatrix(int rows, int cols, int *nonpInd, int i_nonpInd, MatrixXi &dist2grayInd, VectorXi &dist2GrayIndSample); bool isRectFiducial(int index, int columns, int rows); DetectionColor* initDetectionColor(int r, int g, int b); int m_totSize; @@ -28,15 +14,6 @@ private: public: ColorDetection(); ~ColorDetection(); - bool DetectColor( - int caliberationTargetVersion, - int appVersion, - const std::vector<COLORREF>& caliberationColors, - COLORREF sampleColor, - int& outAlgoVersion, - COLORREF& outDetectedColor, - std::string& outErrorString); - size_t DetectColorNew(uint8_t * input_buffer, size_t input_buffer_size, uint8_t *& output_buffer); }; diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetectionAlgorithm.cpp b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetectionAlgorithm.cpp deleted file mode 100644 index 2729cd910..000000000 --- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetectionAlgorithm.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// ColorDetectionAlgorithm.cpp : Defines the entry point for the console application. -// - -#include "stdafx.h" -#include "ColorDetection.h" - - -extern "C" bool __declspec(dllexport) __cdecl CallDetectColor(int targetVersion, int appVersion, - int calibrationCount, int calibration[], int sampleColor, - int& algoVersion, int& detectedColorI, int errorMessageSize, wchar_t* errorMessage) -{ - std::vector<COLORREF> caliberationSamples; - caliberationSamples.resize(calibrationCount); - for (int i = 0; i < calibrationCount; ++i) caliberationSamples[i] = calibration[i]; - COLORREF detectedColor = 0; - std::string errorString; - - ColorDetection detectionAlgorithm; - auto result = detectionAlgorithm.DetectColor(targetVersion, appVersion, caliberationSamples, sampleColor, algoVersion, detectedColor, errorString); - - detectedColorI = detectedColor; - ZeroMemory(errorMessage, errorMessageSize*sizeof(wchar_t)); - MultiByteToWideChar(CP_UTF8, 0, errorString.c_str(), -1, errorMessage, errorMessageSize-1); - return result; -} diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetectionMirta.cpp b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetectionMirta.cpp new file mode 100644 index 000000000..159935276 --- /dev/null +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetectionMirta.cpp @@ -0,0 +1,334 @@ +#include "ColorDetectionMirta.h" +#include "ColorDetection.h" +#include "Detect.h" + +ColorDetectionMirta::ColorDetectionMirta() +{ +} + + +ColorDetectionMirta::~ColorDetectionMirta() +{ +} + +DetectionColor* ColorDetectionMirta::CDetect(DetectionBenchmark** benchmarks, std::vector<cv::Scalar> means, int nCols, int nRows, int targetIndex) +{ + //insert Data + MatrixXd CalibrationSamples(nCols*nRows, 3); + MatrixXi Benchmark_RGB(nCols*nRows, 3); + MatrixXd Benchmark_Lab(nCols*nRows, 3); + int nTot = nCols * nRows; + //means are BGR, have to be inverted + for (int i = 0; i < nTot; ++i) + { + for (int j = 0; j < 3; ++j) + CalibrationSamples(i, j) = means[i][2-j]; + Benchmark_RGB(i, 0) = benchmarks[i]->red; + Benchmark_RGB(i, 1) = benchmarks[i]->green; + Benchmark_RGB(i, 2) = benchmarks[i]->blue; + Benchmark_Lab(i, 0) = benchmarks[i]->l; + Benchmark_Lab(i, 1) = benchmarks[i]->a; + Benchmark_Lab(i, 2) = benchmarks[i]->b; + } + //VectorXd SampleColor(3); + VectorXd DetectedColor(3); + VectorXd SampleColor(3); + for (int j = 0; j < 3; ++j) + SampleColor(j) = CalibrationSamples(targetIndex, j); + //processing goes here + + // calculate distance to gray values matrix + + m_interpPoints = 7; + MatrixXi m_dist2grayInd(nTot - 5, m_interpPoints); + VectorXi m_dist2GrayIndSample(m_interpPoints); + //find gray elements' placement on both cards, includes fiducials position + int nGrays = 2 * ((nCols - 2) + nRows); + VectorXi grayInd(nGrays); + int indG = -1; + for (int i = 0; i < nTot; ++i) + { + if ((Benchmark_RGB(i, 0) == Benchmark_RGB(i, 1)) & (Benchmark_RGB(i, 1) == Benchmark_RGB(i, 2))) + { + indG++; + grayInd(indG) = i; + } + } + + DistanceMatrix(nRows, nCols, m_dist2grayInd, m_dist2GrayIndSample, grayInd, targetIndex); + + int BMCols = Benchmark_RGB.cols(); + MatrixXd GroundTruthData(nTot - 5, BMCols); + MatrixXd GroundTruthDataLab(nTot - 5, BMCols); + MatrixXd CamData(nTot - 5, BMCols); + + int ind = -1; + int fidpos[] = { 0, nCols - 1, (nRows - 1)*nCols, nRows*nCols - 1 }; + for (int i = 0; i < nTot; ++i) + { + if (i != fidpos[0] && i != fidpos[1] && i != fidpos[2] && i != fidpos[3] && i != targetIndex) + { + ind++; + for (int j = 0; j < (int)BMCols; ++j) + { + //distance Matrix is already cleaned of fiducials and Sample + GroundTruthData(ind, j) = Benchmark_RGB(i, j); + GroundTruthDataLab(ind, j) = Benchmark_Lab(i, j); + CamData(ind, j) = CalibrationSamples(i, j); + } + } + } + + for (int i = 0; i < (int)BMCols; ++i) + SampleColor(i) = CalibrationSamples(targetIndex, i); + + Detect DetectSampledColor; + char *outErrorMsg = new char[1024]; + int retVal = DetectSampledColor.Init(GroundTruthData, GroundTruthDataLab, CamData, SampleColor, + m_dist2grayInd, m_dist2GrayIndSample, outErrorMsg); + DetectionColor *retColor; + if (retVal < 0) + { + printf("Failed to initialize data\n"); + retColor = initDetectionColor(3, 3, 3); + return false; + } + VectorXd outResult(3); + VectorXd outResultLab(3); + + int ret = DetectSampledColor.MatchSampleColor(outResult, outResultLab, outErrorMsg); + //This is the output + retColor = initDetectionColor(BYTE(round(outResult(0))), BYTE(round(outResult(1))), BYTE(round(outResult(2)))); + + //Calculate rSquare and RMSE - while debugging only +#ifdef DEBUG + double **RGBEst = new double*[nTot -5]; + double **LabEst = new double*[nTot - 5]; + double **RespVec = new double*[nTot -5]; + double **RespVecLab = new double*[nTot - 5]; + double SumME[3] = { 0.0, 0.0, 0.0 }; + double MeanBM[3] = { 0.0, 0.0, 0.0 }; + double SumSQBM[3] = { 0.0, 0.0, 0.0 }; + double SumMELab[3] = { 0.0, 0.0, 0.0 }; + double MeanBMLab[3] = { 0.0, 0.0, 0.0 }; + double SumSQBMLab[3] = { 0.0, 0.0, 0.0 }; + FILE *fp; + fopen_s(&fp, "C:\\Mirta\\Rsq.txt", "w"); + MatrixXd RespVecLabM(nTot, 3); + RespVecLabM = DetectSampledColor.GetBenchMarkDataLabRel(); + int ndist = m_dist2GrayIndSample.size(); + for (int i = 0; i < nTot - 5; ++i) + { + RGBEst[i] = new double[3]; + LabEst[i] = new double[3]; + RespVec[i] = new double[3]; + RespVecLab[i] = new double[3]; + for (int j = 0; j < (int)3; ++j) + { + SampleColor(j) = CamData(i, j); + RespVec[i][j] = GroundTruthData(i, j); + RespVecLab[i][j] = RespVecLabM(i, j); + } + for (int j = 0; j < ndist; ++j) + m_dist2GrayIndSample(j) = m_dist2grayInd(i, j); + + retVal = DetectSampledColor.Init(GroundTruthData, GroundTruthDataLab, CamData, SampleColor, + m_dist2grayInd, m_dist2GrayIndSample, outErrorMsg); + ret = DetectSampledColor.MatchSampleColor(outResult, outResultLab, outErrorMsg); + for (int j = 0; j < 3; ++j) + { + RGBEst[i][j] = outResult(j); + LabEst[i][j] = outResultLab(j); + SumME[j] += (RGBEst[i][j] - RespVec[i][j])*(RGBEst[i][j] - RespVec[i][j]); + SumMELab[j] += (LabEst[i][j] - RespVecLab[i][j])*(LabEst[i][j] - RespVecLab[i][j]); + MeanBM[j] += RespVec[i][j]; + MeanBMLab[j] += RespVecLab[i][j]; + SumSQBM[j] += RespVec[i][j] * RespVec[i][j]; + SumSQBMLab[j] += RespVecLab[i][j] * RespVecLab[i][j]; + } + fprintf(fp, "%f\t%f\t%f\t", RGBEst[i][0], RGBEst[i][1], RGBEst[i][2]); + fprintf(fp, "%f\t%f\t%f\t", LabEst[i][0], LabEst[i][1], LabEst[i][2]); + fprintf(fp, "%f\t%f\t%f\t", RespVec[i][0], RespVec[i][1], RespVec[i][2]); + fprintf(fp, "%f\t%f\t%f\n", RespVecLab[i][0], RespVecLab[i][1], RespVecLab[i][2]); + } + for (int j = 0; j < 3; ++j) + { + MeanBM[j] /= (numberofrecords - i_nonpInd); + MeanBMLab[j] /= (numberofrecords - i_nonpInd); + } + + double RSquare = 0.0; + double RSquareLab = 0.0; + double SumTop = SumME[0] + SumME[1] + SumME[2]; + double SumTopLab = SumMELab[0] + SumMELab[1] + SumMELab[2]; + double SumBot1 = SumSQBM[0] + SumSQBM[1] + SumSQBM[2]; + double SumBot1Lab = SumSQBMLab[0] + SumSQBMLab[1] + SumSQBMLab[2]; + double SumBot2 = (nTot - 5)*(MeanBM[0] * MeanBM[0] + MeanBM[1] * MeanBM[1] + MeanBM[2] * MeanBM[2]); + double SumBot2Lab = (nTot - 5)*(MeanBMLab[0] * MeanBMLab[0] + MeanBMLab[1] * MeanBMLab[1] + MeanBMLab[2] * MeanBMLab[2]); + RSquare = 1 - (SumTop / (SumBot1 - SumBot2)); + RSquareLab = 1 - (SumTopLab / (SumBot1Lab - SumBot2Lab)); + if (RSquare < 0) + RSquare = 0.0; + if (RSquare > 1) + RSquare = 1.0; + double rmse = sqrt(SumTop / (nTot - 5)); + double rmseLab = sqrt(SumTopLab / (nTot - 5); + fprintf(fp, "%f\t%f\t%f\t%f\n", RSquare, RSquareLab, rmse, rmseLab); + for (int i = 0; i < (nTot - 5); ++i) + { + delete RGBEst[i]; + delete LabEst[i]; + delete RespVec[i]; + delete RespVecLab[i]; + } + + delete[] RGBEst; + delete[] LabEst; + delete[] RespVec; + delete[] RespVecLab; + delete[] outErrorMsg; + fclose(fp); + #endif + return retColor; +} + +DetectionColor* ColorDetectionMirta::initDetectionColor(int r, int g, int b) +{ + DetectionColor* color = (DetectionColor*)malloc(sizeof(DetectionColor)); + detection_color__init(color); + color->has_r = true; + color->has_g = true; + color->has_b = true; + color->r = r; + color->g = g; + color->b = b; + return color; +} + +void ColorDetectionMirta::DistanceMatrix(int nRows, int nCols, MatrixXi &m_dist2grayInd, VectorXi &m_dist2GrayIndSample, VectorXi GrayInd, int TargetInd) +{ + int i, j, k; + int totSize = nCols * nRows; + MatrixXi aa(nRows, nCols); + for (i = 0; i < nRows; i++) + for (j = 0; j < nCols; j++) + aa(i, j) =i * nCols + j; + + // int i_nonpInd = sizeof(nonpInd); + MatrixXd dist2gray(totSize, totSize); + dist2gray.setOnes(); + dist2gray = -dist2gray; + int nGray = GrayInd.size(); + int iG, jG, iB, jB; + + //grays are positioned at GrayInd + for (i = 0; i < totSize; i++) + { + iB = (int)floor(i / nCols); + jB = (int)i - iB * nCols; + for (k = 0; k < nGray; k++) + { + iG = (int)floor(GrayInd(k) / nCols); + jG = GrayInd(k) - iG * nCols; + dist2gray(i, GrayInd(k)) = sqrt((iB - iG)*(iB - iG) + (jB - jG)*(jB - jG)); + } + } + + //Eliminate corners and Target index + //make sure fiducial indices and target are sorted + int fidpos[] = { 0, nCols - 1, (nRows - 1)*nCols, nRows*nCols - 1, TargetInd }; + std::vector<VectorPair> fidVal; + int nfid = sizeof(fidpos) / sizeof(int); + fidVal.resize(nfid); + for (int j = 0; j < nfid; ++j) + { + fidVal[j].m_ID = j; + fidVal[j].m_val = (double)fidpos[j]; + } + std::stable_sort(fidVal.begin(), fidVal.end(), ByDouble()); + for (int j = 0; j < nfid; ++j) + { + fidpos[j] = (int)fidVal[j].m_val; + } + + VectorXd atmp(totSize); + VectorXd btmp(totSize); + + VectorXi atmpInd(totSize); + VectorXi btmpInd(totSize); + VectorXi ctmpInd(totSize); + VectorXi indb(totSize); + int tmpInd = 0; + int nElimFid = 0; + VectorXi PtType(totSize); + PtType.setZero(); + for (i = 0; i < nfid; ++i) + { + PtType(fidpos[i]) = 1; + if (fidpos[i] == TargetInd) + PtType(fidpos[i]) = 2; + } + + int PtInd = -1; + std::vector<VectorPair> IndVal; + for (i = 0; i < totSize; ++i) + { + if (PtType(i) == 0 || PtType(i) == 2) + { + if (PtType(i) == 0) + PtInd += 1; + tmpInd = -1; + for (j = 0; j < totSize; ++j) + { + if (dist2gray(i, j) > -1) + { + tmpInd++; + atmp(tmpInd) = dist2gray(i,j); + atmpInd(tmpInd) = j; + } + } + nElimFid = -1; + //eliminate fiducials and target, store in btmp + for (j = 0; j < tmpInd + 1; ++j) + { + if (atmpInd(j) >= 0 && PtType(atmpInd(j)) == 0) + { + nElimFid++; + btmp(nElimFid) = atmp(j); + btmpInd(nElimFid) = atmpInd(j); + } + } + + if (nElimFid > -1) + { + // shift indices to compensate for corners and target + IndVal.resize(nElimFid + 1); + for (int j = 0; j < nElimFid + 1; ++j) + { + IndVal[j].m_ID = j; + IndVal[j].m_val = btmp(j); + } + std::stable_sort(IndVal.begin(), IndVal.end(), ByDouble()); + //keep the first 10 indices + for (j = 0; j < m_interpPoints; ++j) + { + ctmpInd(j) = btmpInd(IndVal[j].m_ID); + if (ctmpInd(j) >= fidpos[0] && ctmpInd(j) < fidpos[1]) + ctmpInd(j) = ctmpInd[j] - 1; + else if (ctmpInd(j) >= fidpos[1] && ctmpInd(j) < fidpos[2]) + ctmpInd(j) = ctmpInd(j) - 2; + else if (ctmpInd(j) >= fidpos[2] && ctmpInd(j) < fidpos[3]) + ctmpInd[j] = ctmpInd[j] - 3; + else if (ctmpInd(j) >= fidpos[3] && ctmpInd(j) < fidpos[4]) + ctmpInd(j) = ctmpInd(j) - 4; + else + ctmpInd(j) = ctmpInd(j) - 5; + if (PtType(i) == 0) + m_dist2grayInd(PtInd, j) = ctmpInd(j); + else + m_dist2GrayIndSample(j) = ctmpInd(j); + } + } + } + } +} diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetectionMirta.h b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetectionMirta.h new file mode 100644 index 000000000..dce77f687 --- /dev/null +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetectionMirta.h @@ -0,0 +1,27 @@ +#include "Windows.h" +#include "DetectionColor.pb-c.h" +#include "DetectionBenchmark.pb-c.h" +#include <string> +#include <vector> +#include <Eigen/Dense> +#include "ConsolidateData.h" +#include <opencv2/opencv.hpp> +#include <vector> + +using Eigen::MatrixXd; +using Eigen::VectorXd; +using Eigen::MatrixXi; +using Eigen::VectorXi; + +class ColorDetectionMirta +{ +private: + DetectionColor* initDetectionColor(int r, int g, int b); + void DistanceMatrix(int rows, int cols, MatrixXi &m_dist2grayInd, VectorXi &m_dist2GrayIndSample,VectorXi GrayInd, int TargetInd); + int m_interpPoints; +public: + ColorDetectionMirta(); + ~ColorDetectionMirta(); + DetectionColor* CDetect(DetectionBenchmark** benchmarks, std::vector<cv::Scalar> means, int column, int rows, int targetIndex); +}; + diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ConsolidateData.cpp b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ConsolidateData.cpp index c2c3e2c27..9e2e1b9f9 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ConsolidateData.cpp +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ConsolidateData.cpp @@ -19,7 +19,11 @@ ConsolidateData::ConsolidateData() : m_nSep(0), m_SortIndex(NULL), m_nMeasurements(0), - m_diffTol(0.0) + m_diffTol(0.0), + m_Values1(0,0), m_Values2(0,0), + m_SortedValues1(0,0), m_SortedValues2(0,0), + m_breaks(0), m_coeffs(0,0), m_pchipSlopes(0), + m_intervals(0) { } @@ -27,7 +31,11 @@ ConsolidateData::ConsolidateData() : ConsolidateData::ConsolidateData(double diffTol): m_nSep(0), m_SortIndex(NULL), - m_nMeasurements(0) + m_nMeasurements(0), + m_Values1(0,0), m_Values2(0,0), + m_SortedValues1(0,0), m_SortedValues2(0,0), + m_breaks(0), m_coeffs(0,0), m_pchipSlopes(0), + m_intervals(0) { m_diffTol = diffTol; } @@ -352,15 +360,7 @@ int ConsolidateData::LinInterp(VectorXd xIn, VectorXd yIn, double xVal, double & yOut = min(max(yOut, 0.0), 1.0); return(0); } - if (xVal > xIn(lx - 1)) - { - w0 = (xIn(lx - 1) - xVal) / (xIn(lx - 1) - xIn(lx - 2)); - w1 = 1 - w0; - for (int j = 0; j < n_ycols; ++j) - yOut = yIn(lx - 2)* w0 + w1*yIn(lx - 1); - yOut = min(max(yOut, 0.0), 1.0); - return(0); - } + for (int i = 0; i < lx - 1; ++i) { if ((xVal <= xIn(i + 1)) & (xVal >= xIn(i))) @@ -370,9 +370,18 @@ int ConsolidateData::LinInterp(VectorXd xIn, VectorXd yIn, double xVal, double & for (int j = 0; j < n_ycols; ++j) yOut = yIn(i)* w0 + w1*yIn(i + 1); yOut = min(max(yOut, 0.0), 1.0); - break; + return(0); } } + if (xVal > xIn(lx - 1)) + { + w0 = (xIn(lx - 1) - xVal) / (xIn(lx - 1) - xIn(lx - 2)); + w1 = 1 - w0; + for (int j = 0; j < n_ycols; ++j) + yOut = yIn(lx - 2)* w0 + w1 * yIn(lx - 1); + yOut = min(max(yOut, 0.0), 1.0); + return(0); + } return(0); } @@ -397,6 +406,203 @@ int ConsolidateData::LinInterp(VectorXd xIn, MatrixXd yIn, VectorXd xVal, Matri return(0); } +int ConsolidateData::PCHIP(VectorXd xIn, VectorXd yIn, double xVal, double &yOut) +{ + int RetValue = CheckData(xIn, yIn); + if (RetValue < 0) + return(RetValue); + + //Comput Slopes + int n = xIn.size(); + VectorXd diffX(n - 1); + VectorXd diffY(n - 1); + VectorXd del(n - 1); + + for (int i = 0; i < n - 1; ++i) + { + diffX(i) = xIn(i + 1) - xIn(i); + diffY(i) = yIn(i + 1) - yIn(i); + del(i) = diffY(i) / diffX(i); + } + m_coeffs.resize(n - 1, 4); + GetPchipSlopes(xIn, yIn, del); + GetPiecewiseCubicElements(xIn, yIn, diffX, del); + + return(0); +} + +void ConsolidateData::PCHIPInterp(VectorXd xIn, VectorXd yIn, double xVal, double &yOut) +{ + double w0, w1; + int lx = xIn.size(); + int n_ycols = yIn.cols(); + if (xVal < xIn(0)) + { + w0 = (xIn(1) - xVal) / (xIn(1) - xIn(0)); + w1 = 1 - w0; + yOut = yIn(0)* w0 + w1 * yIn(1); + yOut = min(max(yOut, 0.0), 1.0); + return; + } + else if (xVal >= xIn(lx-1)) + { + w0 = (xIn(lx - 1) - xVal) / (xIn(lx - 1) - xIn(lx - 2)); + w1 = 1 - w0; + yOut = yIn(lx - 2)* w0 + w1 * yIn(lx - 1); + yOut = min(max(yOut, 0.0), 1.0); + return; + } + else + { + for (int i = 0; i < lx - 1; ++i) + //find interval + if ((xVal <= xIn(i + 1)) & (xVal >= xIn(i))) + { + //local coordinates + xVal = xVal - m_breaks(i); + yOut = m_coeffs(i, 0); + for (int j = 1; j < 4; ++j) + yOut = xVal * yOut + m_coeffs(i, j); + break; + } + } + return; +} + +void ConsolidateData::GetPiecewiseCubicElements(VectorXd xIn, VectorXd yIn, VectorXd diffX, VectorXd del) +{ + int n = xIn.size(); + VectorXd dzzdx(n - 1); + VectorXd dzdxdx(n - 1); + for (int i = 0; i < n - 1; ++i) + { + dzzdx(i) = (del(i) - m_pchipSlopes(i)) / diffX(i); + dzdxdx(i) = (m_pchipSlopes(i + 1) - del(i)) / diffX(i); + } + m_breaks = xIn; + for (int i = 0; i <n-1; ++i) + { + m_coeffs(i, 0) = (dzdxdx(i) - dzzdx(i)) / diffX(i); + m_coeffs(i, 1) = 2 * dzzdx(i) - dzdxdx(i); + m_coeffs(i, 2) = m_pchipSlopes(i); + m_coeffs(i, 3) = yIn(i); + } +} + +void ConsolidateData::GetPchipSlopes(VectorXd xIn, VectorXd yIn, VectorXd del) +{ + //Compute the first derivatives of the Piecewise Cubic Hermite Interpolating Polynomial + int n = xIn.size(); + m_pchipSlopes.resize(n); + if (n == 2) + { + for (int i = 0; i < n; ++i) + { + m_pchipSlopes(i) = del(0); + } + return; + } + // Slopes at interior points. + //d(k) = weighted average of del(k - 1) and del(k) when they have the same sign. + //d(k) = 0 when del(k - 1) and del(k) have opposites signs or either is zero. + VectorXd hdiff(n - 1); + VectorXd hsdiff(n - 2); + VectorXd w1(n - 2); + VectorXd w2(n - 2); + VectorXd dmax(n - 2); + VectorXd dmin(n - 2); + VectorXi kInd(n - 2); + for (int i = 0; i < n - 2; ++i) + { + if (del(i)*del(i + 1) > 0) + kInd(i) = i; + else + kInd(i) = -1; + } + //Difference + for (int i = 0; i < n - 1; ++i) + hdiff(i) = xIn(i + 1) - xIn(i); + for (int i = 0; i < n - 2; ++i) + { + if (kInd(i) > -1) + hsdiff(i) = hdiff(i) + hdiff(i + 1); + else + hsdiff(i) = 0; + } + for (int i = 0; i < n - 2; ++i) + { + if (kInd(i) > -1) + { + w1(i) = (hdiff(i) + hsdiff(i)) / (3 * hsdiff(i)); + w2(i) = (hsdiff(i) + hdiff(i + 1)) / (3 * hsdiff(i)); + dmax(i) = max(abs(del(i)), abs(del(i + 1))); + dmin(i) = min(abs(del(i)), abs(del(i + 1))); + m_pchipSlopes(i + 1) = dmin(i) / (w1(i)*(del(i) / dmax(i)) + w2(i)*(del(i + 1) / dmax(i))); + } + else + { + m_pchipSlopes(i + 1) = 0; + } + } + + //Calculate Slopes at endpoints + m_pchipSlopes(0) = ((2 * hdiff(0) + hdiff(1))*del(0) - hdiff(0)*del(1)) / (hdiff(0) + hdiff(1)); + if (m_pchipSlopes(0)*del(0)<0) + m_pchipSlopes(0) = 0; + else if (((del(0) * del(1)) < 0) & (std::abs(m_pchipSlopes(0)) > std::abs(3 * del(0)))) + m_pchipSlopes(0) = 3 * del(0); + + m_pchipSlopes(n - 1) = ((2 * hdiff(n - 2) + hdiff(n - 3))*del(n - 2) - hdiff(n - 2)*del(n - 3)) / (hdiff(n - 2) + hdiff(n - 3)); + if ((m_pchipSlopes(n - 1)) *(del(n - 2)) < 0) + m_pchipSlopes(n - 1) = 0; + else if (((del(n - 2)*del(n - 3)) < 0) & (std::abs(m_pchipSlopes(n - 1)) > (std::abs(del(n - 2))))) + m_pchipSlopes(n - 1) = 3 * del(n - 2); + + return; +} + + + int ConsolidateData::CheckData(VectorXd xIn, VectorXd yIn) + { + if (xIn.size() != yIn.size()) //vectors have to be same length + return(-1); + + int n = xIn.size(); + if (n < 2) + return(-2); + //check for strict monotonicity + double diff = -1; + double mindiff = 1e+05; + for (int i = 1; i < n; ++i) + { + diff = xIn(i) - xIn(i - 1); + mindiff = min(mindiff, diff); + } + if (mindiff < 0) // Data is not strictly monotonic + { + //sort x and y + std::vector<std::pair<double, double> >V; + for (int i = 0; i < n; i++) + { + std::pair<double, double>P = std::make_pair(xIn(i), yIn(i)); + V.push_back(P); + } + std::sort(V.begin(), V.end()); + xIn(0) = V[0].first; + yIn(0) = V[0].second; + for (int i = 1; i < n; i++) + { + xIn(i) = V[i].first; + yIn(i) = V[i].second; + diff = xIn(i) - xIn(i - 1); + if (diff <= 0) + return(-3); + } + } + return(0); + } + + bool ConsolidateData::CountExpandReplicates(int *SortIndex, int *ExpCount) diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ConsolidateData.h b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ConsolidateData.h index 5e6ecca4c..4041e137b 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ConsolidateData.h +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ConsolidateData.h @@ -7,6 +7,8 @@ #include <functional> #include "Eigen/Dense" #include "Detect.h" +#include <algorithm> +#include <utility> using Eigen::MatrixXd; using Eigen::VectorXd; @@ -16,10 +18,14 @@ struct VectorPair int m_ID; double m_val; }; - -struct ByInt : public std::binary_function<VectorPair, VectorPair, bool> +struct VectorPairInt { - bool operator()(const VectorPair& lhs, const VectorPair& rhs) const + int m_ID; + int m_val; +}; +struct ByInt : public std::binary_function<VectorPairInt, VectorPairInt, bool> +{ + bool operator()(const VectorPairInt& lhs, const VectorPairInt& rhs) const { return lhs.m_ID< rhs.m_ID; } @@ -50,6 +56,10 @@ public: int LinInterp(VectorXd xIn, MatrixXd yIn, double xVal, VectorXd yOut); int LinInterp(VectorXd xIn, MatrixXd yIn, VectorXd xVal, MatrixXd yOut); int LinInterp(VectorXd xIn, VectorXd yIn, double xVal, double &yOut); + int PCHIP(VectorXd xIn, MatrixXd yIn, double xVal, VectorXd yOut); + int PCHIP(VectorXd xIn, MatrixXd yIn, VectorXd xVal, MatrixXd yOut); + int PCHIP(VectorXd xIn, VectorXd yIn, double xVal, double &yOut); + void PCHIPInterp(VectorXd xIn, VectorXd yIn, double xVal, double &yOut); private: MatrixXd m_Values1; MatrixXd m_Values2; @@ -60,6 +70,11 @@ private: int *m_CountDuplicates; int *m_MarkValues; + VectorXd m_breaks; + MatrixXd m_coeffs; + VectorXd m_pchipSlopes; + int m_polOrder; + int m_intervals; bool m_bLab; int m_nSep; @@ -77,6 +92,10 @@ private: bool SortValues(int *SortIndex); bool CountExpandReplicates(int *SortIndex, int *ExpCount); + void GetPchipSlopes(VectorXd x, VectorXd y, VectorXd del); + void GetPiecewiseCubicElements(VectorXd x, VectorXd y, VectorXd diffX, VectorXd del); + int CheckData(VectorXd xIn, VectorXd yIn); + }; diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Detect.cpp b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Detect.cpp index e9b933cd6..520627829 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Detect.cpp +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Detect.cpp @@ -160,7 +160,7 @@ int Detect::MatchSampleColor(VectorXd &outResult, VectorXd &outResultLab, char * outErrorMsg = msg; return(ret); } - + //VectorXd outLabVec = Solve.eval(m_sampleColorLab ); VectorXd outLabVec = Solve.eval(m_sampleColorLab - m_SampledDataLabWP); for (j = 0; j < nDim; ++j) outLabVec(j) += m_SampledDataLabWP(j); @@ -206,7 +206,7 @@ int Detect::PrepareData() ColorConvert CConvertD65(D65, D65); C_RGB_XYZ_Lab BenchMarkDataWPXYZ = CConvertD65.LabToXYZ(BenchMarkDataWPLab); - ColorConvert CConvert(D65, BenchMarkDataWPXYZ); + ColorConvert CConvert(BenchMarkDataWPXYZ, BenchMarkDataWPXYZ); C_RGB_XYZ_Lab LowLab(0.0, -128.0, -128.0); C_RGB_XYZ_Lab HighLab(100.0, 127.0, 127.0); int j = 0; @@ -224,11 +224,11 @@ int Detect::PrepareData() SampledLabData(i, 1) = DataLab.Get_y(); SampledLabData(i, 2) = DataLab.Get_z(); - //Convert Benchmark Data Lab Relative Colorimetric + //Convert Benchmark Data Lab Relative Colorimetric, use White pount of BenchMark Data DataLab.Set(m_BenchMarkDataLab(i, 0), m_BenchMarkDataLab(i, 1), m_BenchMarkDataLab(i, 2)); DataXYZ = CConvertD65.LabToXYZ(DataLab); - DataXYZ_Norm = CConvert.ApplyBradfordMat(DataXYZ); - DataLab = CConvertD65.XYZToLab(DataXYZ_Norm); + //DataXYZ_Norm = CConvert.ApplyBradfordMat(DataXYZ); + DataLab = CConvert.XYZToLab(DataXYZ); DataLab.Clamp(LowLab, HighLab); BenchMarkLabDataRel(i, 0) = DataLab.Get_x(); BenchMarkLabDataRel(i, 1) = DataLab.Get_y(); @@ -460,6 +460,9 @@ void Detect::LocalGrayCorrection() MatrixXd SDGray(ndistcorr, ncols); VectorXd LocBDGray(1); VectorXd LocSDGray(1); + VectorXd VecBDGray(1); + VectorXd tmpLocBDGray(1); + VectorXd tmpLocSDGray(1); MatrixXd tmpBDGray(ndistcorr, ncols); MatrixXd tmpSDGray(ndistcorr, ncols); @@ -468,6 +471,7 @@ void Detect::LocalGrayCorrection() ConsolidateData Consolidate; m_SampledDataCorr.resize(nrows, ncols); int i, j, k; + int tmpN; for (i = 0; i < nrows; ++i) { for (j = 0; j < ndistcorr; ++j) @@ -478,44 +482,31 @@ void Detect::LocalGrayCorrection() SDGray(j,k) = m_SampledData(m_dist2grayInd(i, j), k); } } -// fprintf(fp1, "%d\n",i); -/* for (j = 0; j < ndistcorr; ++j) - { - for (k = 0; k < ncols; ++k) - fprintf(fp1, "%f\t", BDGray(j, k)); - fprintf(fp1, "\n"); - for (k = 0; k < ncols; ++k) - fprintf(fp1, "%f\t", SDGray(j, k)); - fprintf(fp1, "\n"); - } - */ + Consolidate.Init(BDGray, SDGray); + // values are sorted in MergeValues Consolidate.MergeValues(); tmpBDGray = Consolidate.getOutValues1(); tmpSDGray = Consolidate.getOutValues2(); - int tmpN = tmpBDGray.rows(); + tmpN = tmpBDGray.rows(); + VecBDGray.resize(tmpN); + for (k = 0; k < tmpN; ++k) + VecBDGray(k) = tmpBDGray(k, 1); + Consolidate.CheckMonotonicity(VecBDGray, tmpSDGray); + int kstart = 0; LocBDGray.resize(tmpN); LocSDGray.resize(tmpN); - for (k = 0; k < tmpN; ++k) - LocBDGray(k) = tmpBDGray(k, 1); - Consolidate.CheckMonotonicity(LocBDGray, tmpSDGray); for (j=0; j<ncols; ++j) { for (k=0; k<tmpN; ++k) { - LocBDGray(k) = tmpBDGray(k, j); + LocBDGray(k) = VecBDGray(k); LocSDGray(k) = tmpSDGray(k, j); - } + } Consolidate.CheckUniqueness(LocBDGray, LocSDGray); +// Consolidate.PCHIP(LocSDGray, LocBDGray, m_SampledData(i, j), m_SampledDataCorr(i, j)); +// Consolidate.PCHIPInterp(LocSDGray, LocBDGray, m_SampledData(i, j), m_SampledDataCorr(i, j)); Consolidate.LinInterp(LocSDGray, LocBDGray, m_SampledData(i, j), m_SampledDataCorr(i, j)); - -/* for (k = 0; k < tmpN; ++k) - fprintf(fp1, "%f\t", LocBDGray(k)); - fprintf(fp1, "\n"); - for (k = 0; k < tmpN; ++k) - fprintf(fp1, "%f\t", LocSDGray(k)); - fprintf(fp1, "\n"); - fprintf(fp1, "%f\t%f\n", m_SampledData(i, j), m_SampledDataCorr(i, j)); */ } } @@ -528,36 +519,28 @@ void Detect::LocalGrayCorrection() SDGray(j, k) = m_SampledData(m_dist2GrayIndSample(j), k); } } -/* fprintf(fp1, "s\n"); - for (j = 0; j < ndistcorr; ++j) - { - for (k = 0; k < ncols; ++k) - fprintf(fp1, "%f\t", BDGray(j, k)); - fprintf(fp1, "\n"); - for (k = 0; k < ncols; ++k) - fprintf(fp1, "%f\t", SDGray(j, k)); - fprintf(fp1, "\n"); - } - */ + Consolidate.Init(BDGray, SDGray); m_SampleColorCorr.resize(ncols); Consolidate.MergeValues(); tmpBDGray = Consolidate.getOutValues1(); tmpSDGray = Consolidate.getOutValues2(); - int tmpN = tmpBDGray.rows(); + tmpN = tmpBDGray.rows(); LocBDGray.resize(tmpN); LocSDGray.resize(tmpN); for (k = 0; k < tmpN; ++k) - LocBDGray(k) = tmpBDGray(k, 1); - Consolidate.CheckMonotonicity(LocBDGray, tmpSDGray); - for (j = 0; j<ncols; ++j) + VecBDGray(k) = tmpBDGray(k, 1); + Consolidate.CheckMonotonicity(VecBDGray, tmpSDGray); + int kstart1 =0; + for (j = 0; j < ncols; ++j) { - for (k = 0; k<tmpN; ++k) + for (k = 0; k < tmpN; ++k) { - LocBDGray(k) = tmpBDGray(k, j); + LocBDGray(k) = VecBDGray(k); LocSDGray(k) = tmpSDGray(k, j); } Consolidate.CheckUniqueness(LocBDGray, LocSDGray); + // Consolidate.PCHIP(LocSDGray, LocBDGray, m_sampleColor(j), m_SampleColorCorr(j)); Consolidate.LinInterp(LocSDGray, LocBDGray, m_sampleColor(j), m_SampleColorCorr(j)); /* for (k = 0; k < tmpN; ++k) diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Detect.h b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Detect.h index 0cf65ccbf..daf09c243 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Detect.h +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Detect.h @@ -6,7 +6,7 @@ #include <Eigen/Dense> #include "CRGB_XYZ_Lab.h" #include "ConsolidateData.h" - +#include <Eigen/Dense> using Eigen::MatrixXd; using Eigen::VectorXd; using Eigen::MatrixXi; diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Interp.cpp b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Interp.cpp new file mode 100644 index 000000000..3230793e8 --- /dev/null +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Interp.cpp @@ -0,0 +1,341 @@ +#include "stdafx.h" +#include "Interp.h" + +#define sgn(x) ((x) > 0) ? (1) : (((x) < (0)) ? (-1) : (0)) +#include <algorithm> +#include <utility> +#include <Eigen/Dense> + + +//default Constructor +Interp::Interp() : +m_xIn(1), +m_yIn(1), +m_breaks(1), +m_coeffs(1,1), +m_pchipSlopes(1), +m_polOrder(0), +m_intervals(0) +{ +} + +Interp::Interp(VectorXd xIn, VectorXd yIn): +m_breaks(1), +m_coeffs(1, 1), +m_polOrder(3), +m_intervals(0), +m_pchipSlopes(1) +{ + m_xIn = xIn; + m_yIn = yIn; +} + +Interp::~Interp() +{ +} + + void Interp::SetCoeffs(MatrixXd coeffs) + { + int nxsize = m_xIn.size(); + for (int i = 1; i < nxsize; ++i) + for (int j = 0; j <= m_polOrder; ++j) + m_coeffs(i, j) = coeffs(i, j); + } + + int Interp::LinInterp( MatrixXd yIn, double xVal, VectorXd &yOut) + { + //check sizes + int lx = m_xIn.size(); + if (lx != yIn.rows()) + return (-1); + double w0, w1; + int n_ycols = yIn.cols(); + + //find interval + if (xVal < m_xIn(0)) + { + w0 = (m_xIn(1) - xVal) / (m_xIn(1) - m_xIn(0)); + w1 = 1 - w0; + for (int j = 0; j < n_ycols; ++j) + yOut(j) = yIn(0, j)* w0 + w1 * yIn(1, j); + return(0); + } + if (xVal > m_xIn(lx - 1)) + { + w0 = (m_xIn(lx - 1) - xVal) / (m_xIn(lx - 1) - m_xIn(lx - 2)); + w1 = 1 - w0; + for (int j = 0; j < n_ycols; ++j) + yOut(j) = yIn(lx - 2, j)* w0 + w1 * yIn(lx - 1, j); + return(0); + } + for (int i = 0; i < lx - 1; ++i) + { + if ((xVal <= m_xIn(i + 1)) & (xVal >= m_xIn(i))) + { + w0 = (m_xIn(i + 1) - xVal) / (m_xIn(i + 1) - m_xIn(i)); + w1 = 1 - w0; + for (int j = 0; j < n_ycols; ++j) + yOut(j) = yIn(i, j)* w0 + w1 * yIn(i + 1, j); + } + } + return(0); + } + + int Interp::LinInterp(double xVal, double &yOut) + { + //check sizes + int lx = m_xIn.size(); + if (lx != m_yIn.rows()) + return (-1); + double w0, w1; + int n_ycols = m_yIn.cols(); + + //find interval + if (xVal < m_xIn(0)) + { + w0 = (m_xIn(1) - xVal) / (m_xIn(1) - m_xIn(0)); + w1 = 1 - w0; + for (int j = 0; j < n_ycols; ++j) + yOut = m_yIn(0)* w0 + w1 * m_yIn(1); + yOut = min(max(yOut, 0.0), 1.0); + return(0); + } + if (xVal > m_xIn(lx - 1)) + { + w0 = (m_xIn(lx - 1) - xVal) / (m_xIn(lx - 1) - m_xIn(lx - 2)); + w1 = 1 - w0; + for (int j = 0; j < n_ycols; ++j) + yOut = m_yIn(lx - 2)* w0 + w1 * m_yIn(lx - 1); + yOut = min(max(yOut, 0.0), 1.0); + return(0); + } + for (int i = 0; i < lx - 1; ++i) + { + if ((xVal <= m_xIn(i + 1)) & (xVal >= m_xIn(i))) + { + w0 = (m_xIn(i + 1) - xVal) / (m_xIn(i + 1) - m_xIn(i)); + w1 = 1 - w0; + for (int j = 0; j < n_ycols; ++j) + yOut = m_yIn(i)* w0 + w1 * m_yIn(i + 1); + yOut = min(max(yOut, 0.0), 1.0); + break; + } + } + return(0); + } + + int Interp::LinInterp(MatrixXd yIn, VectorXd xVal, MatrixXd &yOut) + { + //check sizes + int lx = m_xIn.size(); + if (lx != yIn.rows()) + return (-1); + int n_ycols = yIn.cols(); + int n_ValSize = xVal.size(); + VectorXd VyOut(n_ycols); + + for (int i = 0; i<n_ValSize; ++i) + { + LinInterp( yIn, xVal(i), VyOut); + for (int j = 0; j < n_ycols; ++j) + { + yOut(i, j) = VyOut(j); + } + } + return(0); + } + + int Interp::PCHIP( double xVal, double &yOut) + { + // int RetValue = CheckData(); + // if (RetValue < 0) + // return(RetValue); + + //Compute Slopes + int n = m_xIn.size(); + VectorXd diffX(n - 1); + VectorXd diffY(n - 1); + VectorXd del(n - 1); + for (int i = 0; i < n - 1; ++i) + { + diffX(i) = m_xIn(i + 1) - m_xIn(i); + diffY(i) = m_yIn(i + 1) - m_yIn(i); + del(i) = diffY(i) / diffX(i); + } + + GetPchipSlopes( del); + GetPiecewiseCubicElements( diffX, del); + + return(0); + } + + int Interp::PCHIPInterp(double xVal, double &yOut) + { + double w0, w1; + int lx = m_xIn.size(); + int n_ycols = m_yIn.cols(); + if(xVal<m_xIn(0)) + { + w0 = (m_xIn(1) - xVal) / (m_xIn(1) - m_xIn(0)); + w1 = 1 - w0; + yOut = m_yIn(0)* w0 + w1 * m_yIn(1); + yOut = min(max(yOut, 0.0), 1.0); + return(0); + } + else if (xVal >= m_xIn(lx)) + { + w0 = (m_xIn(lx - 1) - xVal) / (m_xIn(lx - 1) - m_xIn(lx - 2)); + w1 = 1 - w0; + yOut = m_yIn(lx - 2)* w0 + w1 * m_yIn(lx - 1); + yOut = min(max(yOut, 0.0), 1.0); + return(0); + } + else + { + for (int i=0; i<lx-1; ++i) + //find interval + if ((xVal <= m_xIn(i + 1)) & (xVal >= m_xIn(i))) + { + //local coordinates + xVal = xVal - m_breaks(i); + yOut = m_coeffs(i, 0); + for (int j = 1; j < 4; ++j) + yOut = xVal * yOut + m_coeffs(i, j); + break; + } + } + return(0); + } + + void Interp::GetPiecewiseCubicElements(VectorXd diffX, VectorXd del) + { + int n = m_xIn.size(); + + VectorXd dzzdx(n - 1); + VectorXd dzdxdx(n - 1); + for (int i = 0; i < n - 1; ++i) + { + dzzdx(i) = (del(i) - m_pchipSlopes(i)) / diffX(i); + dzdxdx(i) = (m_pchipSlopes(i+1) - del(i)) / diffX(i); + } + m_breaks = m_xIn; + for (int i = 0; i <= n; ++i) + { + m_coeffs(i, 0) = (dzdxdx(i) - dzzdx(i)) / diffX(i); + m_coeffs(i, 1) = 2 * dzzdx(i) - dzdxdx(i); + m_coeffs(i, 2) = m_pchipSlopes(i); + m_coeffs(i, 3) = m_yIn(i); + } +} + + + + void Interp::GetPchipSlopes( VectorXd del) + { + //Compute the first derivatives of the Piecewise Cubic Hermite Interpolating Polynomial + int n = m_xIn.size(); + m_pchipSlopes.resize(n); + if (n == 2) + { + for (int i = 0; i < n; ++i) + { + m_pchipSlopes(i) = del(0); + } + return; + } + // Slopes at interior points. + //d(k) = weighted average of del(k - 1) and del(k) when they have the same sign. + //d(k) = 0 when del(k - 1) and del(k) have opposites signs or either is zero. + VectorXd hdiff(n - 1); + VectorXd hsdiff(n - 2); + VectorXd w1(n - 2); + VectorXd w2(n - 2); + VectorXd dmax(n - 2); + VectorXd dmin(n - 2); + VectorXi kInd(n - 2); + for (int i = 0; i < n - 2; ++i) + { + if (del(i)*del(i + 1) > 0) + kInd(i) = i; + else + kInd(i) = 0; + } + //Difference + for (int i = 0; i < n - 1; ++i) + hdiff(i) = m_xIn(i + 1) - m_xIn(i); + for (int i = 0; i < n - 2; ++i) + { + if (kInd(i) > 0) + hsdiff(i) = hdiff(i) + hdiff(i + 1); + else + hsdiff(i) = 0; + } + for (int i = 0; i < n - 2; ++i) + { + if (kInd(i) > 0) + { + w1(i) = (hdiff(i) + hsdiff(i)) / (3 * hsdiff(i)); + w2(i) = (hsdiff(i) + hdiff(i + 1)) / (3 * hsdiff(i)); + dmax(i) = max(abs(del(i)), abs(del(i + 1))); + dmin(i) = min(abs(del(i)), abs(del(i + 1))); + m_pchipSlopes(i + 1) = dmin(i) / (w1(i)*(del(i) / dmax(i)) + w2(i)*(del(i + 1) / dmax(i))); + } + else + m_pchipSlopes(i + 1) = 0; + } + + //Calculate Slopes at endpoints + m_pchipSlopes(0) = ((2 * hdiff(0) + hdiff(1))*del(0) - hdiff(0)*del(1)) / (hdiff(0) + hdiff(1)); + if (sgn(m_pchipSlopes(0)) != sgn(del(0))) + m_pchipSlopes(0) = 0; + else if ((sgn(del(0)) != sgn(del(1))) & (abs(m_pchipSlopes(0)) > abs(3 *del(0)))) + m_pchipSlopes(0) = 3 * del(0); + + m_pchipSlopes(n - 1) = ((2 * hdiff(n - 2) + hdiff(n - 3))*del(n - 2) - hdiff(n - 2)*del(n - 3)) / (hdiff(n - 2) + hdiff(n - 3)); + if (sgn(m_pchipSlopes(n - 1)) != sgn(del(n - 2))) + m_pchipSlopes(n - 1) = 0; + else if ((sgn(del(n - 2)) != sgn(del(n - 3))) & (abs(m_pchipSlopes(n - 1)) > abs(3 *del(n - 2)))) + m_pchipSlopes(n - 1) = 3 * del(n - 2); + + return; + } + + int Interp::CheckData() + { + if (m_xIn.size() != m_yIn.size()) //vectors have to be same length + return(-1); + + int n = m_xIn.size(); + if (n < 2) + return(-2); + //check for strict monotonicity + double diff = -1; + double mindiff = 1e+05; + for (int i = 1; i < n; ++i) + { + diff = m_xIn(i) - m_xIn(i - 1); + mindiff = min(mindiff, diff); + } + if (mindiff < 0) // Data is not strictly monotonic + { + //sort x and y + std::vector<std::pair<double, double> >V; + for (int i = 0; i < n; i++) + { + std::pair<double, double>P = std::make_pair(m_xIn(i), m_yIn(i)); + V.push_back(P); + } + std::sort(V.begin(), V.end()); + m_xIn(0) = V[0].first; + m_yIn(0) = V[0].second; + for (int i = 1; i < n; i++) + { + m_xIn(i) = V[i].first; + m_yIn(i) = V[i].second; + diff = m_xIn(i) - m_xIn(i - 1); + if (diff <= 0) + return(-3); + } + } + return(0); + } diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Interp.h b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Interp.h new file mode 100644 index 000000000..2086a94d5 --- /dev/null +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Interp.h @@ -0,0 +1,39 @@ +#ifndef __INTERP_H__ +#define __INTERP_H__ + +#include "Eigen/Dense" +#include "Detect.h" + +using Eigen::MatrixXd; +using Eigen::VectorXd; + +class Interp +{ +public: + Interp(); + Interp(VectorXd xIn, VectorXd yIn); + ~Interp(); + int LinInterp( MatrixXd yIn, double xVal, VectorXd &yOut); + int LinInterp( MatrixXd yIn, VectorXd xVal, MatrixXd &yOut); + int LinInterp( double xVal, double &yOut); +// int PCHIP(VectorXd xIn, MatrixXd yIn, double xVal, VectorXd yOut); +// int PCHIP(VectorXd xIn, MatrixXd yIn, VectorXd xVal, MatrixXd yOut); + int PCHIP( double xVal, double &yOut); + int PCHIPInterp(double xVal, double &yOut); +private: + int CheckData(); + void GetPchipSlopes(VectorXd del); + void GetPiecewiseCubicElements( VectorXd diffX, VectorXd del); + VectorXd m_xIn; + VectorXd m_yIn; + VectorXd m_breaks; + MatrixXd m_coeffs; + VectorXd m_pchipSlopes; + int m_polOrder; + int m_intervals; + void SetCoeffs(MatrixXd coeffs); + void SetIntervalBreaks(VectorXd breaks) { m_breaks = breaks; }; + void SetPolynomialOrder(int polOrder) { m_polOrder = polOrder; }; + void SetNumberOfIntervals(int intervals) {m_intervals = intervals;}; +}; +#endif
\ No newline at end of file diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/LLS_Solver.cpp b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/LLS_Solver.cpp index e62181007..27e7b25fe 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/LLS_Solver.cpp +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/LLS_Solver.cpp @@ -146,5 +146,5 @@ VectorXd LLS_Solver::eval(VectorXd SampleRGB) } // std::cout << "The Lab solution is:\n" // << resultData << std::endl; - return(resultData); +return(resultData); }
\ No newline at end of file diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Tango.TCC.ColorDetector.vcxproj b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Tango.TCC.ColorDetector.vcxproj index daffed975..f2e62b41e 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Tango.TCC.ColorDetector.vcxproj +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Tango.TCC.ColorDetector.vcxproj @@ -185,10 +185,12 @@ <ClInclude Include="bitmap_image.hpp" /> <ClInclude Include="ColorConvert.h" /> <ClInclude Include="ColorDetection.h" /> + <ClInclude Include="ColorDetectionMirta.h" /> <ClInclude Include="ConsolidateData.h" /> <ClInclude Include="CRGB_XYZ_Lab.h" /> <ClInclude Include="Detect.h" /> <ClInclude Include="Exports.h" /> + <ClInclude Include="Interp.h" /> <ClInclude Include="LLS_Solver.h" /> <ClInclude Include="PMR\TCC\DetectionBenchmark.pb-c.h" /> <ClInclude Include="PMR\TCC\DetectionColor.pb-c.h" /> @@ -201,11 +203,12 @@ <ItemGroup> <ClCompile Include="ColorConvert.cpp" /> <ClCompile Include="ColorDetection.cpp" /> - <ClCompile Include="ColorDetectionAlgorithm.cpp" /> + <ClCompile Include="ColorDetectionMirta.cpp" /> <ClCompile Include="ConsolidateData.cpp" /> <ClCompile Include="C_RGB_XYZ_Lab.cpp" /> <ClCompile Include="Detect.cpp" /> <ClCompile Include="Exports.cpp" /> + <ClCompile Include="Interp.cpp" /> <ClCompile Include="LLS_Solver.cpp" /> <ClCompile Include="PMR\TCC\DetectionBenchmark.pb-c.c" /> <ClCompile Include="PMR\TCC\DetectionColor.pb-c.c" /> diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Tango.TCC.ColorDetector.vcxproj.filters b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Tango.TCC.ColorDetector.vcxproj.filters index e3af22d85..61beb5852 100644 --- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Tango.TCC.ColorDetector.vcxproj.filters +++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/Tango.TCC.ColorDetector.vcxproj.filters @@ -69,14 +69,17 @@ <ClInclude Include="PMR\TCC\DetectionBenchmark.pb-c.h"> <Filter>PMR</Filter> </ClInclude> + <ClInclude Include="ColorDetectionMirta.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Interp.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="stdafx.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="ColorDetectionAlgorithm.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="ColorDetection.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -113,5 +116,11 @@ <ClCompile Include="PMR\TCC\DetectionBenchmark.pb-c.c"> <Filter>PMR</Filter> </ClCompile> + <ClCompile Include="ColorDetectionMirta.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Interp.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/Tango_TCC.sln b/Software/Visual_Studio/Tango_TCC.sln new file mode 100644 index 000000000..5656e6679 --- /dev/null +++ b/Software/Visual_Studio/Tango_TCC.sln @@ -0,0 +1,62 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.539 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.TCC.BL", "TCC\Tango.TCC.BL\Tango.TCC.BL.csproj", "{F209FAE8-73F9-441B-97F4-0844A0279390}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tango.TCC.ColorDetector", "TCC\Tango.TCC.ColorDetector\Tango.TCC.ColorDetector.vcxproj", "{862328A4-8632-43AF-B466-55825C7962FE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.MachineStudio.UI", "MachineStudio\Tango.MachineStudio.UI\Tango.MachineStudio.UI.csproj", "{116DFDB0-7681-46FE-8BAD-FE8AE09BB076}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F209FAE8-73F9-441B-97F4-0844A0279390}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F209FAE8-73F9-441B-97F4-0844A0279390}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F209FAE8-73F9-441B-97F4-0844A0279390}.Debug|x64.ActiveCfg = Debug|Any CPU + {F209FAE8-73F9-441B-97F4-0844A0279390}.Debug|x64.Build.0 = Debug|Any CPU + {F209FAE8-73F9-441B-97F4-0844A0279390}.Debug|x86.ActiveCfg = Debug|Any CPU + {F209FAE8-73F9-441B-97F4-0844A0279390}.Debug|x86.Build.0 = Debug|Any CPU + {F209FAE8-73F9-441B-97F4-0844A0279390}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F209FAE8-73F9-441B-97F4-0844A0279390}.Release|Any CPU.Build.0 = Release|Any CPU + {F209FAE8-73F9-441B-97F4-0844A0279390}.Release|x64.ActiveCfg = Release|Any CPU + {F209FAE8-73F9-441B-97F4-0844A0279390}.Release|x64.Build.0 = Release|Any CPU + {F209FAE8-73F9-441B-97F4-0844A0279390}.Release|x86.ActiveCfg = Release|Any CPU + {F209FAE8-73F9-441B-97F4-0844A0279390}.Release|x86.Build.0 = Release|Any CPU + {862328A4-8632-43AF-B466-55825C7962FE}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {862328A4-8632-43AF-B466-55825C7962FE}.Debug|x64.ActiveCfg = Debug|x64 + {862328A4-8632-43AF-B466-55825C7962FE}.Debug|x64.Build.0 = Debug|x64 + {862328A4-8632-43AF-B466-55825C7962FE}.Debug|x86.ActiveCfg = Debug|Win32 + {862328A4-8632-43AF-B466-55825C7962FE}.Debug|x86.Build.0 = Debug|Win32 + {862328A4-8632-43AF-B466-55825C7962FE}.Release|Any CPU.ActiveCfg = Release|Win32 + {862328A4-8632-43AF-B466-55825C7962FE}.Release|x64.ActiveCfg = Release|x64 + {862328A4-8632-43AF-B466-55825C7962FE}.Release|x64.Build.0 = Release|x64 + {862328A4-8632-43AF-B466-55825C7962FE}.Release|x86.ActiveCfg = Release|Win32 + {862328A4-8632-43AF-B466-55825C7962FE}.Release|x86.Build.0 = Release|Win32 + {116DFDB0-7681-46FE-8BAD-FE8AE09BB076}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {116DFDB0-7681-46FE-8BAD-FE8AE09BB076}.Debug|Any CPU.Build.0 = Debug|Any CPU + {116DFDB0-7681-46FE-8BAD-FE8AE09BB076}.Debug|x64.ActiveCfg = Debug|Any CPU + {116DFDB0-7681-46FE-8BAD-FE8AE09BB076}.Debug|x64.Build.0 = Debug|Any CPU + {116DFDB0-7681-46FE-8BAD-FE8AE09BB076}.Debug|x86.ActiveCfg = Debug|Any CPU + {116DFDB0-7681-46FE-8BAD-FE8AE09BB076}.Release|Any CPU.ActiveCfg = Release|Any CPU + {116DFDB0-7681-46FE-8BAD-FE8AE09BB076}.Release|Any CPU.Build.0 = Release|Any CPU + {116DFDB0-7681-46FE-8BAD-FE8AE09BB076}.Release|x64.ActiveCfg = Release|Any CPU + {116DFDB0-7681-46FE-8BAD-FE8AE09BB076}.Release|x64.Build.0 = Release|Any CPU + {116DFDB0-7681-46FE-8BAD-FE8AE09BB076}.Release|x86.ActiveCfg = Release|Any CPU + {116DFDB0-7681-46FE-8BAD-FE8AE09BB076}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2E47C63D-6176-460B-A475-E95BBEB03CA5} + EndGlobalSection +EndGlobal |
