11

私は Java プログラミングにしか慣れていないので、C++ の初心者です。私がやろうとしているのは、画像ファイル (.bmp) をマトリックスに読み込み、マトリックス上で 3x3 マトリックス (フィルター) を使用して畳み込みを実行し、畳み込み画像を含む新しい画像ファイルを生成することです。

私はグーグルを見回して、次の実装を思い付くことができました:

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])));
    }
4

2 に答える 2

5

どうやらはるかに安全で、セグメンテーション違反を取り除いたものに置き換えstrcpy()ました。strncpy()

于 2012-12-06T20:58:24.320 に答える
2

メイン関数に「Image.cpp」を含めます。「Image.h」が必要です。そうしないと、ヘッダー ファイルで既に定義されている関数の別の定義がコンパイラによって認識されます。

于 2015-02-21T22:21:37.360 に答える