Init source

This commit is contained in:
Davey Mathijssen
2017-11-13 12:26:01 +01:00
parent 68fd5ed22b
commit 08ea3ff8db
14 changed files with 1447 additions and 0 deletions
+33
View File
@@ -297,3 +297,36 @@ __pycache__/
*.btm.cs
*.odx.cs
*.xsd.cs
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
+31
View File
@@ -0,0 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.12
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AdvancedVision", "AdvancedVision.vcxproj", "{D07114EF-4EC2-45EE-944D-5A269C142C0F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {718B94D4-63F0-4DFC-84A7-C7CA7AF5ACA9}
EndGlobalSection
EndGlobal
+175
View File
@@ -0,0 +1,175 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.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">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{d07114ef-4ec2-45ee-944d-5a269c142c0f}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>AdvancedVision</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</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>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</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>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</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>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>C:\opencv\build\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalUsingDirectories>C:\opencv\build\include;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>C:\opencv\build\x64\vc14\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opencv_world330.lib;opencv_world330d.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>C:\opencv\build\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalUsingDirectories>C:\opencv\build\include;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>C:\opencv\build\x64\vc14\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>opencv_world330.lib;opencv_world330d.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>C:\opencv\build\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalUsingDirectories>C:\opencv\build\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>C:\opencv\build\x64\vc14\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>C:\opencv\build\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalUsingDirectories>C:\opencv\build\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>C:\opencv\build\x64\vc14\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="allContoursTestprogramma.cpp" />
<ClCompile Include="avansvisionlib.cpp" />
<ClCompile Include="Source.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="avansvisionlib.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,36 @@
<?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>
<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">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="avansvisionlib.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
+37
View File
@@ -0,0 +1,37 @@
========================================================================
CONSOLE APPLICATION : [!output PROJECT_NAME] Project Overview
========================================================================
AppWizard has created this [!output PROJECT_NAME] application for you.
This file contains a summary of what you will find in each of the files that
make up your [!output PROJECT_NAME] application.
This is the main project file for VC++ projects generated using an Application Wizard.
It contains information about the version of Visual C++ that generated the file, and
information about the platforms, configurations, and project features selected with the
Application Wizard.
This is the filters file for VC++ projects generated using an Application Wizard.
It contains information about the association between the files in your project
and the filters. This association is used in the IDE to show grouping of files with
similar extensions under a specific node (for e.g. ".cpp" files are associated with the
"Source Files" filter).
This is the main application source file.
/////////////////////////////////////////////////////////////////////////////
Other standard files:
StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file
named [!output PROJECT_NAME].pch and a precompiled types file named StdAfx.obj.
/////////////////////////////////////////////////////////////////////////////
Other notes:
AppWizard uses "TODO:" comments to indicate parts of the source code you
should add to or customize.
/////////////////////////////////////////////////////////////////////////////
+33
View File
@@ -0,0 +1,33 @@
#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>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat image = imread("input/Week2/basisfiguren.jpg", CV_LOAD_IMAGE_COLOR);
if (!image.data)
{
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);
return 0;
}
+106
View File
@@ -0,0 +1,106 @@
// Functionaliteit: Testprogramma voor het testen van de allContours() functie
// Zie module Vision C++ voor Gevorderden Opdracht 2 van Fase 1
// De demo laat met avansvisionlib en OpenCV de contouren zien.
//
// De algoritmiek wordt in de eerste workshop toegelicht.
//
// Jan Oostindie, dd 8-11-2016
//
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <string>
#include "avansvisionlib.h"
using namespace cv;
using namespace std;
int main(int argc, char *argv[])
{
// zie: project properties - configuration properties - debugging - command arguments
if (argc != 2)
{
cout << "NB! Geef als command argument volledige padnaam van de imagefile mee" << endl;
return -1;
}
else cout << "De imagefile = " << argv[1] << endl;
// Lees de afbeelding in
Mat image;
image = imread(argv[1], CV_LOAD_IMAGE_COLOR);
if (!image.data)
{
cout << "Could not open or find the image" << std::endl;
return -1;
}
// De afbeelding converteren naar een grijswaarde afbeelding
Mat gray_image;
cvtColor(image, gray_image, CV_BGR2GRAY);
// Converteren naar grijswaarde afbeelding
cout << "Imagefile: " << argv[1] << " met succes geconverteerd naar grijswaarde beeld." << endl;
////////////////////////////////////////////////////////////////////////////////
imshow("Original", gray_image);
waitKey(0);
/** ! Gebruik een region of interest voor de rummikub images **/
// Mat imageROI = gray_image(Rect(34, 28, 976, 82));
// imshow("imageROI", imageROI);
// waitKey(0);
// Grijswaarde afbeelding thresholden
Mat binaryImage;
/** ! Gebruik een region of interest voor de rummikub figuren **/
// threshold(imageROI, binaryImage, 65, 1, CV_THRESH_BINARY_INV);
// 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);
// 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);
show16SImageStretch(binary16S,"Binary image");
// haal de contouren uit het binary image
vector<vector<Point>> contours;
cout << "Contouren bepalen...";
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 = " << contours.size() << endl;
getline(cin, line);
for (int i = 0; i < contours.size(); i++) {
cout << "*** Contour " << i + 1 << " ***" << endl;
cout << "Press ENTER to continue....";
getline(cin, line);
for (int j = 0; j < contours[i].size(); j++) {
cout << "(" << contours[i][j].x << "," << contours[i][j].y << ")" << endl;
}
}
// Creeer een witte image
Mat contourImage = cvCreateImage(cvSize(binary16S.cols, binary16S.rows), IPL_DEPTH_8U, 3);
contourImage = Scalar(255, 255, 255);
// teken de contouren op de witte image
drawContours(contourImage, contours, -1, CV_RGB(255, 0, 0));
// druk het image met de contouren af
imshow("Found contours", contourImage);
waitKey(0);
string pipo;
cin >> pipo;
return 0;
}
+763
View File
@@ -0,0 +1,763 @@
// avansvisionlib - Growing Visionlibrary of Avans based on OpenCV 2.4.10
// Goal: deep understanding of vision algorithms by means of developing own (new) algorithms.
//
// Copyright Jan Oostindie, basic version 1.0 dd 8-11-2016. Contains basic functions to perform calculations on matrices/images of class Mat.
// Including BLOB labeling functions
//
// 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
#include "avansvisionlib.h"
#include <math.h>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
// pre: (i < m.rows) & (j < m.cols)
// Mat is call by reference
void setEntry(Mat m, int i, int j, double value) {
int index = i * m.cols + j;
double * p = m.ptr<double>(0);
p[index] = value;
} // setEntry
// pre: (i < m.rows) & (j < m.cols)
double getEntry(Mat m, int i, int j) {
int index = i * m.cols + j;
double * p = m.ptr<double>(0);
return *(p + index);
} // getEntry
// func: calculate product of a row and column of equal length
// pre: (row.cols == col.rows)
double inproduct(Mat row, Mat col) {
double * p1 = row.ptr<double>(0);
double * p2 = col.ptr<double>(0);
double sumproducts = 0;
for (int i = 0; i < row.cols; i++)
sumproducts += p1[i] * p2[i];
return sumproducts;
} // inproduct
void printMatrix(Mat m) {
for (int i = 0; i < m.rows; i++) {
for (int j = 0; j < m.cols; j++)
cout << getEntry(m, i, j) << " ";
cout << endl;
}
cout << endl;
} // printMatrix
Mat getRow(Mat m, int rowNr) {
Mat result = Mat_<double>(1, m.cols);
double entry;
for (int colNr = 0; colNr < m.cols; colNr++) {
entry = getEntry(m, rowNr, colNr);
// cout << " ** getRow ** " << endl;
// cout << " entry = " << entry << endl;
setEntry(result, 0, colNr, entry);
}
return result;
} // getRow
Mat getCol(Mat m, int colNr) {
Mat result = Mat_<double>(m.rows, 1);
double entry;
for (int rowNr = 0; rowNr < m.rows; rowNr++) {
entry = getEntry(m, rowNr, colNr);
// cout << " ** getColumn ** " << endl;
// cout << " entry = " << entry << endl;
setEntry(result, rowNr, 0, entry);
}
return result;
} // getCol
// pre: (a.cols == b.rows)
Mat multiply(Mat a, Mat b)
{
Mat result = Mat_<double>(a.rows, b.cols);
double inprod;
for (int arow = 0; arow < a.rows; arow++) {
for (int bcol = 0; bcol < b.cols; bcol++) {
inprod = inproduct(getRow(a, arow), getCol(b, bcol));
setEntry(result, arow, bcol, inprod);
}
}
return result;
} // multiply
// pre: matrices have equal dimensions i.e. (a.cols == b.cols) & (a.rows == b.rows)
Mat add(Mat a, Mat b)
{
Mat result = Mat_<double>(a.rows, a.cols);
double entrysum;
for (int row = 0; row < a.rows; row++) {
for (int col = 0; col < a.cols; col++) {
entrysum = getEntry(a, row, col) + getEntry(b, row, col);
setEntry(result, row, col, entrysum);
}
}
return result;
} // add
Mat transpose(Mat m) {
Mat result = Mat_<double>(m.cols, m.rows);
for (int row = 0; row < m.rows; row++)
for (int col = 0; col < m.cols; col++)
setEntry(result, col, row, getEntry(m, row, col));
return result;
} // transpose
// func: sets all entries of a matrix to a value
// pre: true
void setValue(Mat m, double value) {
for (int row = 0; row < m.rows; row++)
for (int col = 0; col < m.cols; col++)
setEntry(m, row, col, value);
} // setValue
double generateRandomValue(double min, double max) {
int steps = rand() % 100 + 1;
double dx = (max - min) / 100;
return min + dx * steps;
} // generateRandomValue
// func: sets all entries of a matrix to a random value in interval [min,max]
// pre: true
void setRandomValue(Mat m, double min, double max) {
srand(time(NULL));
for (int row = 0; row < m.rows; row++)
for (int col = 0; col < m.cols; col++)
setEntry(m, row, col, generateRandomValue(min, max));
} // randomValue
/*********************************** Image operaties ****************************************/
// NB images are supposed to have 1 channel (B/W image) and depth 16 bits signed (CV_16S)
/********************************************************************************************/
void setEntryImage(Mat m, int i, int j, _int16 value) {
int index = i * m.cols + j;
_int16 * p = m.ptr<_int16>(0);
p[index] = value;
} // setEntry
// pre: (i < m.rows) & (j < m.cols)
_int16 getEntryImage(Mat m, int i, int j) {
int index = i * m.cols + j;
_int16 * p = m.ptr<_int16>(0);
return *(p + index);
} // getEntryImage
// func: calculate product of a row and column of equal length
// pre: (row.cols == col.rows)
_int16 inproductImage(Mat row, Mat col) {
_int16 * p1 = row.ptr<_int16>(0);
_int16 * p2 = col.ptr<_int16>(0);
_int16 sumproducts = 0;
for (int i = 0; i < row.cols; i++)
sumproducts += p1[i] * p2[i];
return sumproducts;
} // inproductImage
Mat getRowImage(Mat m, int rowNr) {
Mat result = Mat_<_int16>(1, m.cols);
_int16 entry;
for (int colNr = 0; colNr < m.cols; colNr++) {
entry = getEntryImage(m, rowNr, colNr);
setEntryImage(result, 0, colNr, entry);
}
return result;
} // getRow
Mat getColImage(Mat m, int colNr) {
Mat result = Mat_<_int16>(m.rows, 1);
_int16 entry;
for (int rowNr = 0; rowNr < m.rows; rowNr++) {
entry = getEntryImage(m, rowNr, colNr);
setEntryImage(result, rowNr, 0, entry);
}
return result;
} // getColImage
Mat multiplyImage(Mat a, Mat b)
{
Mat result = Mat_<_int16>(a.rows, b.cols);
_int16 inprod;
for (int arow = 0; arow < a.rows; arow++) {
for (int bcol = 0; bcol < b.cols; bcol++) {
inprod = inproductImage(getRow(a, arow), getColImage(b, bcol));
setEntry(result, arow, bcol, inprod);
}
}
return result;
} // multiplyImage
// pre: matrices have equal dimensions i.e. (a.cols == b.cols) & (a.rows == b.rows)
Mat addImage(Mat a, Mat b)
{
Mat result = Mat_<_int16>(a.rows, a.cols);
_int16 entrysum;
for (int row = 0; row < a.rows; row++) {
for (int col = 0; col < a.cols; col++) {
entrysum = getEntryImage(a, row, col) + getEntryImage(b, row, col);
setEntryImage(result, row, col, entrysum);
}
}
return result;
} // addImage
// func: searches the maximum pixel value in the image
// return: maximum pixel
_int16 maxPixelImage(Mat m) {
_int16 max = getEntryImage(m, 0, 0);
_int16 next;
for (int row = 0; row < m.rows; row++) {
for (int col = 0; col < m.cols; col++) {
next = getEntryImage(m, row, col);
if (next > max) max = next;
}
}
return max;
} // maxPixelImage
// func: searches the minimum pixel value in the image
// return: minimum pixel value
_int16 minPixelImage(Mat m) {
_int16 min = getEntryImage(m, 0, 0);
_int16 next;
for (int row = 0; row < m.rows; row++) {
for (int col = 0; col < m.cols; col++) {
next = getEntryImage(m, row, col);
if (next < min) min = next;
}
}
return min;
} // minPixelImage
// 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) {
_int16 max = getEntryImage(m, 0, 0);
_int16 min = getEntryImage(m, 0, 0);
_int16 next;
for (int row = 0; row < m.rows; row++) {
for (int col = 0; col < m.cols; col++) {
next = getEntryImage(m, row, col);
if (next > max) max = next;
else
if (next < min) min = next;
}
}
minPixelValue = min;
maxPixelValue = max;
} // getPixelRangeImage
// func: stretches the image to a specified range
void stretchImage(Mat m, _int16 minPixelValue, _int16 maxPixelValue) {
_int16 min, max, oldValue, newValue;
getPixelRangeImage(m, min, max);
double scale = maxPixelValue - minPixelValue;
scale /= (max - min);
for (int row = 0; row < m.rows; row++) {
for (int col = 0; col < m.cols; col++) {
oldValue = getEntryImage(m, row, col);
newValue = scale * (oldValue - min) + minPixelValue;
setEntryImage(m, row, col, newValue);
}
}
} // stretchImage
// func: shows a 16S image on the screen
// pre: m is a 16S image (depth 16 bits, signed)
void show16SImageStretch(Mat m, string windowTitle) {
Mat mCopy;
m.copyTo(mCopy);
stretchImage(mCopy, 0, 255);
mCopy.convertTo(mCopy, CV_8U);
// namedWindow(windowTitle, CV_WINDOW_AUTOSIZE);
imshow(windowTitle, mCopy);
waitKey(0);
} // show16SImage
// 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) {
Mat mCopy;
m.copyTo(mCopy);
mCopy.convertTo(mCopy, CV_8U);
// namedWindow("show16SImageClip", CV_WINDOW_AUTOSIZE);
imshow(windowTitle, mCopy);
waitKey(0);
} // show16SImage
// 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) {
unsigned char lut[256];
for (int i = 0; i < 256; i++) {
lut[i] = saturate_cast<uchar>(pow((float)(i / 255.0), gamma) * 255.0f);
}
// dst = src.clone();
const int channels = image.channels();
switch (channels) {
case 1: {
MatIterator_<uchar> it, end;
for (it = image.begin<uchar>(), end = image.end<uchar>(); it != end; it++)
*it = lut[(*it)];
break;
}
case 3: {
MatIterator_<Vec3b> it, end;
for (it = image.begin<Vec3b>(), end = image.end<Vec3b>(); it != end; it++) {
(*it)[0] = lut[((*it)[0])];
(*it)[1] = lut[((*it)[1])];
(*it)[2] = lut[((*it)[2])];
}
break;
}
} // switch
} // gammaCorrection
// 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) {
Mat result = Mat_<_int16>(binaryImage.rows+2, binaryImage.cols+2);
// eerste rij 0 maken
for (int col = 0; col < result.cols; col++)
setEntryImage(result,0,col,0);
// binaryImage copieren naar admin waarbij een 1 steeds wordt omgezet naar -1.
for (int row = 1; row < (result.rows-1); row++) {
// 0 vooraan de rij zetten
setEntryImage(result,row,0,0);
// rij binaryImage copieren
_int16 value;
for (int col = 1; col < result.cols - 1; col++) {
value = getEntryImage(binaryImage, row - 1, col - 1);
if (value == 1) value = -1;
setEntryImage(result, row, col, value);
}
// 0 achteraan de rij zetten
setEntryImage(result, row, result.cols - 1, 0);
} // for
// laatste rij 0 maken
for (int col = 0; col < result.cols; col++)
setEntryImage(result, result.rows-1, col, 0);
return result;
} // makeAdmin
// func: Searches the next blob after position (row,col) i.e. searches
// the next -1 in admin
// post: if return_value == 1 then (row,col) contains the position
// where the next blob starts.
// return_value: 1 next blob found ; starting position is (row,col)
// 0 no blob found ; (row, col) == (-1, -1)
bool findNextBlob(Mat admin, int & row, int & col) {
bool found = false;
// zoeken in de huidige rij
for (int currCol = col; (currCol < (admin.cols - 1)) & !found; currCol++)
if (getEntryImage(admin, row, currCol) == -1) {
found = true;
// row unchanged
col = currCol;
}
// zoeken vanaf de volgende rij
for (int currRow = row+1; (currRow < (admin.rows-1)) &!found; currRow++)
for (int currCol = 1; (currCol < (admin.cols-1)) & !found; currCol++)
if (getEntryImage(admin, currRow, currCol) == -1) {
found = true;
row = currRow;
col = currCol;
}
if (!found) {
row = -1;
col = -1;
}
return found;
}; // findNextBlob
// 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) {
switch (nr) {
case 0: return getEntryImage(admin, x - 1, y ); break;
case 1: return getEntryImage(admin, x - 1, y + 1); break;
case 2: return getEntryImage(admin, x , y + 1); break;
case 3: return getEntryImage(admin, x + 1, y + 1); break;
case 4: return getEntryImage(admin, x + 1, y); break;
case 5: return getEntryImage(admin, x + 1, y - 1); break;
case 6: return getEntryImage(admin, x, y - 1); break;
case 7: return getEntryImage(admin, x - 1, y - 1); break;
default: cout << "ERROR getEntryNeighbour " << endl;
}
} // getEntryNeighbour
// func: determines if there are more than 1 adjacent 1's
bool moreNext1(const Mat & admin, int x, int y) {
int cnt1 = 0;
bool more = false;
for (int nr = 0; (nr <= 7) & !more; nr++)
if (getEntryNeighbour(admin, x, y, nr) == -1) {
cnt1++;
if (cnt1 > 1) more = true;
}
return more;
} // moreNext1
// 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) {
int rotX, rotY;
rotX = currX - 1 ; rotY = currY ; //0
if (getEntryImage(admin, rotX, rotY) == -1) next1 = 0;
else {
rotX = currX - 1; rotY = currY + 1; //1
if (getEntryImage(admin, rotX, rotY) == -1) next1 = 1;
else {
rotX = currX; rotY = currY + 1; //2
if (getEntryImage(admin, rotX, rotY) == -1) next1 = 2;
else {
rotX = currX + 1; rotY = currY + 1; //3
if (getEntryImage(admin, rotX, rotY) == -1) next1 = 3;
else {
rotX = currX + 1; rotY = currY; //4
if (getEntryImage(admin, rotX, rotY) == -1) next1 = 4;
else {
rotX = currX + 1; rotY = currY - 1; //5
if (getEntryImage(admin, rotX, rotY) == -1) next1 = 5;
else {
rotX = currX; rotY = currY - 1; //6
if (getEntryImage(admin, rotX, rotY) == -1) next1 = 6;
else {
rotX = currX - 1; rotY = currY - 1; //7
if (getEntryImage(admin, rotX, rotY) == -1) next1 = 7;
else next1 = -99;
} // 6
} // 5
} // 4
} // 3
} // 2
} // 1
} //0
if (next1 >= 0) {
currX = rotX;
currY = rotY;
}
} // findNext1
// 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) {
// Every visited pixel is labeled with:
// blobNr*10 + <relative position to the parent >
//
// definition of relative positions
// 7 0 1
// 6 X 2
// 5 4 3
//
// The first visited pixel, i.e. (row,col), is labeled with:
// blobNr * 10 + 8
int x = row, y = col;
setEntryImage(admin, x, y, blobNr*10 + 8);
int next1 = -999;
int area = 1;
// flag more is set when any entry in the path has two or more
// unvisited neighbours because we visit only one at a time.
bool allLabeledFlag = true;
while (allLabeledFlag) {
allLabeledFlag = false;
bool pathLabeled = false;
while (!pathLabeled) {
if (!allLabeledFlag) allLabeledFlag = moreNext1(admin, x, y);
findNext1(admin, x, y, next1);
if (next1 >= 0) {
setEntryImage(admin, x, y, blobNr*10 + next1);
area++;
}
else {
//findprevious
switch (getEntryImage(admin, x, y) % 10) {
case 0: x += 1; break;
case 1: x += 1; y -= 1; break;
case 2: y -= 1; break;
case 3: x -= 1; y -= 1; break;
case 4: x -= 1; break;
case 5: x -= 1; y += 1; break;
case 6: y += 1; break;
case 7: x += 1; y += 1; break;
case 8: pathLabeled = true; break; // currIndex should be 0 now
default: cout << "Error func labelIter!";
} // case
} // else
} // while
} // while (more)
return area;
} // labelIter
// func: labels all pixels of one blob which starts at position (topX,topY) with blobNr.
// During the labeling proces the centre of gravity is calculated.
// This function is used by function labelBLOBInfo
// 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 labelIterInfo(Mat & admin, int topX, int topY, int blobNr,
int & xGravity, int & yGravity) {
// Every visited pixel is labeled with:
// blobNr*10 + <relative position to the parent >
//
// definition of relative positions
// 7 0 1
// 6 X 2
// 5 4 3
//
// The first visited pixel, i.e. (row,col), is labeled with:
// blobNr * 10 + 8
xGravity = topX;
yGravity = topY;
int x = topX, y = topY;
setEntryImage(admin, topX, topY, blobNr * 10 + 8);
int next1 = -999;
int area = 1;
// allLabeledFlag is set when any entry in the path has two or more
// unvisited neighbours because we visit only one at a time.
// This algorithm good be speeded up by using a stack (future improvement)
bool allLabeledFlag = true;
while (allLabeledFlag) {
allLabeledFlag = false;
bool pathLabeled = false;
while (!pathLabeled) {
if (!allLabeledFlag) allLabeledFlag = moreNext1(admin, x, y);
findNext1(admin, x, y, next1);
if (next1 >= 0) {
setEntryImage(admin, x, y, blobNr * 10 + next1);
area++;
xGravity += x;
yGravity += y;
}
else {
//findprevious
switch (getEntryImage(admin, x, y) % 10) {
case 0: x += 1; break;
case 1: x += 1; y -= 1; break;
case 2: y -= 1; break;
case 3: x -= 1; y -= 1; break;
case 4: x -= 1; break;
case 5: x -= 1; y += 1; break;
case 6: y += 1; break;
case 7: x += 1; y += 1; break;
case 8: pathLabeled = true; break; // currIndex should be 0 now
default: cout << "Error func labelIter!";
} // case
} // else
} // while
} // while (more)
xGravity /= area;
yGravity /= area;
return area;
} // labelIterInfo
// 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) {
int area = 0;
// bij waarde -1 is het pixel nog niet bezocht
if (getEntryImage(admin, row, col) == -1) {
//cout << "(row,col) = " << "(" << row << "," << col << ")" << endl;
// pixel labelen met het volgnummer van de blob
setEntryImage(admin, row, col, blobNr);
area = 1;
// alle pixels rondom huidige pixel bezoeken
// (row-1,col-1) (row-1,col ) (row-1,col+1)
// (row ,col-1) (row, col ) (row ,col+1)
// (row+1,col-1) (row, col ) (row+1,col+1)
area += labelRecursive(admin, row - 1, col, blobNr);
area += labelRecursive(admin, row - 1, col + 1, blobNr);
area += labelRecursive(admin, row, col + 1, blobNr);
area += labelRecursive(admin, row + 1, col + 1, blobNr);
area += labelRecursive(admin, row, col, blobNr);
area += labelRecursive(admin, row + 1, col - 1, blobNr);
area += labelRecursive(admin, row, col - 1, blobNr);
area += labelRecursive(admin, row - 1, col - 1, blobNr);
}
return area;
} // label
// 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) {
labeledImage = Mat_<_int16>(admin.rows-2,admin.cols-2);
for (int row = 1; row < admin.rows-1; row++) {
for (int col = 1; col < admin.cols-1; col++) {
setEntryImage(labeledImage, row-1,col-1,
getEntryImage(admin, row, col) / 10);
}
}
} // retrieveLabeledImage
// 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) {
// admin contains the administration of the recursive process.
// meaning of the entry values:
// -1: a "1" which is not visited yet. Changes to 1 when visited.
// 0: always a "0"
// 1, 2, 3,... : a "1" which is visited and is labeled with the object number.
Mat admin = makeAdmin(binaryImage);
int row = 1;
int col = 1;
// init volgnummer
int blobNr = 0;
// label alle BLOBs met een volgnummer
while ((row > 0) & (row < (admin.rows - 1)) &
(col > 0) & (col < (admin.cols - 1)))
if (findNextBlob(admin, row, col)) labelIter(admin, row, col, ++blobNr);
retrieveLabeledImage(admin, labeledImage);
// laatste volgnummer is gelijk aan het aantal gevonden blobs
return blobNr;
} // labelBLOBs
// func: removes a BLOB from the labeling administration
// pre: (posx,posy) is the position of the BLOB, blobNr the number
// of the blob to be removed.
void removeBLOB(Mat & admin, int blobNr) {
_int16 value;
for (int row = 1; row < admin.rows-2; row++)
for (int col = 1; col < admin.cols-2; col++) {
value = getEntryImage(admin, row, col);
while (value > 10) value /= 10;
if (value == blobNr) setEntryImage(admin, row, col, 0);
}
} // removeBLOB
// func: labeling of all blobs in a binary image with a area in [threhAreaMin,threhAreaMax]. 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, int threshAreaMax) {
// admin contains the administration of the recursive process.
// meaning of the entry values:
// -1: a "1" which is not visited yet.
// 0: always a "0"
// 1, 2, 3,... : a "1" which is visited and is labeled with the object number.
Mat admin = makeAdmin(binaryImage);
int row = 1;
int col = 1;
// init volgnummer
int blobNr = 0;
int area;
int xGravity, yGravity;
// label alle BLOBs met een volgnummer
while ((row > 0) & (row < (admin.rows - 1)) &
(col > 0) & (col < (admin.cols - 1)))
if (findNextBlob(admin, row, col)) {
area = labelIterInfo(admin, row, col, ++blobNr, xGravity, yGravity);
if ((area >= threshAreaMin) & (area <= threshAreaMax)) {
firstpixelVec.push_back(new Point2d(row - 1, col - 1));
posVec.push_back(new Point2d(xGravity-1, yGravity-1));
areaVec.push_back(area);
}
else removeBLOB(admin, blobNr--);
}
retrieveLabeledImage(admin, labeledImage);
// laatste volgnummer is gelijk aan het aantal gevonden blobs
return blobNr;
} // labelBLOBsInfo
+233
View File
@@ -0,0 +1,233 @@
// avansvisionlib - Growing Visionlibrary of Avans based on OpenCV 2.4.10
// Goal: deep understanding of vision algorithms by means of developing own (new) algorithms.
//
// Copyright Jan Oostindie, basic version 0.2 dd 15-9-2016. Contains basic functions to perform calculations on matrices/images of class Mat.
// Including BLOB labeling functions
//
// 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
#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 functioncall 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);
Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 693 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB