C++ 图像处理 - 将图像文件读入二维数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13750142/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:41:16  来源:igfitidea点击:

C++ Image Processing - Reading an Image file into 2D Array

c++image-processingbmp

提问by MathanMV

I'm an absolute noobie at C++ as I've only been familiar with Java programming. What I'm trying to do is to read an Image file (.bmp) into a matrix where I can perform a convolution with a 3x3 matrix (filter) on the matrix to produce a new image file with the convoluted image.

我是 C++ 的绝对菜鸟,因为我只熟悉 Java 编程。我想要做的是将图像文件 (.bmp) 读入矩阵,在该矩阵中我可以在矩阵上使用 3x3 矩阵(过滤器)执行卷积,以生成带有卷积图像的新图像文件。

I've looked around google and managed to come up with the following implementation:

我环顾了谷歌并设法提出了以下实现:

Image.h file:

图像.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 file:

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 file:

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;

}

When I try to run the following file with:

当我尝试使用以下文件运行以下文件时:

g++ Main.cpp -o main

./main

I get a segmentation:11 error and not sure what is causing this error!

我收到一个segmentation:11 错误,不知道是什么导致了这个错误!

Note: I have to use a pure C++ implementation so cannot use other libraries.

注意:我必须使用纯 C++ 实现,因此不能使用其他库。

HELP!

帮助!

EDIT: I think the code thats giving me the segmentation error is :

编辑:我认为给我分段错误的代码是:

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

But not sure why!

但不知道为什么!

EDIT #3: Works after replacing above code with :

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

采纳答案by MathanMV

replaced strcpy()with strncpy()which is much safer apparently and that removed the segmentation fault.

替换strcpy()strncpy()which 显然更安全,并且消除了分段错误。

回答by John Smith

In the main function you include "Image.cpp" and there should be "Image.h" otherwise the compiler would recognize another definition of functions already defined in the header file

在主函数中包含“Image.cpp”并且应该有“Image.h”,否则编译器会识别头文件中已经定义的函数的另一个定义