Problem z porownywaniem obrazow 2 obrazow .txt

0

Witam wszystkich ponownie! Jako czesc zadania na univerku musze porownac 2 obrazy w formacie tekstowym. Jeden z nich jest podzielony na bloki o rozmiarze 32x32 i pomieszany. Zadaniem jest zlozyc obraz w calosc.

Aby porownac obrazy uzywam algorytmu SSD (Sum of Squered Differences). Udaje mi sie porownac ze soba bloki, ale problem wystepuje podczas drugiej petli gdzie probuje stworzyc ostatni Matrix. Dostaje nastepujacy blad:

Unhandled exception at 0x00F1887C in test.exe: 0xC0000005: Access violation reading location 0x00CF1000.

Moje pytanie brzmi: Co powoduje ten blad i jak go naprawic?

To jest moj plik Matrix.h gdzie converuje matryce 2d na 1d

 #pragma
#ifndef MATRIX_H
#define MATRIX_H

class Matrix
{
protected:
    int M;
    int N; 
    double* data;
    Matrix(){M = 0; N = 0;data = 0;}                                                //Constructor to avoid error

public:

    Matrix(int sizeR, int sizeC, double* input_data);                               //Constructor
    Matrix(int sizeR, int sizeC);
    ~Matrix();                                                                      //Destructor
    Matrix(const Matrix& existingMatrix);                                           //Copy Constructor
    double get (int i , int j)  const;                                              //Returns value at specified location
    const void set(int i, int j, double& val);                                      //Changes value at specified location
    int getM() const;                                                               //Return value of M
    int getN() const;                                                               //Return value of N
    Matrix getBlock(int startRow, int endRow, int startColumn, int endColumn);      //Return section of Matrix
    Matrix operator + (const Matrix& B);
    Matrix operator = (const Matrix& B);
    Matrix operator - (const Matrix& B);
    Matrix operator * (const Matrix& B);
    Matrix operator / (const Matrix& B);
    Matrix operator ++ ();
    double operator () (int i, int j);
    void out();
    double sum();
};

class BinaryImage
    :public Matrix
{

public:
    BinaryImage(int sizeR, int sizeC, double* input_data, double thresh);
    ~BinaryImage();
    BinaryImage(const Matrix& rhs, double thresh);
    BinaryImage(const BinaryImage& existingBinIm);
    const void set(int i, int j, double& val);
};

#endif

To jest moja sekcja Main. Metoda gdzie wystepuje problem to testOperation()

#include<iostream>
#include<Windows.h>
#include<fstream>
#include<string>
#include"Matrix.h"
using namespace std;

void testOperation();
double* readTXT(char* fileName, int sizeR, int sizeC);
void writePGM(char* fileName, Matrix& toWrite, int Q);

int main()
{
    int selection;

    cout<<"Select a program to run:"<<endl<<"1 - Logo Reorganisation"<<endl<<"2 - Where's Wally"<<endl<<"Selection: ";
    cin>>selection;
    cout<<endl;
    switch(selection)
    {
    case 1:
        cout<<"Logo Reorganisation Commencing..."<<endl;
        testOperation();
        break;
    case 2:
        cout<<"Where's Wally Commencing..."<<endl;
        break;
    default:
        cout<<"Selection invalid"<<endl;
        break;
    }

    Sleep(1000);
    return 0;
}

//Consructor
Matrix::Matrix(int sizeR, int sizeC, double* inputData)
{
    M = sizeR;
    N = sizeC;
    data = new double [M*N];
    for (int ii = 0; ii < M*N; ii++)
    {
        data[ii] = inputData[ii];
    }
}

Matrix::Matrix(int sizeR, int sizeC)
{
    M = sizeR;
    N = sizeC;
    data = new double [M*N];

    for (int ii = 0; ii < M*N; ii++)
    {
        *(data+ii) = 0;
    }
}

//Destructor
Matrix::~Matrix()
{
    delete [] data;
}

//Copy Constructor
Matrix::Matrix(const Matrix& existingMatrix)
{
    M = existingMatrix.getM();
    N = existingMatrix.getN();
    data = new double[M*N];

    for (int ii = 0; ii < M; ii++)
    {
        for (int jj = 0; jj < N; jj++)
        {
            int k = ii*N+jj;
            data[k] = existingMatrix.get(ii,jj);
        }
    }
}

//Pass by constant value
double Matrix::get (int i , int j)  const   
{
    int k = i*N + j;
    return data[k];
}

//Pass by Refrence
const void Matrix::set(int i, int j, double& val)
{
    int k = i*N + j;
    val = data[k];
}

//Return Value of M
int Matrix::getM() const
{
    return M;
}

//Return Value of N
int Matrix::getN() const
{
    return N;
}

//Return Section of the Matrix.
Matrix Matrix::getBlock(int startRow, int endRow, int startColumn, int endColumn)
{
    int Row = endRow-startRow+1;
    int Column =  endColumn - startColumn+1;
    double* block = new double[(Row)*(Column)];
    for (int ii = 0; ii < Row; ii++)
    {
        for (int jj = 0; jj < Column; jj++)
        {
            int k = ii*Column+jj;
            block[k] = get(ii+startRow, jj+startColumn);
        }
    }
    Matrix t(Row,Column,block);
    delete [] block;
    return t;
}

//Allows for addion of Matricies, Operation Overloading.
Matrix Matrix::operator +(const Matrix& B)
{
    Matrix C = Matrix(M, N, 0);
    double temp;
    for (int ii = 0; ii < M; ii++)
    {
        for (int jj = 0; jj < N; jj++)
        {
            temp = data[ii*N+jj] + B.get(ii,jj);
            C.set(ii,jj, temp);
        }
    }

    return C;
}

//Makes x and y equal, Opperation Overloading.
Matrix Matrix::operator =(const Matrix& B)
{
    if (this == &B)
    {
        return *this;
    }

    else 
    {
        M = B.getM();
        N = B.getN();
        delete [] data;
        data = new double [M*N];
        for (int ii = 0; ii < M; ii++)
        {
            for (int jj = 0; jj < N; jj++)
            {
                data[ii*N+jj] = B.get(ii,jj);   
            }
        }
        return *this;
    }
}

//Allows for subtraction of matricies, Operation Overloading.
Matrix Matrix::operator -(const Matrix& B)
{
    Matrix C = Matrix(M, N);
    double temp;
    for (int ii = 0; ii < M-1; ii++)
    {
        for (int jj = 0; jj < N-1; jj++)
        {
            temp = data[ii*N+jj] - B.get(ii,jj);
            C.set(ii,jj, temp);
        }
    }

    return C;
}

//Allows for multiplication of Matricies, Operation Overloading.
Matrix Matrix::operator *(const Matrix& B)
{
    Matrix C = Matrix(M, B.getN());
    double temp;
    for (int ii = 0; ii < M; ii++)
    {
        for (int jj = 0; jj < N; jj++)
        {
            temp = data[ii*N+jj] * B.get(ii,jj);
            C.set(ii,jj, temp);
        }
    }

    return C;
}

//Allows for addition of Matricies, Operation Overloading.
Matrix Matrix::operator /(const Matrix& B)
{
    Matrix C = Matrix(M, B.getN(), 0);
    double temp;
    for (int ii = 0; ii < M; ii++)
    {
        for (int jj = 0; jj < N; jj++)
        {
            temp = data[ii*N+jj] / B.get(ii,jj);
            C.set(ii,jj, temp);
        }
    }

    return C;
}

//Incrmentation of all values in Matrix by 1, Operation Overloading.
Matrix Matrix::operator ++()
{
    for (int ii = 0; ii < M*N; ii++)
    {
        data[ii] = data[ii]++;
    }

    return *this;
}


//Allows calling of "get" function indirectly.
double Matrix::operator() (int i, int j)
{
    return data[i*N+j];
}

double Matrix::sum()
{
    double total = 0.0;
    for (int ii = 0; ii < M*N; ii++)
    {
        total = total + data[ii];
    }


    return total;
}

void Matrix::out()
{
    for (int ii = 0; ii < M*N; ii++)
    {
        if(data[ii] == 255)
            cout<<"1 ";
        else
        cout<<data[ii]<<" ";
    }
}

BinaryImage ::BinaryImage(int sizeR, int sizeC, double*input_data, double thresh)
    :Matrix(sizeR, sizeC, input_data)
{
    for(int ii = 0; ii < M*N; ii++)
    {
        if (data[ii] > thresh)
        {
            data[ii] = 1;
        }

        else 
        {
            data[ii] = 0;
        }
    }
}

BinaryImage::BinaryImage(const Matrix& rhs, double thresh)
    :Matrix(rhs)
{
    for(int ii = 0; ii < M*N; ii++)
    {
        if (data[ii] > thresh)
        {
            data[ii] = 1;
        }

        else 
        {
            data[ii] = 0;
        }
    }

}

BinaryImage::BinaryImage(const BinaryImage& rhs)
{
    M = rhs.getM();
    N = rhs.getN();
    data = new double[M*N];
    for (int ii = 0; ii<M; ii++){
        for (int jj = 0; jj<N; jj++){
            data[ii] = rhs.get(ii, jj);
        }
    }
}

const void BinaryImage::set(int i, int j, double& val)
{
    int k = i*N + j;
    val = data[k];
}



//Reads in file and from specified location and builds it
double* readTXT(char* fileName, int sizeR, int sizeC)
{
    double* input_data = new double[sizeR*sizeC];
    int i =0;
    ifstream currentFile(fileName);
    if (currentFile.is_open())
    {
        while(currentFile.good())
        {
            if (i>sizeR*sizeC-1) break;
            currentFile >> *(input_data+i);
            i++;


        }
        currentFile.close();
    }
    else
    {
        cout<<"File path not found"<<endl;
    }

    return input_data;
    delete [] input_data;

}

void testOperation()
{
  char* filePath2 = "E:\\logo_with_noise.txt";
    double* basIm2 = readTXT(filePath2, 512, 512);
    Matrix logoWithNoise(512, 512, basIm2);
    cout<<"done"<<endl;

    //Reads in the Shuffled Image
    char* filePath = "E:\\logo_shuffled.txt";
    double* basIm = readTXT(filePath, 512, 512);
    Matrix logoShuffled(512, 512, basIm);
    cout<<"done"<<endl;


    Matrix logoUnshuffled(512,512);
    double Score = 0.0;                                                     //Current "Pixels" score
    double bestScore = 0.0;                                                     //Best "Pixel" score
    int bestX, bestY = 0;

    //For Loop to begin Sum of Squared Differences
    for (int x = 0; x < 480; x+=32)
    {   
        for (int y = 0; y < 480; y += 32)
        {
            Matrix subWithNoise = logoWithNoise.getBlock(x,(x+32),y,(y+32));
            //subShuffled.out();
            bestScore = 70000.0;
            for (int xx = 0; xx< 480; xx+=32)
            {
                for (int yy = 0; yy < 480; yy+=32)
                {
                    //Calculating the Score starts here
                    cout<<"loop started"<<endl;
                    int t = yy+32;
                    int l = xx+32;
                    Matrix subShuffled = logoShuffled.getBlock(xx,l, yy, t);
                    cout<<"submade"<<endl;
                    Matrix diff = subWithNoise - logoWithNoise;
                    Matrix product = diff*diff;
                    Score = diff.sum();
                    if (Score < bestScore)
                    {
                        bestScore = Score;
                        bestX = xx;
                        bestY = yy;
                    }
                    cout<<"loop ended"<<endl;
                }
            }

            //For loop to put the best option into the final Matrix
            for (int ii = bestX; ii < (bestX+=32); ii++)
            {
                for (int jj = bestY; jj < (bestY+=32); jj++)
                {
                    double temp = logoShuffled.get(ii,jj);
                    logoUnshuffled.set(ii,jj,temp);
                }
            }
        }
    }
    //Creates file
    char* newFile = "finished.pgm";
    writePGM(newFile, logoUnshuffled, 1);
	cin.get();

}

void writePGM(char* fileName, Matrix& toWrite, int Q)
{
    int x = toWrite.getM();
    int y = toWrite.getN();
    unsigned char *image;
    ofstream myfile;

    image = (unsigned char *) new unsigned char [x*y];

    // convert the integer values to unsigned char

    for(int i = 0; i<x; i++)
    {
        for (int j = 0; j<y; j++)
        {
            image[i*y+j]=(unsigned char)toWrite.get(i,j);
        }
    }

    myfile.open(fileName, ios::out|ios::binary|ios::trunc);

    if (!myfile) 
    {
        cout << "Can't open file: " << fileName << endl;
        exit(1);
    }

    myfile << "P5" << endl;
    myfile << y << " " << x << endl;
    myfile << Q << endl;

    myfile.write( reinterpret_cast<char *>(image), (x*y)*sizeof(unsigned char));

    if (myfile.fail()) 
    {
        cout << "Can't write image " << fileName << endl;
        exit(0);
    }

    myfile.close();

    delete [] image;
} 

W zalaczniku umiescilem pliki .txt uzyte z kodem. Bede wdzieczny za kazda pomoc. Pozdrawiam

0

Sprawdź debugerem pod jaką dokładnie linijką w funkcji testOperation program się wywala

0
robcio napisał(a):

Sprawdź debugerem pod jaką dokładnie linijką w funkcji testOperation program się wywala

 //Pass by constant value
double Matrix::get (int i , int j)  const   
{
    int k = i*N + j;
    return data[k]; <------- Next line to execute
}
1

robcio napisał(a) dzisiaj, 20
Sprawdź debugerem pod jaką dokładnie linijką w funkcji testOperation program się wywala

//Pass by constant value
double Matrix::get (int i , int j) const
{
int k = i*N + j;
return data[k]; <------- Next line to execute
}

Jeśli masz segfaulta, a debugger wskazuje linie z indeksowaniem tablicy/wektora to pewnie z indeksem jest coś nie tak.
Czemu nie podejrzałeś sobie zawartości k? Masz demo wersje debuggera?
Problem tkwi w tym kawałku:

 
    for (int ii = bestX; ii < (bestX+=32); ii++)
            {
                for (int jj = bestY; jj < (bestY+=32); jj++)
                {
                    double temp = logoShuffled.get(ii,jj);
                    logoUnshuffled.set(ii,jj,temp);
                }
            }

Get dostaje za duże ii oraz jj, bo += nie jest operatorem którego chciałeś użyć.
Twój kod ma też inne problemy, ale nie wiem czy cię to interesuje ;) Na przyszłość radzę przed wrzuceniem na forum 500 linii
kodu przeorać go mocniej debuggerem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1