2012-12-06 40 views
11

我是C++的絕對noobie,因爲我只熟悉Java編程。我想要做的是讀取一個圖像文件(.bmp)到一個矩陣中,我可以在矩陣上使用3x3矩陣(濾波器)執行卷積,以生成具有卷積圖像的新圖像文件。C++圖像處理 - 將圖像文件讀取到2D數組中

我環顧四周谷歌和設法想出下面的實現:

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

} 

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

但不知道爲什麼!

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

回答

5

替換strcpy()strncpy()這是更安全顯然並且除去段故障。

2

在主函數中包含「Image.cpp」,並且應該有「Image.h」,否則編譯器會識別已在頭文件中定義的函數的另一個定義