Обработка изображений в C ++ — чтение файла изображения в 2D-массив

Я абсолютный новичок в C ++, так как я был знаком только с программированием на Java. То, что я пытаюсь сделать, это прочитать файл изображения (.bmp) в матрицу, где я могу выполнить свертку с матрицей 3×3 (фильтр) на матрице, чтобы создать новый файл изображения с извилистым изображением.

Я посмотрел вокруг Google и сумел придумать следующую реализацию:

Файл image.h:

//  Image.h

#include <fstream> // for file I/O

using namespace std;
typedef unsigned char unchar; // Easier to understand & code.

class MImage {

public:
MImage(const char* fileName); //Constructor
~MImage(); //Deconstructor
void write(const char* fileName);
void smoothFilter(); //smoothing filer.
private:
ifstream* pInFile;
ofstream* pOutFile;
unchar imageHeaderData[1078]; //.bmp header data with offset 1078.
unchar** imageData;
unchar m_smoothFilter[3][3]; // Smoothing Filter.
unchar**  filteredData;
};

Файл Image.cpp:

//  Image.cpp
//

#ifndef _Image_h
#define _Image_h
#define WIDTH 128
#define HEIGHT 128

#include "Image.h"#include <cmath>

#endif

using namespace std;
typedef unsigned char unchar;

//Constructor

MImage::MImage(const char* fileName){

imageData = new unchar* [HEIGHT]; // create new array size: height of image.
filteredData = new unchar* [HEIGHT];// create new array size: height of image.

for (int i = 0; i < HEIGHT; i++) {

imageData[i] = new unchar [WIDTH]; //create matrix.
filteredData[i] = new unchar [WIDTH]; //create matrix.
}

//image I/O
pInFile = new ifstream;
pInFile->open(fileName, ios::in | ios::binary); // open fileName and read as binary.
pInFile->seekg(0, ios::beg); //pos filter at beginning of image file.
pInFile->read(reinterpret_cast<char*>(imageHeaderData),1078); //read bmp header data into array.

for(int i=0; i<HEIGHT; i++) {
pInFile->read(reinterpret_cast<char*>(imageData[i]),WIDTH);//read row into each array entry.
}

pInFile->close(); //close stream.

char m_smoothFilter[3][3] = {
{1,1,1},
{1,2,1},
{1,1,1}
};

}

MImage::~MImage(){

delete pInFile;
delete pOutFile;

for(int i=0; i<HEIGHT; i++){
delete[] imageData[i];
delete[] filteredData[i];
}

delete[] imageData;
delete[] filteredData;
}

void MImage::write(const char* fileName) {

smoothFilter();
pOutFile = new ofstream;
pOutFile->open(fileName, ios::out | ios::trunc | ios::binary);
pOutFile->write(reinterpret_cast<char*>(imageHeaderData), 1078); //write header data onto output

for(int i = 0; i < HEIGHT; i++){

pOutFile->write(reinterpret_cast<char*>(filteredData[i]),WIDTH); // write new image data.

}

pOutFile->close(); //close stream
}

void MImage::smoothFilter(){

//copy input image into new image
for(int i = 0; i < HEIGHT; i++) {
strcpy(reinterpret_cast<char*>(filteredData[i]), reinterpret_cast<char*>(imageData[i]));
}

int sumOfPixels = 0;

for(int i = 1; i < HEIGHT -1; i++) {

for(int j = 1; j < WIDTH -1; j++) {

sumOfPixels = m_smoothFilter[0][0] * imageData[i+1][j-1] + // top left corner
m_smoothFilter[0][1] * imageData[i+1][j]   + // top center
m_smoothFilter[0][2] * imageData[i+1][j+1] + // top right corner
m_smoothFilter[1][0] * imageData[i][j-1]   + // center left
m_smoothFilter[1][1] * imageData[i][j]     + // center center
m_smoothFilter[1][2] * imageData[i][j+1]   + // center right
m_smoothFilter[2][0] * imageData[i-1][j-1] + // bottom left corner
m_smoothFilter[2][1] * imageData[i-1][j]   + // bottom center
m_smoothFilter[2][2] * imageData[i-1][j+1];  // bottom right corner

filteredData[i][j] = (sumOfPixels / ( m_smoothFilter[0][0] + m_smoothFilter[0][1] +
m_smoothFilter[0][2] + m_smoothFilter[1][0] +
m_smoothFilter[1][1] + m_smoothFilter[1][2] +
m_smoothFilter[2][0] + m_smoothFilter[2][1] +
m_smoothFilter[2][2]));
}
}

}

Файл Main.cpp:

//
//  Main.cpp
//

#include <iostream>
#include "Image.cpp"#include <fstream>

using namespace std;

int main() {

MImage img("test.bmp");
img.write("output.bmp");
return 0;

}

Когда я пытаюсь запустить следующий файл с:

g++ Main.cpp -o main

./main

Я получаю ошибку сегментации: 11 и не уверен, что является причиной этой ошибки!

Примечание: я должен использовать чистую реализацию C ++, поэтому не могу использовать другие библиотеки.

ПОМОГИТЕ!

РЕДАКТИРОВАТЬ:
Я думаю, что код, который дает мне ошибку сегментации:

for(int i = 0; i < HEIGHT; i++) {
strcpy(reinterpret_cast<char*>(filteredData[i]), reinterpret_cast<char*>(imageData[i]));
}

Но не уверен почему!

РЕДАКТИРОВАТЬ № 3:
Работает после замены вышеуказанного кода на:

for(int i= 0; i<HEIGHT; i++) {
strncpy (reinterpret_cast<char*>(filteredData[i]),
reinterpret_cast<char*>(imageData[i]),
sizeof(reinterpret_cast<char*>(filteredData[i])));
}

11

Решение

заменены strcpy() с strncpy() что, по-видимому, намного безопаснее и устраняет ошибку сегментации.

5

Другие решения

В основной функции вы включаете «Image.cpp», и должен быть «Image.h», иначе компилятор распознает другое определение функций, уже определенных в заголовочном файле.

2

По вопросам рекламы [email protected]