Recognition of a time series in an image based on a neural network

Good day, locals.





I have long wanted to post something suitable on Habr, but there was no idea.





And then I remembered about one of my projects, which sank into oblivion along with the repository on which it was recorded. This is a simplified model of my term paper, when I did it, the knowledge was in my head. And now you have to remember and do everything anew.





In general, this project will have two different images that the program will recognize. Both images are generated programmatically using the qt and c ++ framework.





In total, about 300 lines of code.





Here is the image data:





And second:





400 300 .





, , , , , 2 , , .





?





-, "y" - , "x" (400 ). , " " , .





2 :





w (t + 1) = w (t) -k * | x ​​[i] -w (t) |

k - , x[i] - "y" , w(t)- ,w(t+1) - . 2 , , ( x->f(x)->x).





:





.





:





k = 0,75 2- :









, , .





k , 10^-6 .





:





sum1 sum2 - "y" - ( )





v-v - V-, v 2533.56, w-v 39032.4 . : w w . .





10 :





, .





But if a straight line is drawn in the center horizontally, then it recognizes both classes better than neurons with errors of the 1st kind:





Next is the main.cpp program code:





#include <iostream>
#include <QtWidgets/QApplication>
#include "MainWindow.h"


int main(int argc,char*argv[])
{
    QApplication a(argc, argv);
    QWidget qw;
    MainWindow mw(&qw);
    mw.show();
    mw.CreateImage("");
    mw.CreateImage2("");
    mw.OpenImage("");
    mw.OpenImage2("");
    return a.exec();
}

      
      



Neuron.h:





#pragma once
#include <ctime>
#include <iostream>
#include <vector>
class Neuron
{
public:
	std::vector<double> x,  y, x0;
	double error;
	Neuron(std::vector<double> x, int length, int level);
	int level, length, min_, max_;
	std::vector<double>  Send();
	void Lerning(int steps);
	double Thinking(std::vector<double> xx);

	std::vector<double> SendW();

};
      
      



Neuron.cpp:





#include "Neuron.h"

Neuron::Neuron(std::vector<double> x,int length,int level)
{
	this->x = x;
	this->length = length;
	if (level == 2)
	{
		srand(time(NULL));
		min_ = 0;
		max_ = 300;
		for (size_t i = 0; i < length; i++)
		{
			x0.push_back(min_ + rand() % (max_ - min_ + 1)); 
			y.push_back(x0[i]);
			//std::cout << x0[i] << std::endl;
		}
	}
	this->level = level;
	this->error = 0.0;
}

std::vector<double> Neuron::Send()
{
	if (level == 1)
		return this->x;
	else
		return this->y;
}
std::vector<double> Neuron::SendW()
{
		return this->x0;
}
void Neuron::Lerning(int steps)
{
	float k = 0.75;
	for (size_t j = 0; j < steps; j++)
	{
		for (size_t i = 0; i < length; i++)
		{
			x0[i] = x0[i] + k* (x[i]-x0[i]);
		}
	}
}
double Neuron::Thinking(std::vector<double> xx)
{
	error = 0.0;
	for (size_t i = 0; i < length; i++)
	{
		y[i] = abs(xx[i] - x0[i]);
		error += y[i];
	}
	return error;
}

      
      



NeuralNet.h





#pragma once
#include "Neuron.h"
//#include <vector>
class NeuralNet
{
public:
	std::vector<Neuron*> l1,l2;
	void InitNeurons(std::vector<double> x, int length);
	void LearnNeurons(int steps, int i);
	double TestNeurons(int i, std::vector<double> xx);
};

      
      



NeuralNet.cpp





#include "NeuralNet.h"

void NeuralNet::InitNeurons(std::vector<double> x,int length)
{
	l1.push_back(new Neuron(x,length,1));
}
void NeuralNet::LearnNeurons(int steps,int i)
{
		l2.push_back(new Neuron(l1[i]->Send(), l1[i]->length, 2));
		l2[i]->Lerning(steps);
}
double NeuralNet::TestNeurons(int i, std::vector<double> xx)
{
	double res = 0.0 ;
	res = l2[i]->Thinking(xx);
	return res;
}

      
      



MainWindow.h





#pragma once
#include <QtWidgets/qmainwindow.h>
#include <QtGui/qpicture.h>
#include <QtGui/qimage.h>
#include <QtGui/qpainter.h>
#include <QtCore/qdebug.h> 
#include <vector>
#include <iostream>
#include <fstream> //   
#include <iomanip> 
#include "NeuralNet.h"
#pragma comment(lib,"Qt5Core.lib")
#pragma comment(lib,"Qt5Widgets.lib")
#pragma comment(lib,"Qt5Gui.lib")

namespace Ui {
    class MainWindow;
}
//Q_OBJECT
class MainWindow : public QMainWindow
{
    //Q_OBJECT
public:
    explicit MainWindow(QWidget* parent = 0);
    void CreateImage(QString path);
    void CreateImage2(QString path);
    void OpenImage(QString path);
    void OpenImage2(QString path);
    std::vector<double> x1, x2, zeros1, zeros2;
    QImage* image_t1, * image_t2 ;
    NeuralNet net;
    // ~MainWindow();
protected:
    void paintEvent(QPaintEvent*); //   
    
private:
    Ui::MainWindow* ui;
    
};
      
      



MainWindow.cpp





#include "MainWindow.h"
MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
{
    setWindowTitle(tr("Neural"));
    setGeometry(0, 0, 1000, 700);
}
void MainWindow::paintEvent(QPaintEvent*)
{
    QImage img("testImage.png"); //  
    QPainter painter(this); //   painter,   
    painter.drawImage(0, 0, img.scaled(this->size())); //     0,0     
}

void MainWindow::CreateImage(QString path)
{
    QImage image(QSize(400, 300), QImage::Format_RGB32);
    QPainter painter(&image);
    painter.fillRect(QRectF(0, 0, 400, 300), Qt::white);
    painter.setPen(QPen(Qt::black));
    painter.drawLine(0, 0, image.width() / 2, image.height());
    painter.drawLine(image.width() / 2, image.height(), image.width(), 0);

    image.save("testImage.png");
}
void MainWindow::CreateImage2(QString path)
{
    QImage image(QSize(400, 300), QImage::Format_RGB32);
    QPainter painter(&image);
    painter.fillRect(QRectF(0, 0, 400, 300), Qt::white);
    painter.setPen(QPen(Qt::black));
    painter.drawLine(0, 0, image.width() / 4, image.height());
    painter.drawLine(image.width() / 4, image.height() , image.width() / 2, 0);
    painter.drawLine(image.width() / 2, 0, 3 * image.width() / 4, image.height());
    painter.drawLine(3*image.width() / 4, image.height(), image.width() , 0);

    image.save("testImage2.png");
}

void MainWindow::OpenImage(QString path)
{
    image_t1 = new QImage("testImage.png");
    QPoint qp;
    std::ofstream fout("data.txt", std::ios_base::out | std::ios_base::trunc);

    for (int i = 0; i < image_t1->width(); i++)
    {
        for (int j = 0; j < image_t1->height(); j++)
        {
            qp.setX(i);
            qp.setY(j);
            if (image_t1->pixel(qp) != 4294967295/* 4278190080*/)
            {
                x1.push_back(j);
                zeros1.push_back(abs(150-j));
                //qDebug() << j << " ";
                fout << j<< std::endl;
                break;
            }
        }

    }
    qDebug() <<"size:"<< x1.size() << " ";
    int sum = 0;
    for (int j = 0; j < zeros1.size(); j++)
    {
        sum += zeros1[j];
    }
    qDebug() << "sum1=" << sum << " ";
    fout.close();
    
    net.InitNeurons(x1, x1.size());
    net.LearnNeurons(10,0);
    //net.TestNeurons(0);
    for (size_t i = 0; i < net.l2[0]->SendW().size(); i++)
    {
        qp.setX(i);
        qp.setY(int(net.l2[0]->SendW()[i]));
        image_t1->setPixel(qp, Qt::red);
    }
    image_t1->save("testImage1-1-1-1-000000.png");
    
}
void MainWindow::OpenImage2(QString path)
{
    image_t2 = new QImage("testImage2.png");
    QPoint qp;
    std::ofstream fout("data.txt", std::ios_base::out | std::ios_base::trunc);

    for (int i = 0; i < image_t2->width(); i++)
    {
        for (int j = 0; j < image_t2->height(); j++)
        {
            qp.setX(i);
            qp.setY(j);
            if (image_t2->pixel(qp) != 4294967295/* 4278190080*/)
            {
                x2.push_back(j);
                fout << j << std::endl;
                zeros2.push_back(abs(150 - j));
                //qDebug() << j << " ";
                break;
            }
        }

    }
    qDebug() << "size:" << x2.size() << " ";
    int sum = 0;
    for (int j = 0; j < zeros2.size(); j++)
    {
        sum += zeros2[j];
    }
    qDebug()<<"sum2=" << sum << " ";
    fout.close();
    
    net.InitNeurons(x2, x2.size());
    net.LearnNeurons(10,1);
    qDebug() <<"v - v"<< net.TestNeurons(0, x1);
    qDebug() <<"v - w"<< net.TestNeurons(0, x2);
    qDebug() <<"w - v"<< net.TestNeurons(1, x1);
    qDebug() <<"w - w"<< net.TestNeurons(1, x2);
    for (size_t i = 0; i < net.l2[1]->SendW().size(); i++)
    {
        qp.setX(i);
        qp.setY(int(net.l2[1]->SendW()[i]));
        //qDebug() << int(net.l2[1]->SendW()[i]) << " ";// std::endl;
        image_t2->setPixel(qp, Qt::red);
    }
    image_t2->save("testImage2-2-2-2-000000.png");
    
}

      
      



Thanks for attention!








All Articles