我正在嘗試使用下面的代碼構建邊緣檢測程式。但是我遇到了各種各樣的問題,我不知道如何解決。
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define xrows 700
#define ycolumns 1244
int Gradient[xrows][ycolumns];
int Image_input[xrows][ycolumns];
int G_x[xrows][ycolumns];
int G_y[xrows][ycolumns];
int main() {
FILE *fw = fopen("sobel_outt.txt", "w");
FILE *fr = fopen("ny.txt", "r");
int x, y, row, column, num;
int i = 0;
int XLENGTH = 700;
int YLENGTH = 1244;
for (row = 0; row < XLENGTH; row ) {
for (column = 0; column < YLENGTH; column ) {
fscanf(fr, "%d " ",", &num);
Image_input[row][column] = num;
}
}
fclose(fr);
for (x = 0; x < XLENGTH; x = 3) {
i ;
for (y = 0; y < YLENGTH; y = 3) {
if ((x == 0) || (x == XLENGTH - 1) || (y == 0) || (y == YLENGTH - 1)) {
G_x[x][y] = G_y[x][y] = Gradient[x][y] = 0;
} else {
G_x[x][y] = Image_input[x 1][y - 1]
2 * Image_input[x 1][y]
Image_input[x 1][y 1]
- Image_input[x - 1][y - 1]
- 2 * Image_input[x - 1][y]
- Image_input[x - 1][y 1];
G_y[x][y] = Image_input[x - 1][y 1]
2 * Image_input[x][y 1]
Image_input[x 1][y 1]
- Image_input[x - 1][y - 1]
- 2 * Image_input[x][y - 1]
- Image_input[x 1][y - 1];
Gradient[x][y] = (abs(G_x[x][y]) abs(G_y[x][y]));
if (Gradient[x][y] > 255) {
Gradient[x][y] = 255;
}
}
fprintf(fw, "%d,\n", Gradient[x][y]);
}
}
printf("i= %d", i);
fclose(fw);
return 0;
}
該程式在 devcpp IDE 中運行時似乎執行良好,并且所有矩陣都被宣告為全域變數。每當我在主函式中宣告它們時,程式就會崩潰。
我嘗試使用 Visual Studio 運行該程式,但遇到了更多問題。我收到一些錯誤訊息,指出fscanf被忽略fprintf且不安全。
最后但同樣重要的是,我遇到了另一個錯誤,指出我用完了所有可用的堆疊記憶體。
任何建議都會受到歡迎。
編輯:你們中的許多人建議我導致堆疊溢位。我將嘗試使用堆記憶體作為替代方案。我的第二個問題仍然存在。
uj5u.com熱心網友回復:
將矩陣定義為具有自動存盤功能的區域變數會使用接近 14MB 的堆疊空間。這肯定會導致許多平臺上的堆疊溢位。建議從堆中分配資料。
Microsoft 的 Visual C 編譯器被配置為抱怨fscanf并fprintf提倡使用fscanf_sandfprintf_s代替。他們設法獲得了這個和其他功能,包括 C 標準(附件 K),但 API 以微妙的方式進行了更改以保持一致性(使用size_t而不是UINT陣列長度),并且微軟沒有更改他們的版本。這種差異對于 32 位目標并不重要,但型別size_t現在unsigned在大多數 64 位平臺上有所不同。
fscanf_s()因此不建議對可移植程式使用。#define _CRT_SECURE_NO_WARNINGS您可以通過在 include之前添加來禁用編譯器警告<stdio.h>。
但是請注意,您不應忽略 的回傳值fscanf()來檢測無效或丟失的資料:如果轉換失敗,目標變數將保持不變,從而導致不正確的結果甚至未定義的行為。
這是從堆中分配矩陣的修改版本:
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS // disable warnings in fscanf
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROWS 700
#define COLS 1244
int main() {
int (*Gradient)[COLS] = calloc(sizeof(*Gradient), ROWS);
int (*Image_input)[COLS] = calloc(sizeof(*Image_input), ROWS);
int (*G_x)[COLS] = calloc(sizeof(*G_x), ROWS);
int (*G_y)[COLS] = calloc(sizeof(*G_y), ROWS);
if (!Gradient || !Image_input || !G_x || !G_y) {
fprintf(stderr, "cannot allocate memory\n");
return 1;
}
FILE *fr = fopen("ny.txt", "r");
if (fr == NULL) {
fprintf(stderr, "cannot open ny.txt: %s\n", strerror(errno));
return 1;
}
FILE *fw = fopen("sobel_outt.txt", "w");
if (fw == NULL) {
fprintf(stderr, "cannot open sobel_outt.txt: %s\n",
strerror(errno));
return 1;
}
int x, y, row, column, num;
int i = 0;
int XLENGTH = ROWS;
int YLENGTH = COLS;
for (row = 0; row < XLENGTH; row ) {
for (column = 0; column < YLENGTH; column ) {
if (fscanf(fr, "%d ,", &num) != 1) {
fprintf(stderr, "cannot read value for Image_input[%d][%d]\n",
row, column);
return 1;
}
Image_input[row][column] = num;
}
}
fclose(fr);
for (x = 0; x < XLENGTH; x = 3) {
i ;
for (y = 0; y < YLENGTH; y = 3) {
if (x == 0 || x == XLENGTH - 1 || y == 0 || y == YLENGTH - 1) {
G_x[x][y] = G_y[x][y] = Gradient[x][y] = 0;
} else {
G_x[x][y] = Image_input[x 1][y - 1]
2 * Image_input[x 1][y]
Image_input[x 1][y 1]
- Image_input[x - 1][y - 1]
- 2 * Image_input[x - 1][y]
- Image_input[x - 1][y 1];
G_y[x][y] = Image_input[x - 1][y 1]
2 * Image_input[x][y 1]
Image_input[x 1][y 1]
- Image_input[x - 1][y - 1]
- 2 * Image_input[x][y - 1]
- Image_input[x 1][y - 1];
Gradient[x][y] = abs(G_x[x][y]) abs(G_y[x][y]);
if (Gradient[x][y] > 255) {
Gradient[x][y] = 255;
}
}
fprintf(fw, "%d,\n", Gradient[x][y]);
}
}
fclose(fw);
printf("i= %d\n", i);
free(Gradient);
free(Image_input);
free(G_x);
free(G_y);
return 0;
}
請注意, 的最終值i應始終為XLENGTH。
這是對所有資料使用單一結構的替代方案,比分配的 2D 矩陣更容易處理:
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROWS 700
#define COLS 1244
struct sobel {
int Gradient[ROWS][COLS];
int Image_input[ROWS][COLS];
int G_x[ROWS][COLS];
int G_y[ROWS][COLS];
};
int main() {
struct sobel *data = (struct sobel *)calloc(sizeof(*data), 1);
if (!data) {
fprintf(stderr, "cannot allocate memory\n");
return 1;
}
FILE *fr = fopen("ny.txt", "r");
if (fr == NULL) {
fprintf(stderr, "cannot open ny.txt: %s\n", strerror(errno));
return 1;
}
FILE *fw = fopen("sobel_outt.txt", "w");
if (fw == NULL) {
fprintf(stderr, "cannot open sobel_outt.txt: %s\n", strerror(errno));
return 1;
}
int x, y, row, column, num;
int i = 0;
int XLENGTH = ROWS;
int YLENGTH = COLS;
for (row = 0; row < XLENGTH; row ) {
for (column = 0; column < YLENGTH; column ) {
if (fscanf(fr, "%d " ",", &num) != 1) {
fprintf(stderr, "cannot read value for Image_input[%d][%d]\n", row, column);
return 1;
}
data->Image_input[row][column] = num;
}
}
fclose(fr);
for (x = 0; x < XLENGTH; x = 3) {
i ;
for (y = 0; y < YLENGTH; y = 3) {
if (x == 0 || x == XLENGTH - 1 || y == 0 || y == YLENGTH - 1) {
data->G_x[x][y] = data->G_y[x][y] = data->Gradient[x][y] = 0;
} else {
data->G_x[x][y] = data->Image_input[x 1][y - 1]
2 * data->Image_input[x 1][y]
data->Image_input[x 1][y 1]
- data->Image_input[x - 1][y - 1]
- 2 * data->Image_input[x - 1][y]
- data->Image_input[x - 1][y 1];
data->G_y[x][y] = data->Image_input[x - 1][y 1]
2 * data->Image_input[x][y 1]
data->Image_input[x 1][y 1]
- data->Image_input[x - 1][y - 1]
- 2 * data->Image_input[x][y - 1]
- data->Image_input[x 1][y - 1];
data->Gradient[x][y] = abs(data->G_x[x][y]) abs(data->G_y[x][y]);
if (data->Gradient[x][y] > 255) {
data->Gradient[x][y] = 255;
}
}
fprintf(fw, "%d,\n", data->Gradient[x][y]);
}
}
fclose(fw);
printf("i= %d\n", i);
free(data);
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/475874.html
