VS2022中OpenCV C++动态二维数组读取非正方形图意外终止
超分辨率插值算法内存分配异常问题
我使用Visual Studio 2022作为IDE,基于OpenCV C++实现超分辨率(SR)插值算法。目前问题出在readImage函数中,因此已注释掉插值流程的process函数,仅保留readImage和内存释放的deleteImage函数用于排查。
readImage函数会为三个动态分配的二维整数数组(input_image、intermediate_image、output_image)分配内存,随后将图像的像素强度值赋值给input_image。
遇到的具体异常情况:
- 读取非正方形(M×N,宽高不等)图像时,在为
int** intermediate_image和int** output_image分配内存的步骤,程序会意外终止;但读取正方形(M×M)图像时运行完全正常。 - 已排除内存不足的可能,哪怕仅读取1张非正方形图像也会崩溃,调试时有时甚至无法打印
"debug1"。 - 特殊现象:若不给
INPUT_WIDTH/HEIGHT乘以SR_RATE(值为2),程序可正常运行;在Visual Studio Code中模拟不读取图像的纯内存分配流程,也无异常。
主函数代码
#include <iostream> #include <filesystem> #include <string> #include <fstream> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <iostream> #include <ctime> #include <algorithm> namespace fs = std::filesystem; using namespace std; using namespace cv; #define SR_RATE 2 #define OFFSET 3 const string DATASET = "Set5"; const string ORIGIN_PATH = "../datasets/2X/625/" + DATASET + "/Y_0.5_temp/"; const string OUTPUT_PATH = "../datasets/2X/625/" + DATASET + "/Y_my_result/"; const string WEIGHTS_PATH = "../weights/2X/625/txt/"; int INPUT_WIDTH, INPUT_HEIGHT; int INTER_WIDTH, INTER_HEIGHT; int OUTPUT_WIDTH, OUTPUT_HEIGHT; //double weights[625][7]; void readImage(int*** input_image, int*** output_image, int*** intermediate_image, Mat img); void deleteImage(int*** input_image, int ih, int*** output_image, int oh, int*** intermediate_image, int inh); // void writeImage(string filename, int** output_image, int width, int height, string filetype); // void classify(int* c0, int* c1, int* c2, int* c3, int p1, int p2, int p3, int p4, int p5); // void process(int** input_image, int*** output_image, int*** intermediate_image); // void clearArray(int*** output_image, int*** intermediate_image); int main() { /* Runtime */ clock_t startTime, endTime; double duration, totalTime = 0.0, imgNum = 0.0; startTime = clock(); /* Load weights */ /*for (int fi = 0; fi < 625; ++fi) { string filename = WEIGHTS_PATH + "0_" + to_string(fi) + ".txt"; ifstream ifs(filename, ios::in); int wi = 0; while (ifs >> weights[fi][wi]) { wi += 1; } ifs.close(); }*/ endTime = clock(); totalTime = ((double)(endTime - startTime)) / CLOCKS_PER_SEC; for (const auto& entry : fs::directory_iterator(ORIGIN_PATH)) { imgNum += 1; startTime = clock(); string filename = entry.path().stem().string(); string img_path = entry.path().string(); string filetype = entry.path().extension().string(); /* Load Image */ int** input_image = NULL; int** intermediate_image = NULL; int** output_image = NULL; Mat img = imread(img_path, IMREAD_UNCHANGED); /* Allocate memory for arrays and Set input_image */ readImage(&input_image, &output_image, &intermediate_image, img); std::cout << "complete" << endl; /* Fill Zeros */ //clearArray(&output_image, &intermediate_image); /* Interpolation */ //process(input_image, &output_image, &intermediate_image); /* Output result*/ //writeImage(filename, output_image, OUTPUT_HEIGHT, OUTPUT_WIDTH, filetype); /* Free momory */ deleteImage(&input_image, INPUT_HEIGHT, &output_image, OUTPUT_HEIGHT, &intermediate_image, INTER_HEIGHT); endTime = clock(); duration = ((double)(endTime - startTime)) / CLOCKS_PER_SEC; totalTime += duration; std::cout << filename << " : " << duration << endl; } std::cout << "Total Time: " << totalTime << endl; std::cout << "Average Time" << totalTime / imgNum << endl; }
readImage函数代码
void readImage(int*** input_image, int*** output_image, int*** intermediate_image, Mat img) { INPUT_HEIGHT = img.rows; INPUT_WIDTH = img.cols; std::cout << INPUT_HEIGHT << " " << INPUT_WIDTH << endl; (*input_image) = new int* [INPUT_HEIGHT]; for (int i = 0; i < INPUT_HEIGHT; ++i) { (*input_image)[i] = new int[INPUT_WIDTH]; } for (int y = 0; y < INPUT_HEIGHT; ++y) { for (int x = 0; x < INPUT_WIDTH; ++x) { (*input_image)[x][y] = (int)img.ptr<uchar>(y)[x]; } } /* if I don't multiply by SR_RATE */ /* intermediate_image can be newed */ INTER_HEIGHT = INPUT_HEIGHT * SR_RATE; INTER_WIDTH = INPUT_WIDTH * SR_RATE; //INTER_WIDTH = INPUT_WIDTH; std::cout << INTER_HEIGHT << " " << INTER_WIDTH << endl; /************* BUG **************/ std::cout << "debug1" << endl; (*intermediate_image) = new int* [INTER_HEIGHT]; std::cout << "debug2" << endl; for (int i = 0; i < INTER_HEIGHT; ++i) { //(*intermediate_image)[i] = new int[INTER_WIDTH]; (*intermediate_image)[i] = new int[INTER_WIDTH]; } /************* BUG **************/ OUTPUT_HEIGHT = INPUT_HEIGHT * SR_RATE; OUTPUT_WIDTH = INPUT_WIDTH * SR_RATE; //std::cout << OUTPUT_HEIGHT << " " << OUTPUT_WIDTH << endl; (*output_image) = new int* [OUTPUT_HEIGHT]; for (int i = 0; i < OUTPUT_HEIGHT; ++i) { (*output_image)[i] = new int[OUTPUT_WIDTH]; } }
deleteImage函数代码
void deleteImage(int*** input_image, int ih, int*** output_image, int oh, int*** intermediate_image, int inh) { for (int i = 0; i < ih; ++i) { delete[](*input_image)[i]; } delete[](*input_image); for (int i = 0; i < inh; ++i) { delete[](*intermediate_image)[i]; } delete[](*intermediate_image); for (int i = 0; i < oh; ++i) { delete[](*output_image)[i]; } delete[](*output_image); }
内容的提问来源于stack exchange,提问作者Jacky Yeh
相关产品推荐
相关产品推荐

