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