私の大学の課題の一環として、.txt 形式の 2 つの画像を比較する必要があります。
どちらの画像も 512x512 で、16x16 のブロックに分割されていることを考慮するよう求められます。つまり、各ブロックは 32x32 です。
2 つの画像を比較するために、画像のブロックに対して差の二乗和アルゴリズムを使用しています。左上から始めて、適切な数学が見つかるまで順番に作業します。ただし、これは私の問題が発生している場所です。混乱していない画像から単一のブロックを正常に取得し、それを混乱した画像の別のブロックと比較した後、2 回目の反復で次のエラーが発生します。
Windows は、Assignment1.exe でブレークポイントをトリガーしました。
これは、ヒープの破損が原因である可能性があります。これは、Assignment1.exe またはそれがロードした DLL のバグを示しています。
私の質問は、コードのエラーの原因は何ですか?
以下は Matrix.h というヘッダー ファイルで、txt ファイルから取得した 2 次元マトリックスを 1 次元画像に変換します。
#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
この次のセクションは私のメインです。エラーの場合に使用しているメソッドは、shuffledLogo() と呼ばれます。
#include<iostream>
#include<Windows.h>
#include<fstream>
#include<string>
#include"Matrix.h"
using namespace std;
void shuffledLogo();
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;
shuffledLogo();
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;
int Column = endColumn - startColumn;
double* block = new double[(Row)*(Column)];
int n = endColumn-startColumn;
for (int ii = startRow; ii < endRow; ii++)
{
for (int jj = startColumn; jj < endColumn; jj++)
{
int k = ii*n+jj;
block[k] = data[ii*N+jj];
}
}
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];
}
void shuffledLogo()
{
char* filePath2 = "E:\\logo_shuffled.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);
}
//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 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;
}
エラーを詳しく調べたいかどうかを確認できるように、フォルダをパブリック ドロップボックス ファイルに自由に配置しました。私のコードが乱雑で表示が不十分な場合があることを理解しています。改善方法について誰か提案があれば教えてください。