Initial Code v0.1.0

This commit is contained in:
jomjol
2020-08-07 17:42:29 +02:00
parent 0e2475bf0d
commit 4fe26dc0d8
269 changed files with 87264 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
#include "ClassFlow.h"
#include <fstream>
#include <string>
#include <iostream>
#include <string.h>
void ClassFlow::SetInitialParameter(void)
{
ListFlowControll = NULL;
}
std::vector<string> ClassFlow::ZerlegeZeile(std::string input)
{
std::vector<string> Output;
std::string delimiter = " =,";
input = trim(input, delimiter);
size_t pos = findDelimiterPos(input, delimiter);
std::string token;
while (pos != std::string::npos) {
token = input.substr(0, pos);
token = trim(token, delimiter);
Output.push_back(token);
input.erase(0, pos + 1);
input = trim(input, delimiter);
pos = findDelimiterPos(input, delimiter);
}
Output.push_back(input);
return Output;
}
bool ClassFlow::isNewParagraph(string input)
{
if (input[0] == '[')
return true;
return false;
}
bool ClassFlow::GetNextParagraph(FILE* pfile, string& aktparamgraph)
{
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph));
if (this->isNewParagraph(aktparamgraph))
return true;
return false;
}
ClassFlow::ClassFlow(void)
{
SetInitialParameter();
ListFlowControll = NULL;
}
ClassFlow::ClassFlow(std::vector<ClassFlow*> * lfc)
{
SetInitialParameter();
ListFlowControll = lfc;
}
bool ClassFlow::ReadParameter(FILE* pfile, string &aktparamgraph)
{
return false;
}
bool ClassFlow::doFlow(string time)
{
return false;
}
string ClassFlow::getReadout()
{
return string();
}
bool ClassFlow::getNextLine(FILE* pfile, string *rt)
{
char zw[1024];
if (pfile == NULL)
{
*rt = "";
return false;
}
fgets(zw, 1024, pfile);
printf("%s", zw);
if ((strlen(zw) == 0) && feof(pfile))
{
*rt = "";
return false;
}
*rt = zw;
*rt = trim(*rt);
while (zw[0] == '#' || (rt->size() == 0)) // Kommentarzeilen und Leerzeilen überspringen
{
fgets(zw, 1024, pfile);
printf("%s", zw);
if (feof(pfile))
{
*rt = "";
return false;
}
*rt = zw;
*rt = trim(*rt);
}
return true;
}

View File

@@ -0,0 +1,40 @@
#pragma once
#include <fstream>
#include <string>
#include <vector>
#include "Helper.h"
#include "CFindTemplate.h"
using namespace std;
struct HTMLInfo
{
float val;
std::string filename;
};
class ClassFlow
{
protected:
std::vector<string> ZerlegeZeile(string input);
bool isNewParagraph(string input);
bool GetNextParagraph(FILE* pfile, string& aktparamgraph);
bool getNextLine(FILE* pfile, string* rt);
std::vector<ClassFlow*>* ListFlowControll;
virtual void SetInitialParameter(void);
public:
ClassFlow(void);
ClassFlow(std::vector<ClassFlow*> * lfc);
virtual bool ReadParameter(FILE* pfile, string &aktparamgraph);
virtual bool doFlow(string time);
virtual string getReadout();
virtual string name(){return "ClassFlow";};
};

View File

@@ -0,0 +1,108 @@
#include "ClassFlowAlignment.h"
ClassFlowAlignment::ClassFlowAlignment()
{
initalrotate = 0;
anz_ref = 0;
suchex = 40;
suchey = 40;
namerawimage = "/sdcard/img_tmp/raw.jpg";
ListFlowControll = NULL;
}
ClassFlowAlignment::ClassFlowAlignment(std::vector<ClassFlow*>* lfc)
{
initalrotate = 0;
anz_ref = 0;
suchex = 40;
suchey = 40;
namerawimage = "/sdcard/img_tmp/raw.jpg";
ListFlowControll = lfc;
}
bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> zerlegt;
aktparamgraph = trim(aktparamgraph);
if (aktparamgraph.size() == 0)
if (!this->GetNextParagraph(pfile, aktparamgraph))
return false;
if (aktparamgraph.compare("[Alignment]") != 0) // Paragraph passt nich zu MakeImage
return false;
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
zerlegt = this->ZerlegeZeile(aktparamgraph);
if ((zerlegt[0] == "InitalRotate") && (zerlegt.size() > 1))
{
this->initalrotate = std::stod(zerlegt[1]);
}
if ((zerlegt[0] == "SearchFieldX") && (zerlegt.size() > 1))
{
this->suchex = std::stod(zerlegt[1]);
}
if ((zerlegt[0] == "SearchFieldY") && (zerlegt.size() > 1))
{
this->suchey = std::stod(zerlegt[1]);
}
if ((zerlegt.size() == 3) && (anz_ref < 2))
{
this->reffilename[anz_ref] = FormatFileName("/sdcard" + zerlegt[0]);
this->ref_x[anz_ref] = std::stod(zerlegt[1]);
this->ref_y[anz_ref] = std::stod(zerlegt[2]);
anz_ref++;
}
}
return true;
}
bool ClassFlowAlignment::doFlow(string time)
{
string input = namerawimage;
string output = "/sdcard/img_tmp/rot.jpg";
string output3 = "/sdcard/img_tmp/rot_roi.jpg";
string output2 = "/sdcard/img_tmp/alg.jpg";
string output4 = "/sdcard/img_tmp/alg_roi.jpg";
input = FormatFileName(input);
output = FormatFileName(output);
output2 = FormatFileName(output2);
CRotate *rt;
if (this->initalrotate != 0)
{
rt = new CRotate(input);
rt->Rotate(this->initalrotate);
rt->SaveToFile(output);
delete rt;
}
else
{
CopyFile(input, output);
}
CAlignAndCutImage *caic;
caic = new CAlignAndCutImage(output);
caic->Align(this->reffilename[0], this->ref_x[0], this->ref_y[0], this->reffilename[1], this->ref_x[1], this->ref_y[1], suchex, suchey, output3);
caic->SaveToFile(output2);
printf("Startwriting Output4:%s\n", output4.c_str());
if (output4.length() > 0)
{
caic->drawRect(ref_x[0], ref_y[0], caic->t0_dx, caic->t0_dy, 255, 0, 0, 2);
caic->drawRect(ref_x[1], ref_y[1], caic->t1_dx, caic->t1_dy, 255, 0, 0, 2);
caic->SaveToFile(output4);
printf("Write output4: %s\n", output4.c_str());
}
delete caic;
// Align mit Templates
return true;
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include "ClassFlow.h"
#include "Helper.h"
#include <string>
using namespace std;
class ClassFlowAlignment :
public ClassFlow
{
protected:
float initalrotate;
string reffilename[2];
int ref_x[2], ref_y[2];
int anz_ref;
int suchex, suchey;
string namerawimage;
public:
ClassFlowAlignment();
ClassFlowAlignment(std::vector<ClassFlow*>* lfc);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string name(){return "ClassFlowAlignment";};
};

View File

@@ -0,0 +1,257 @@
#include "ClassFlowAnalog.h"
#include <math.h>
#include <iomanip>
#include <sstream>
// #define OHNETFLITE
#ifndef OHNETFLITE
#include "CTfLiteClass.h"
#endif
ClassFlowAnalog::ClassFlowAnalog()
{
isLogImage = false;
string cnnmodelfile = "";
modelxsize = 1;
modelysize = 1;
ListFlowControll = NULL;
}
ClassFlowAnalog::ClassFlowAnalog(std::vector<ClassFlow*>* lfc)
{
isLogImage = false;
string cnnmodelfile = "";
modelxsize = 1;
modelysize = 1;
ListFlowControll = NULL;
ListFlowControll = lfc;
}
string ClassFlowAnalog::getReadout()
{
int prev = -1;
string result = "";
for (int i = ROI.size() - 1; i >= 0; --i)
{
prev = ZeigerEval(ROI[i]->result, prev);
result = std::to_string(prev) + result;
}
return result;
}
int ClassFlowAnalog::ZeigerEval(float zahl, int ziffer_vorgaenger)
{
int ergebnis_nachkomma = ((int) floor(zahl * 10)) % 10;
int ergebnis_vorkomma = ((int) floor(zahl)) % 10;
int ergebnis, ergebnis_rating;
if (ziffer_vorgaenger == -1)
return ergebnis_vorkomma % 10;
ergebnis_rating = ergebnis_nachkomma - ziffer_vorgaenger;
if (ergebnis_nachkomma >= 5)
ergebnis_rating-=5;
else
ergebnis_rating+=5;
ergebnis = (int) round(zahl);
if (ergebnis_rating < 0)
ergebnis-=1;
if (ergebnis == -1)
ergebnis+=10;
ergebnis = ergebnis % 10;
return ergebnis;
}
bool ClassFlowAnalog::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> zerlegt;
aktparamgraph = trim(aktparamgraph);
if (aktparamgraph.size() == 0)
if (!this->GetNextParagraph(pfile, aktparamgraph))
return false;
if (aktparamgraph.compare("[Analog]") != 0) // Paragraph passt nich zu MakeImage
return false;
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
zerlegt = this->ZerlegeZeile(aktparamgraph);
if ((zerlegt[0] == "LogImageLocation") && (zerlegt.size() > 1))
{
this->isLogImage = true;
this->LogImageLocation = zerlegt[1];
}
if ((zerlegt[0] == "Model") && (zerlegt.size() > 1))
{
this->cnnmodelfile = zerlegt[1];
}
if ((zerlegt[0] == "ModelInputSize") && (zerlegt.size() > 2))
{
this->modelxsize = std::stoi(zerlegt[1]);
this->modelysize = std::stoi(zerlegt[2]);
}
if (zerlegt.size() >= 5)
{
roianalog* neuroi = new roianalog;
neuroi->name = zerlegt[0];
neuroi->posx = std::stoi(zerlegt[1]);
neuroi->posy = std::stoi(zerlegt[2]);
neuroi->deltax = std::stoi(zerlegt[3]);
neuroi->deltay = std::stoi(zerlegt[4]);
ROI.push_back(neuroi);
}
}
return true;
}
bool ClassFlowAnalog::doFlow(string time)
{
doAlignAndCut(time);
doNeuralNetwork(time);
return true;
}
bool ClassFlowAnalog::doAlignAndCut(string time)
{
string input = "/sdcard/img_tmp/alg.jpg";
string input_roi = "/sdcard/img_tmp/alg_roi.jpg";
string ioresize = "/sdcard/img_tmp/resize.bmp";
string output;
string nm;
input = FormatFileName(input);
input_roi = FormatFileName(input_roi);
CResizeImage *rs;
CImageBasis *img_roi = NULL;
CAlignAndCutImage *caic = new CAlignAndCutImage(input);
if (input_roi.length() > 0)
img_roi = new CImageBasis(input_roi);
for (int i = 0; i < ROI.size(); ++i)
{
printf("Analog %d - Align&Cut\n", i);
output = "/sdcard/img_tmp/" + ROI[i]->name + ".jpg";
output = FormatFileName(output);
caic->CutAndSave(output, ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay);
rs = new CResizeImage(output);
rs->Resize(modelxsize, modelysize);
ioresize = "/sdcard/img_tmp/ra" + std::to_string(i) + ".bmp";
ioresize = FormatFileName(ioresize);
rs->SaveToFile(ioresize);
delete rs;
if (img_roi)
{
int r = 0;
int g = 255;
int b = 0;
img_roi->drawRect(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, r, g, b, 1);
img_roi->drawCircle((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) (ROI[i]->deltax/2), r, g, b, 2);
img_roi->drawLine((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) ROI[i]->posy, (int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay), r, g, b, 2);
img_roi->drawLine((int) ROI[i]->posx, (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) ROI[i]->posx + ROI[i]->deltax, (int) (ROI[i]->posy + ROI[i]->deltay/2), r, g, b, 2);
}
}
delete caic;
if (img_roi)
{
img_roi->SaveToFile(input_roi);
delete img_roi;
}
return true;
}
bool ClassFlowAnalog::doNeuralNetwork(string time)
{
string input = "/sdcard/img_tmp/alg.jpg";
string ioresize = "/sdcard/img_tmp/resize.bmp";
string output;
string nm;
input = FormatFileName(input);
#ifndef OHNETFLITE
CTfLiteClass *tflite = new CTfLiteClass;
string zwcnn = "/sdcard" + cnnmodelfile;
zwcnn = FormatFileName(zwcnn);
printf(zwcnn.c_str());printf("\n");
tflite->LoadModel(zwcnn);
tflite->MakeAllocate();
#endif
for (int i = 0; i < ROI.size(); ++i)
{
printf("Analog %d - TfLite\n", i);
ioresize = "/sdcard/img_tmp/ra" + std::to_string(i) + ".bmp";
ioresize = FormatFileName(ioresize);
float f1, f2;
f1 = 0; f2 = 0;
#ifndef OHNETFLITE
tflite->LoadInputImage(ioresize);
tflite->Invoke();
f1 = tflite->GetOutputValue(0);
f2 = tflite->GetOutputValue(1);
#endif
float result = fmod(atan2(f1, f2) / (M_PI * 2) + 2, 1);
// printf("Result sin, cos, ziffer: %f, %f, %f\n", f1, f2, result);
ROI[i]->result = result * 10;
printf("Result Analog%i: %f\n", i, ROI[i]->result);
if (isLogImage)
{
std::stringstream stream;
stream << std::fixed << std::setprecision(1) << ROI[i]->result;
std::string s = stream.str();
// std::snprintf(&s[0], s.size(), "%.2f", pi);
nm = "/sdcard" + LogImageLocation + "/" + s + "_" + ROI[i]->name + "_" + time + ".jpg";
nm = FormatFileName(nm);
output = "/sdcard/img_tmp/" + ROI[i]->name + ".jpg";
output = FormatFileName(output);
printf("Analog - save to file: %s\n", nm.c_str());
CopyFile(output, nm);
}
}
#ifndef OHNETFLITE
delete tflite;
#endif
return true;
}
std::vector<HTMLInfo*> ClassFlowAnalog::GetHTMLInfo()
{
std::vector<HTMLInfo*> result;
for (int i = 0; i < ROI.size(); ++i)
{
HTMLInfo *zw = new HTMLInfo;
zw->filename = ROI[i]->name + ".jpg";
zw->val = ROI[i]->result;
result.push_back(zw);
}
return result;
}

View File

@@ -0,0 +1,36 @@
#pragma once
#include "ClassFlow.h"
// #include "CTfLiteClass.h"
struct roianalog {
int posx, posy, deltax, deltay;
float result;
string name;
};
class ClassFlowAnalog :
public ClassFlow
{
protected:
string LogImageLocation;
bool isLogImage;
std::vector<roianalog*> ROI;
string cnnmodelfile;
int modelxsize, modelysize;
int ZeigerEval(float zahl, int ziffer_vorgaenger);
public:
ClassFlowAnalog();
ClassFlowAnalog(std::vector<ClassFlow*>* lfc);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string getReadout();
bool doNeuralNetwork(string time);
bool doAlignAndCut(string time);
std::vector<HTMLInfo*> GetHTMLInfo();
string name(){return "ClassFlowAnalog";};
};

View File

@@ -0,0 +1,212 @@
#include "ClassFlowControll.h"
#include "Helper.h"
std::vector<HTMLInfo*> ClassFlowControll::GetAllDigital()
{
for (int i = 0; i < FlowControll.size(); ++i)
if (FlowControll[i]->name().compare("ClassFlowDigit") == 0)
return ((ClassFlowDigit*) (FlowControll[i]))->GetHTMLInfo();
std::vector<HTMLInfo*> empty;
return empty;
}
std::vector<HTMLInfo*> ClassFlowControll::GetAllAnalog()
{
for (int i = 0; i < FlowControll.size(); ++i)
if (FlowControll[i]->name().compare("ClassFlowAnalog") == 0)
return ((ClassFlowAnalog*) (FlowControll[i]))->GetHTMLInfo();
std::vector<HTMLInfo*> empty;
return empty;
}
void ClassFlowControll::SetInitialParameter(void)
{
AutoStart = false;
AutoIntervall = 10;
}
bool ClassFlowControll::isAutoStart(long &_intervall)
{
_intervall = AutoIntervall * 60 * 1000; // AutoIntervall: Minuten -> ms
return AutoStart;
}
ClassFlow* ClassFlowControll::CreateClassFlow(std::string _type)
{
ClassFlow* cfc = NULL;
_type = trim(_type);
if (_type.compare("[MakeImage]") == 0)
cfc = new ClassFlowMakeImage(&FlowControll);
if (_type.compare("[Alignment]") == 0)
cfc = new ClassFlowAlignment(&FlowControll);
if (_type.compare("[Analog]") == 0)
cfc = new ClassFlowAnalog(&FlowControll);
if (_type.compare("[Digits]") == 0)
cfc = new ClassFlowDigit(&FlowControll);
if (_type.compare("[PostProcessing]") == 0)
{
cfc = new ClassFlowPostProcessing(&FlowControll);
flowpostprocessing = (ClassFlowPostProcessing*) cfc;
}
if (cfc) // Wird nur angehangen, falls es nicht [AutoTimer] ist, denn dieses ist für FlowControll
FlowControll.push_back(cfc);
if (_type.compare("[AutoTimer]") == 0)
cfc = this;
return cfc;
}
void ClassFlowControll::InitFlow(std::string config)
{
int aktFlow;
bool handeled;
string line;
flowpostprocessing = NULL;
ClassFlow* cfc;
FILE* pFile;
config = FormatFileName(config);
pFile = fopen(config.c_str(), "r");
line = "";
handeled = true;
char zw[1024];
if (pFile != NULL)
{
fgets(zw, 1024, pFile);
printf("%s", zw);
line = std::string(zw);
}
while ((line.size() > 0) && !(feof(pFile)))
{
cfc = CreateClassFlow(line);
if (cfc)
{
cfc->ReadParameter(pFile, line);
}
else
{
fgets(zw, 1024, pFile);
printf("%s", zw);
line = std::string(zw);
}
}
fclose(pFile);
}
bool ClassFlowControll::doFlow(string time)
{
bool result = true;
for (int i = 0; i < FlowControll.size(); ++i)
result = result && FlowControll[i]->doFlow(time);
return result;
}
string ClassFlowControll::getReadout(bool _rawvalue = false)
{
if (flowpostprocessing)
return flowpostprocessing->getReadout();
string zw = "";
string result = "";
for (int i = 0; i < FlowControll.size(); ++i)
{
zw = FlowControll[i]->getReadout();
if (zw.length() > 0)
{
if (result.length() == 0)
result = zw;
else
result = result + "\t" + zw;
}
}
return result;
}
string ClassFlowControll::GetPrevalue()
{
if (flowpostprocessing)
{
return flowpostprocessing->GetPreValue();
}
return std::string();
}
std::string ClassFlowControll::UpdatePrevalue(std::string _newvalue)
{
float zw;
char* p;
_newvalue = trim(_newvalue);
// printf("Input UpdatePreValue: %s\n", _newvalue.c_str());
if (_newvalue.compare("0.0") == 0)
{
zw = 0;
}
else
{
zw = strtof(_newvalue.c_str(), &p);
if (zw == 0)
return "- Error in String to Value Conversion!!! Must be of format value=123.456";
}
if (flowpostprocessing)
{
flowpostprocessing->SavePreValue(zw);
return _newvalue;
}
return std::string();
}
bool ClassFlowControll::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> zerlegt;
aktparamgraph = trim(aktparamgraph);
if (aktparamgraph.size() == 0)
if (!this->GetNextParagraph(pfile, aktparamgraph))
return false;
if (aktparamgraph.compare("[AutoTimer]") != 0) // Paragraph passt nich zu MakeImage
return false;
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
zerlegt = this->ZerlegeZeile(aktparamgraph);
if ((zerlegt[0] == "AutoStart") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
{
AutoStart = true;
}
}
if ((zerlegt[0] == "Intervall") && (zerlegt.size() > 1))
{
AutoIntervall = std::stof(zerlegt[1]);
}
}
return true;
}

View File

@@ -0,0 +1,41 @@
#pragma once
#include <string>
#include "ClassFlow.h"
#include "ClassFlowMakeImage.h"
#include "ClassFlowAlignment.h"
#include "ClassFlowDigit.h"
#include "ClassFlowAnalog.h"
#include "ClassFlowPostProcessing.h"
class ClassFlowControll :
public ClassFlow
{
protected:
std::vector<ClassFlow*> FlowControll;
ClassFlowPostProcessing* flowpostprocessing;
ClassFlow* CreateClassFlow(std::string _type);
bool AutoStart;
float AutoIntervall;
void SetInitialParameter(void);
public:
void InitFlow(std::string config);
bool doFlow(string time);
string getReadout(bool _rawvalue);
string UpdatePrevalue(std::string _newvalue);
string GetPrevalue();
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool isAutoStart(long &_intervall);
std::vector<HTMLInfo*> GetAllDigital();
std::vector<HTMLInfo*> GetAllAnalog();
string name(){return "ClassFlowControll";};
};

View File

@@ -0,0 +1,210 @@
#include "ClassFlowDigit.h"
//#include "CFindTemplate.h"
//#include "CTfLiteClass.h"
// #define OHNETFLITE
#ifndef OHNETFLITE
#include "CTfLiteClass.h"
#endif
// #include "bitmap_image.hpp"
ClassFlowDigit::ClassFlowDigit()
{
isLogImage = false;
string cnnmodelfile = "";
modelxsize = 1;
modelysize = 1;
ListFlowControll = NULL;
}
ClassFlowDigit::ClassFlowDigit(std::vector<ClassFlow*>* lfc)
{
isLogImage = false;
string cnnmodelfile = "";
modelxsize = 1;
modelysize = 1;
ListFlowControll = NULL;
ListFlowControll = lfc;
}
string ClassFlowDigit::getReadout()
{
string rst = "";
for (int i = 0; i < ROI.size(); ++i)
{
if (ROI[i]->resultklasse == 10)
rst = rst + "N";
else
rst = rst + std::to_string(ROI[i]->resultklasse);
}
return rst;
}
bool ClassFlowDigit::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> zerlegt;
aktparamgraph = trim(aktparamgraph);
if (aktparamgraph.size() == 0)
if (!this->GetNextParagraph(pfile, aktparamgraph))
return false;
if (aktparamgraph.compare("[Digits]") != 0) // Paragraph passt nich zu MakeImage
return false;
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
zerlegt = this->ZerlegeZeile(aktparamgraph);
if ((zerlegt[0] == "LogImageLocation") && (zerlegt.size() > 1))
{
isLogImage = true;
LogImageLocation = zerlegt[1];
}
if ((zerlegt[0] == "Model") && (zerlegt.size() > 1))
{
cnnmodelfile = zerlegt[1];
}
if ((zerlegt[0] == "ModelInputSize") && (zerlegt.size() > 2))
{
modelxsize = std::stoi(zerlegt[1]);
modelysize = std::stoi(zerlegt[2]);
}
if (zerlegt.size() >= 5)
{
roi* neuroi = new roi;
neuroi->name = zerlegt[0];
neuroi->posx = std::stoi(zerlegt[1]);
neuroi->posy = std::stoi(zerlegt[2]);
neuroi->deltax = std::stoi(zerlegt[3]);
neuroi->deltay = std::stoi(zerlegt[4]);
ROI.push_back(neuroi);
}
}
return true;
}
bool ClassFlowDigit::doFlow(string time)
{
doAlignAndCut(time);
doNeuralNetwork(time);
return true;
}
bool ClassFlowDigit::doAlignAndCut(string time)
{
string input = "/sdcard/img_tmp/alg.jpg";
string input_roi = "/sdcard/img_tmp/alg_roi.jpg";
string ioresize = "/sdcard/img_tmp/resize.bmp";
string output;
string nm;
input = FormatFileName(input);
input_roi = FormatFileName(input_roi);
CResizeImage *rs;
CImageBasis *img_roi = NULL;
CAlignAndCutImage *caic = new CAlignAndCutImage(input);
if (input_roi.length() > 0)
img_roi = new CImageBasis(input_roi);
for (int i = 0; i < ROI.size(); ++i)
{
printf("DigitalDigit %d - Align&Cut\n", i);
output = "/sdcard/img_tmp/" + ROI[i]->name + ".jpg";
output = FormatFileName(output);
caic->CutAndSave(output, ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay);
rs = new CResizeImage(output);
rs->Resize(modelxsize, modelysize);
ioresize = "/sdcard/img_tmp/rd" + std::to_string(i) + ".bmp";
ioresize = FormatFileName(ioresize);
rs->SaveToFile(ioresize);
delete rs;
if (img_roi)
{
img_roi->drawRect(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, 0, 0, 255, 2);
}
}
delete caic;
if (img_roi)
{
img_roi->SaveToFile(input_roi);
delete img_roi;
}
return true;
}
bool ClassFlowDigit::doNeuralNetwork(string time)
{
string input = "/sdcard/img_tmp/alg.jpg";
string ioresize = "/sdcard/img_tmp/resize.bmp";
string output;
string nm;
input = FormatFileName(input);
#ifndef OHNETFLITE
CTfLiteClass *tflite = new CTfLiteClass;
string zwcnn = "/sdcard" + cnnmodelfile;
zwcnn = FormatFileName(zwcnn);
printf(zwcnn.c_str());printf("\n");
tflite->LoadModel(zwcnn);
tflite->MakeAllocate();
#endif
for (int i = 0; i < ROI.size(); ++i)
{
printf("DigitalDigit %d - TfLite\n", i);
ioresize = "/sdcard/img_tmp/rd" + std::to_string(i) + ".bmp";
ioresize = FormatFileName(ioresize);
// printf("output: %s, ioresize: %s\n", output.c_str(), ioresize.c_str());
ROI[i]->resultklasse = 0;
#ifndef OHNETFLITE
ROI[i]->resultklasse = tflite->GetClassFromImage(ioresize);
#endif
printf("Result Digit%i: %d\n", i, ROI[i]->resultklasse);
if (isLogImage)
{
nm = "/sdcard" + LogImageLocation + "/" + std::to_string(ROI[i]->resultklasse) + "/" + time + "_" + ROI[i]->name + ".jpg";
output = "/sdcard/img_tmp/" + ROI[i]->name + ".jpg";
output = FormatFileName(output);
nm = FormatFileName(nm);
CopyFile(output, nm);
}
}
#ifndef OHNETFLITE
delete tflite;
#endif
return true;
}
std::vector<HTMLInfo*> ClassFlowDigit::GetHTMLInfo()
{
std::vector<HTMLInfo*> result;
for (int i = 0; i < ROI.size(); ++i)
{
HTMLInfo *zw = new HTMLInfo;
zw->filename = ROI[i]->name + ".jpg";
zw->val = ROI[i]->resultklasse;
result.push_back(zw);
}
return result;
}

View File

@@ -0,0 +1,37 @@
#pragma once
#include "ClassFlow.h"
#include "Helper.h"
#include <string>
struct roi {
int posx, posy, deltax, deltay;
int resultklasse;
string name;
roi* next;
};
class ClassFlowDigit :
public ClassFlow
{
protected:
string LogImageLocation;
bool isLogImage;
std::vector<roi*> ROI;
string cnnmodelfile;
int modelxsize, modelysize;
bool doNeuralNetwork(string time);
bool doAlignAndCut(string time);
public:
ClassFlowDigit();
ClassFlowDigit(std::vector<ClassFlow*>* lfc);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string getReadout();
std::vector<HTMLInfo*> GetHTMLInfo();
string name(){return "ClassFlowDigit";};
};

View File

@@ -0,0 +1,154 @@
#include "ClassFlowMakeImage.h"
#include "Helper.h"
#include "CFindTemplate.h"
#include "ClassControllCamera.h"
#include <time.h>
esp_err_t ClassFlowMakeImage::camera_capture(){
string nm = namerawimage;
Camera.CaptureToFile(nm);
return ESP_OK;
}
void ClassFlowMakeImage::takePictureWithFlash(int flashdauer)
{
string nm = namerawimage;
if (isImageSize && (ImageQuality > 0))
Camera.SetQualitySize(ImageQuality, ImageSize);
printf("Start CaptureFile\n");
Camera.CaptureToFile(nm, flashdauer);
}
ClassFlowMakeImage::ClassFlowMakeImage()
{
isLogImage = false;
waitbeforepicture = 5;
isImageSize = false;
ImageQuality = -1;
TimeImageTaken = 0;
namerawimage = "/sdcard/img_tmp/raw.jpg";
}
ClassFlowMakeImage::ClassFlowMakeImage(std::vector<ClassFlow*>* lfc)
{
isLogImage = false;
waitbeforepicture = 5;
isImageSize = false;
ImageQuality = -1;
TimeImageTaken = 0;
namerawimage = "/sdcard/img_tmp/raw.jpg";
ListFlowControll = lfc;
}
bool ClassFlowMakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> zerlegt;
aktparamgraph = trim(aktparamgraph);
if (aktparamgraph.size() == 0)
if (!this->GetNextParagraph(pfile, aktparamgraph))
return false;
if (aktparamgraph.compare("[MakeImage]") != 0) // Paragraph passt nich zu MakeImage
return false;
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
zerlegt = this->ZerlegeZeile(aktparamgraph);
if ((zerlegt[0] == "LogImageLocation") && (zerlegt.size() > 1))
{
this->isLogImage = true;
this->LogImageLocation = zerlegt[1];
}
if ((zerlegt[0] == "ImageQuality") && (zerlegt.size() > 1))
this->ImageQuality = std::stod(zerlegt[1]);
if ((zerlegt[0] == "ImageSize") && (zerlegt.size() > 1))
{
ImageSize = Camera.TextToFramesize(zerlegt[1].c_str());
isImageSize = true;
}
}
return true;
}
void ClassFlowMakeImage::CopyFile(string input, string output)
{
input = FormatFileName(input);
output = FormatFileName(output);
input = namerawimage;
printf("Copy Input : %s\n", input.c_str());
printf("Copy Output: %s\n", output.c_str());
char cTemp;
FILE* fpSourceFile = fopen(input.c_str(), "rb");
FILE* fpTargetFile = fopen(output.c_str(), "wb");
if (fpSourceFile == NULL)
{
printf("fpSourceFile == NULL\n");
perror("Error");
}
if (fpTargetFile == NULL)
{
printf("fpTargetFile == NULL\n");
perror("Error");
}
while (fread(&cTemp, 1, 1, fpSourceFile) == 1)
{
fwrite(&cTemp, 1, 1, fpTargetFile);
}
// Close The Files
fclose(fpSourceFile);
fclose(fpTargetFile);
printf("Copy done\n");
}
bool ClassFlowMakeImage::doFlow(string zwtime)
{
////////////////////////////////////////////////////////////////////
// TakeImage and Store into /image_tmp/raw.jpg TO BE DONE
////////////////////////////////////////////////////////////////////
int flashdauer = (int) waitbeforepicture * 1000;
takePictureWithFlash(flashdauer);
time(&TimeImageTaken);
localtime(&TimeImageTaken);
if (this->isLogImage)
{
string nm = "/sdcard" + this->LogImageLocation + "/" + zwtime + ".jpg";
string input = "/sdcard/image_tmp/raw.jgp";
printf("loginput from: %s to: %s\n", input.c_str(), nm.c_str());
nm = FormatFileName(nm);
input = FormatFileName(input);
CopyFile(input, nm);
}
return true;
}
time_t ClassFlowMakeImage::getTimeImageTaken()
{
return TimeImageTaken;
}

View File

@@ -0,0 +1,41 @@
#pragma once
#include "ClassFlow.h"
#include "ClassControllCamera.h"
#include <string>
static const char* TAG2 = "example";
#define BLINK_GPIO GPIO_NUM_4
#define CAMERA_MODEL_AI_THINKER
class ClassFlowMakeImage :
public ClassFlow
{
protected:
string LogImageLocation;
bool isLogImage;
float waitbeforepicture;
framesize_t ImageSize;
bool isImageSize;
int ImageQuality;
time_t TimeImageTaken;
string namerawimage;
void CopyFile(string input, string output);
esp_err_t camera_capture();
void takePictureWithFlash(int flashdauer);
public:
ClassFlowMakeImage();
ClassFlowMakeImage(std::vector<ClassFlow*>* lfc);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
time_t getTimeImageTaken();
string name(){return "ClassFlowMakeImage";};
};

View File

@@ -0,0 +1,302 @@
#include "ClassFlowPostProcessing.h"
#include "Helper.h"
#include "ClassFlowAnalog.h"
#include "ClassFlowDigit.h"
#include "ClassFlowMakeImage.h"
#include <time.h>
string ClassFlowPostProcessing::GetPreValue()
{
return to_string(PreValue);
}
bool ClassFlowPostProcessing::LoadPreValue(void)
{
FILE* pFile;
char zw[1024];
string zwtime, zwvalue;
pFile = fopen(FilePreValue.c_str(), "r");
if (pFile == NULL)
return false;
fgets(zw, 1024, pFile);
printf("%s", zw);
zwtime = trim(std::string(zw));
fgets(zw, 1024, pFile);
printf("%s", zw);
zwvalue = trim(std::string(zw));
PreValue = stof(zwvalue.c_str());
time_t tStart;
int yy, month, dd, hh, mm, ss;
struct tm whenStart;
sscanf(zwtime.c_str(), "%d-%d-%d_%d-%d-%d", &yy, &month, &dd, &hh, &mm, &ss);
whenStart.tm_year = yy - 1900;
whenStart.tm_mon = month - 1;
whenStart.tm_mday = dd;
whenStart.tm_hour = hh;
whenStart.tm_min = mm;
whenStart.tm_sec = ss;
whenStart.tm_isdst = -1;
tStart = mktime(&whenStart);
time_t now;
time(&now);
localtime(&now);
double difference = difftime(now, tStart);
difference /= 60;
if (difference > PreValueAgeStartup)
return false;
return true;
}
void ClassFlowPostProcessing::SavePreValue(float value, string zwtime)
{
FILE* pFile;
PreValue = value;
pFile = fopen(FilePreValue.c_str(), "w");
if (strlen(zwtime.c_str()) == 0)
{
time_t rawtime;
struct tm* timeinfo;
char buffer[80];
time(&rawtime);
timeinfo = localtime(&rawtime);
strftime(buffer, 80, "%Y-%m-%d_%H-%M-%S", timeinfo);
zwtime = std::string(buffer);
}
fputs(zwtime.c_str(), pFile);
fputs("\n", pFile);
fputs(to_string(value).c_str(), pFile);
fputs("\n", pFile);
fclose(pFile);
}
ClassFlowPostProcessing::ClassFlowPostProcessing()
{
PreValueUse = false;
PreValueAgeStartup = 30;
AllowNegativeRates = false;
MaxRateValue = 0.1;
ErrorMessage = false;
ListFlowControll = NULL;
PreValueOkay = false;
useMaxRateValue = false;
FilePreValue = FormatFileName("/sdcard/config/prevalue.ini");
}
ClassFlowPostProcessing::ClassFlowPostProcessing(std::vector<ClassFlow*>* lfc)
{
PreValueUse = false;
PreValueAgeStartup = 30;
AllowNegativeRates = false;
MaxRateValue = 0.1;
ErrorMessage = false;
ListFlowControll = NULL;
PreValueOkay = false;
useMaxRateValue = false;
FilePreValue = FormatFileName("/sdcard/config/prevalue.ini");
ListFlowControll = lfc;
}
bool ClassFlowPostProcessing::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> zerlegt;
aktparamgraph = trim(aktparamgraph);
if (aktparamgraph.size() == 0)
if (!this->GetNextParagraph(pfile, aktparamgraph))
return false;
if (aktparamgraph.compare("[PostProcessing]") != 0) // Paragraph passt nich zu MakeImage
return false;
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
zerlegt = this->ZerlegeZeile(aktparamgraph);
if ((zerlegt[0] == "PreValueUse") && (zerlegt.size() > 1))
{
if ((zerlegt[1] == "True") || (zerlegt[1] == "true"))
{
PreValueUse = true;
PreValueOkay = LoadPreValue();
}
}
if ((zerlegt[0] == "AllowNegativeRates") && (zerlegt.size() > 1))
{
if ((zerlegt[1] == "True") || (zerlegt[1] == "true"))
AllowNegativeRates = true;
}
if ((zerlegt[0] == "ErrorMessage") && (zerlegt.size() > 1))
{
if ((zerlegt[1] == "True") || (zerlegt[1] == "true"))
ErrorMessage = true;
}
if ((zerlegt[0] == "PreValueAgeStartup") && (zerlegt.size() > 1))
{
PreValueAgeStartup = std::stoi(zerlegt[1]);
}
if ((zerlegt[0] == "MaxRateValue") && (zerlegt.size() > 1))
{
useMaxRateValue = true;
MaxRateValue = std::stof(zerlegt[1]);
}
}
return true;
}
bool ClassFlowPostProcessing::doFlow(string zwtime)
{
string result = "";
string digit = "";
string analog = "";
bool isdigit = false;
bool isanalog = false;
string zw;
string error = "";
time_t imagetime = 0;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowMakeImage") == 0)
{
imagetime = ((ClassFlowMakeImage*)(*ListFlowControll)[i])->getTimeImageTaken();
}
if (((*ListFlowControll)[i])->name().compare("ClassFlowDigit") == 0)
{
isdigit = true;
digit = (*ListFlowControll)[i]->getReadout();
}
if (((*ListFlowControll)[i])->name().compare("ClassFlowAnalog") == 0)
{
isanalog = true;
analog = (*ListFlowControll)[i]->getReadout();
}
}
if (imagetime == 0)
time(&imagetime);
struct tm* timeinfo;
timeinfo = localtime(&imagetime);
char strftime_buf[64];
strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%d_%H-%M-%S", timeinfo);
zwtime = std::string(strftime_buf);
// // TESTING ONLY////////////////////
// isdigit = true; digit = "12N";
// isanalog = true; analog = "456";
if (!PreValueUse || !PreValueOkay)
{
if (isdigit)
ReturnValue = digit;
if (isdigit && isanalog)
ReturnValue = ReturnValue + ".";
if (isanalog)
ReturnValue = ReturnValue + analog;
if ((findDelimiterPos(ReturnValue, "N") == std::string::npos) && (ReturnValue.length() > 0))
{
while ((ReturnValue.length() > 1) && (ReturnValue[0] == '0'))
{
ReturnValue.erase(0, 1);
}
ReturnRawValue = ReturnValue;
Value = std::stof(ReturnValue);
SavePreValue(Value, zwtime);
}
return true;
}
if (isdigit)
{
digit = ErsetzteN(digit);
zw = zw + digit;
}
if (isdigit && isanalog)
zw = zw + ".";
if (isanalog)
zw = zw + analog;
ReturnRawValue = zw;
Value = std::stof(zw);
if ((!AllowNegativeRates) && (Value < PreValue))
{
error = "Negative Rate - Return old value - " + std::to_string(Value);
Value = PreValue;
}
if (useMaxRateValue && ((Value - PreValue) > MaxRateValue))
{
error = "Negative Rate - Return old value - " + std::to_string(Value);
Value = PreValue;
}
ReturnValue = std::to_string(Value);
if (ErrorMessage && (error.length() > 0))
ReturnValue = ReturnValue + "\t" + error;
if (error.length() == 0)
SavePreValue(Value, zwtime);
return true;
}
string ClassFlowPostProcessing::getReadout()
{
return ReturnValue;
}
string ClassFlowPostProcessing::getReadoutParam(bool _rawValue)
{
if (_rawValue)
return ReturnRawValue;
return ReturnValue;
}
string ClassFlowPostProcessing::ErsetzteN(string input)
{
int posN, posPunkt;
int pot, ziffer;
float zw;
posN = findDelimiterPos(input, "N");
posPunkt = input.length();
while (posN != std::string::npos)
{
pot = posPunkt - posN - 1;
zw = PreValue / pow(10, pot);
ziffer = ((int) zw) % 10;
input[posN] = ziffer + 48;
posN = findDelimiterPos(input, "N");
}
return input;
}

View File

@@ -0,0 +1,42 @@
#pragma once
#include "ClassFlow.h"
#include <string>
class ClassFlowPostProcessing :
public ClassFlow
{
protected:
bool PreValueUse;
int PreValueAgeStartup;
bool AllowNegativeRates;
float MaxRateValue;
bool useMaxRateValue;
bool ErrorMessage;
bool PreValueOkay;
string FilePreValue;
float PreValue;
float Value;
string ReturnValue;
string ReturnRawValue;
bool LoadPreValue(void);
string ErsetzteN(string);
public:
ClassFlowPostProcessing();
ClassFlowPostProcessing(std::vector<ClassFlow*>* lfc);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string getReadout();
string getReadoutParam(bool _rawValue);
void SavePreValue(float value, string time = "");
string GetPreValue();
string name(){return "ClassFlowPostProcessing";};
};

View File

@@ -0,0 +1,157 @@
//#pragma warning(disable : 4996)
#include "Helper.h"
//#define ISWINDOWS_TRUE
using namespace std;
std::string FormatFileName(std::string input)
{
#ifdef ISWINDOWS_TRUE
input.erase(0, 1);
std::string os = "/";
std::string ns = "\\";
FindReplace(input, os, ns);
#endif
return input;
}
void FindReplace(std::string& line, std::string& oldString, std::string& newString) {
const size_t oldSize = oldString.length();
// do nothing if line is shorter than the string to find
if (oldSize > line.length()) return;
const size_t newSize = newString.length();
for (size_t pos = 0; ; pos += newSize) {
// Locate the substring to replace
pos = line.find(oldString, pos);
if (pos == std::string::npos) return;
if (oldSize == newSize) {
// if they're same size, use std::string::replace
line.replace(pos, oldSize, newString);
}
else {
// if not same size, replace by erasing and inserting
line.erase(pos, oldSize);
line.insert(pos, newString);
}
}
}
bool ctype_space(const char c, string adddelimiter)
{
if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == 11)
{
return true;
}
if (adddelimiter.find(c) != string::npos)
return true;
return false;
}
string trim(string istring, string adddelimiter)
{
bool trimmed = false;
if (ctype_space(istring[istring.length() - 1], adddelimiter))
{
istring.erase(istring.length() - 1);
trimmed = true;
}
if (ctype_space(istring[0], adddelimiter))
{
istring.erase(0, 1);
trimmed = true;
}
if ((trimmed == false) || (istring.size() == 0))
{
return istring;
}
else
{
return trim(istring, adddelimiter);
}
}
size_t findDelimiterPos(string input, string delimiter)
{
size_t pos = std::string::npos;
size_t zw;
string akt_del;
for (int anz = 0; anz < delimiter.length(); ++anz)
{
akt_del = delimiter[anz];
if ((zw = input.find(akt_del)) != std::string::npos)
{
if (pos != std::string::npos)
{
if (zw < pos)
pos = zw;
}
else
pos = zw;
}
}
return pos;
}
void CopyFile(string input, string output)
{
input = FormatFileName(input);
output = FormatFileName(output);
char cTemp;
FILE* fpSourceFile = fopen(input.c_str(), "rb");
FILE* fpTargetFile = fopen(output.c_str(), "wb");
// Code Section
// Read From The Source File - "Copy"
while (fread(&cTemp, 1, 1, fpSourceFile) == 1)
{
// Write To The Target File - "Paste"
fwrite(&cTemp, 1, 1, fpTargetFile);
}
// Close The Files
fclose(fpSourceFile);
fclose(fpTargetFile);
}
string getFileType(string filename)
{
int lastpos = filename.find(".", 0);
int neu_pos;
while ((neu_pos = filename.find(".", lastpos + 1)) > -1)
{
lastpos = neu_pos;
}
string zw = filename.substr(lastpos + 1, filename.size() - lastpos);
return zw;
}
string toUpper(string in)
{
for (int i = 0; i < in.length(); ++i)
in[i] = toupper(in[i]);
return in;
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include <string>
#include <fstream>
using namespace std;
std::string FormatFileName(std::string input);
void FindReplace(std::string& line, std::string& oldString, std::string& newString);
void CopyFile(string input, string output);
size_t findDelimiterPos(string input, string delimiter);
//string trim(string istring);
string trim(string istring, string adddelimiter = "");
bool ctype_space(const char c, string adddelimiter);
string getFileType(string filename);
string toUpper(string in);

View File

@@ -0,0 +1,101 @@
#ifndef CAMERADEFINED
#define CAMERADEFINED
#if defined(CAMERA_MODEL_WROVER_KIT)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 21
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 19
#define Y4_GPIO_NUM 18
#define Y3_GPIO_NUM 5
#define Y2_GPIO_NUM 4
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 25
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 32
#define VSYNC_GPIO_NUM 22
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#elif defined(CAMERA_MODEL_AI_THINKER)
#define PWDN_GPIO_NUM GPIO_NUM_32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM GPIO_NUM_0
#define SIOD_GPIO_NUM GPIO_NUM_26
#define SIOC_GPIO_NUM GPIO_NUM_27
#define Y9_GPIO_NUM GPIO_NUM_35
#define Y8_GPIO_NUM GPIO_NUM_34
#define Y7_GPIO_NUM GPIO_NUM_39
#define Y6_GPIO_NUM GPIO_NUM_36
#define Y5_GPIO_NUM GPIO_NUM_21
#define Y4_GPIO_NUM GPIO_NUM_19
#define Y3_GPIO_NUM GPIO_NUM_18
#define Y2_GPIO_NUM GPIO_NUM_5
#define VSYNC_GPIO_NUM GPIO_NUM_25
#define HREF_GPIO_NUM GPIO_NUM_23
#define PCLK_GPIO_NUM GPIO_NUM_22
#else
#error "Camera model not selected"
#endif
static camera_config_t camera_config = {
.pin_pwdn = PWDN_GPIO_NUM,
.pin_reset = RESET_GPIO_NUM,
.pin_xclk = XCLK_GPIO_NUM,
.pin_sscb_sda = SIOD_GPIO_NUM,
.pin_sscb_scl = SIOC_GPIO_NUM,
.pin_d7 = Y9_GPIO_NUM,
.pin_d6 = Y8_GPIO_NUM,
.pin_d5 = Y7_GPIO_NUM,
.pin_d4 = Y6_GPIO_NUM,
.pin_d3 = Y5_GPIO_NUM,
.pin_d2 = Y4_GPIO_NUM,
.pin_d1 = Y3_GPIO_NUM,
.pin_d0 = Y2_GPIO_NUM,
.pin_vsync = VSYNC_GPIO_NUM,
.pin_href = HREF_GPIO_NUM,
.pin_pclk = PCLK_GPIO_NUM,
//XCLK 20MHz or 10MHz for OV2640 double FPS (Experimental)
.xclk_freq_hz = 20000000,
.ledc_timer = LEDC_TIMER_0,
.ledc_channel = LEDC_CHANNEL_0,
.pixel_format = PIXFORMAT_JPEG,//YUV422,GRAYSCALE,RGB565,JPEG
// .pixel_format = PIXFORMAT_RGB888,//YUV422,GRAYSCALE,RGB565,JPEG
// .frame_size = FRAMESIZE_QVGA,//QQVGA-QXGA Do not use sizes above QVGA when not JPEG
.frame_size = FRAMESIZE_SVGA,//QQVGA-QXGA Do not use sizes above QVGA when not JPEG
.jpeg_quality = 12, //0-63 lower number means higher quality
.fb_count = 1 //if more than one, i2s runs in continuous mode. Use only with JPEG
};
#endif