You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 13:03:32