C++ 图像处理 - 将图像文件读入二维数组
Posted
技术标签:
【中文标题】C++ 图像处理 - 将图像文件读入二维数组【英文标题】:C++ Image Processing - Reading an Image file into 2D Array 【发布时间】:2012-12-06 18:29:46 【问题描述】:我是 C++ 的绝对菜鸟,因为我只熟悉 Java 编程。我要做的是将图像文件(.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])));
【问题讨论】:
【参考方案1】:将strcpy()
替换为strncpy()
,这显然更安全,并且消除了分段错误。
【讨论】:
【参考方案2】:在主函数中包含“Image.cpp”并且应该有“Image.h”,否则编译器会识别头文件中已经定义的函数的另一个定义
【讨论】:
以上是关于C++ 图像处理 - 将图像文件读入二维数组的主要内容,如果未能解决你的问题,请参考以下文章
使用 openCV 在 C++ 中查看灰度 RAW 图像文件