我正在使用Sobel屏蔽边缘检测而不使用任何特殊库。我想要的输出是512x512矩阵的文本文件,其值介于0到1之间。 我已经通过设置较小的值(如50而不是' ROW-2')来检查代码是否正常工作。和' COL-2'。 但是,如果我把它们放回去,代码将永远运行。
常量值为:
const int ROW = 512;
const int COL = 512;
const double Gx [3][3] = { {-1.0,0.0,1.0},{-2.0,0.0,2.0},{-1.0,0.0,1.0}};
const double Gy [3][3] = { {1.0,2.0,1.0},{0.0,0.0,0.0},{-1.0,-2.0,-1.0}};
这是主要功能:
int main()
{
double NewImage[ROW][COL] = {0};
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
NewImage[i][j] = 0;
}
}
for (int i = 0; i < ROW-2; i++)
{
for (int j = 0; j < COL-2; j++)
{
NewImage[i+1][j+1] = SobelConvolution(i,j);
}
}
ofstream newImage;
string filename;
filename = "output image.txt";
newImage.open (filename.c_str());
for(int rows = 0; rows < ROW; rows++)
{
for(int cols = 0; cols < COL; cols++)
{
newImage << NewImage[ROW][COL] <<" ";
}
newImage << endl;
}
newImage.close();
return 0;
}
这是SobelConvolution的功能:
double SobelConvolution(int row, int col)
{
double convX;
double convY;
double conv;
convX = ImageReader(row,col)*Gx[2][2]
+ ImageReader(row,col+1)*Gx[2][1]
+ ImageReader(row,col+2)*Gx[2][0]
+ ImageReader(row+1,col)*Gx[1][2]
+ ImageReader(row+1,col+1)*Gx[1][1]
+ ImageReader(row+1,col+2)*Gx[1][0]
+ ImageReader(row+2,col)*Gx[0][2]
+ ImageReader(row+2,col+1)*Gx[0][1]
+ ImageReader(row+2,col+2)*Gx[0][0];
convY = ImageReader(row,col)*Gy[2][2]
+ ImageReader(row,col+1)*Gy[2][1]
+ ImageReader(row,col+2)*Gy[2][0]
+ ImageReader(row+1,col)*Gy[1][2]
+ ImageReader(row+1,col+1)*Gy[1][1]
+ ImageReader(row+1,col+2)*Gy[1][0]
+ ImageReader(row+2,col)*Gy[0][2]
+ ImageReader(row+2,col+1)*Gy[0][1]
+ ImageReader(row+2,col+2)*Gy[0][0];
conv = sqrt((convX*convX) + (convY*convY));
return conv;
}
这是函数ImageReader:
double ImageReader(int r, int c)
{
double OrigImage[ROW][COL];
ifstream defaultImage ("image.txt");
if (defaultImage.good())
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
defaultImage >> OrigImage[i][j];
}
}
}
return OrigImage [r][c];
}
任何提示或建议?提前谢谢!
答案 0 :(得分:4)
以下是一些注释:
<强> ImageReader
强>
只返回数组的一个值,不需要在每个时间读取整个数组,只需要一个值。在我看来,这个功能是多余的。
<强> SobelConvolution
强>
此功能很好,但有一个不必要的变量 - conv
。
<强> main
强>
当我们已经NewImage
时,我不知道为什么要将0
的每个值初始化为0
!你也不知道实际上需要NewImage
这是我要写的内容(广泛评论):
double SobelConvolution(int row, int col)
{
//ImageReader has been removed, it was unnecessary. The code has been moved here
double oldImage[ROW][COL];
std::ifstream defaultImage{ "image.txt" };
//Error handling if file doesn't exist - consider doing something else :)
if (!defaultImage.is_open())
return 0;
//Initialize array
for (int i = 0; i < ROW; ++i)
for (int j = 0; j < COL; ++j)
defaultImage >> oldImage[i][j];
//You should always declare variables where they are first used, this
//reduces the possibility of errors
//We can just access the array directly
double convX = oldImage[row][col] * Gx[2][2]
+ oldImage[row][col + 1] * Gx[2][1]
+ oldImage[row][col + 2] * Gx[2][0]
+ oldImage[row + 1][col] * Gx[1][2]
+ oldImage[row + 1][col + 1] * Gx[1][1]
+ oldImage[row + 1][col + 2] * Gx[1][0]
+ oldImage[row + 2][col] * Gx[0][2]
+ oldImage[row + 2][col + 1] * Gx[0][1]
+ oldImage[row + 2][col + 2] * Gx[0][0];
double convY = oldImage[row][col] * Gy[2][2]
+ oldImage[row][col + 1] * Gy[2][1]
+ oldImage[row][col + 2] * Gy[2][0]
+ oldImage[row + 1][col] * Gy[1][2]
+ oldImage[row + 1][col + 1] * Gy[1][1]
+ oldImage[row + 1][col + 2] * Gy[1][0]
+ oldImage[row + 2][col] * Gy[0][2]
+ oldImage[row + 2][col + 1] *Gy[0][1]
+ oldImage[row + 2][col + 2]*Gy[0][0];
//No need to create a separate variable just to return it
return sqrt((convX*convX) + (convY*convY));
}
int main()
{
//= {} Initializes every element to 0, you don't need to do it :) Just so you know :)
//Note that it crashes here, because my stack size was too small,
//maybe consider using a dynamic array (512 * 512 is pretty big) :)
//double NewImage[ROW][COL] = {};
//The array is not really needed, see below
std::string filename = "oimage.txt";
std::ofstream newImage{ filename };
//No need to create another array just to output it again,
//Just output the calculated values - this doesn't ignore the first/last values
for (int rows = 0; rows < ROW; rows++)
{
for (int cols = 0; cols < COL; cols++)
newImage << SobelConvolution(rows, cols) << " ";
newImage << '\n'; //std::endl flushes the stream, while \n does not - it is faster :)
}
newImage.close();
return 0;
}
答案 1 :(得分:2)
你真的想打开单个图像文件18次并读取每行和每列的所有数据只是为了返回单行和列18次?为什么不一次读取图像文件并将图像数据数组传递给函数?
答案 2 :(得分:2)
你所做的不仅仅是效率低下,而且是完全疯狂的。
对于图像的每个像素,您调用SobelConvolution,后者又调用ImageReader 18次(其中6次没有用,因为相应的系数为零)。但可怕的是,ImageReader每次都会从文本文件中执行完整的图像读取,只需简单的数组查找即可。
总而言之,您正在执行4718592文件流打开/关闭以及从文件读取1236950581248值,其中只需1次打开/关闭和262144次读取就足够了。 (不计算单个读取比直接数组访问要贵得多。)完整运行可能持续两个小时或更长时间。