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

调用.hpp中定义的类报错:VS2019+OpenCV3.4.1出现this->p空指针访问冲突

报错触发原因

  • 成员变量初始化顺序不符合C语法规则:C类中成员变量的初始化顺序严格遵循声明顺序,而非赋值顺序。你代码中imgBlank、height、width的声明位置早于original,实例化类时会先初始化imgBlank,此时original还未完成初始化,是无数据的空cv::Mat对象,调用original.size()时访问了空指针,直接触发mat.inl.hpp中的内存访问异常。
  • 类内初始化调用成员函数逻辑非法:成员变量imgGUI在类内直接初始化时调用了crosshair()、imgCoordinate()两个成员函数,此时类实例还未完成整体构造,posX、posY等依赖变量均未赋值,逻辑不成立,属于潜在崩溃点。
  • 额外隐患:cv::Mat默认是浅拷贝,原代码中Mat img = imgBlank直接赋值后绘制,会修改原始的imgBlank对象,导致后续生成的GUI图像叠加旧的绘制内容。

修复方案

  1. 调整成员变量声明顺序,将作为依赖的original放在类成员的最前方。
  2. 取消依赖original的变量的类内默认初始化,新增独立的参数更新方法,在original赋值后手动调用完成初始化,同时增加非空判断避免空指针。
  3. 将预初始化的imgGUI改为动态生成的成员函数,需要使用时实时计算返回结果,避免类未构造完成就调用成员函数的问题。
  4. 绘制图像时调用clone()做深拷贝,避免修改原始的空白背景图。

修复后完整代码

#pragma once
#include "Header_1.h"

class GUI_1
{
public:
    // 输入源图像,作为依赖放在最前面声明
    cv::Mat original;

    // 目标跟踪坐标变量
    int posX = 0;
    int posY = 0;
    
    // 十字准星、文本颜色参数
    double red = 0;
    double green = 255;
    double blue = 255;

    /// @brief 更新GUI依赖参数,original赋值后、坐标变更后可调用
    void updateParams() {
        if (original.empty()) {
            CV_Error(cv::Error::StsBadArg, "输入的original图像为空");
        }
        height = original.size().height;
        width = original.size().width;
        imgBlank = cv::Mat::zeros(original.size(), CV_8UC3);
    }

    /// @brief 绘制十字准星
    cv::Mat crosshair()
    {
        cv::Mat img = imgBlank.clone(); // 深拷贝避免修改原始背景
        int length = 10;
        line(img, cv::Point(posX - length, posY), cv::Point(posX + length, posY), 
             cv::Scalar(blue, green, red), 1);
        line(img, cv::Point(posX, posY - length), cv::Point(posX, posY + length), 
             cv::Scalar(blue, green, red), 1);
        return img;
    }

    /// @brief 绘制坐标文本
    cv::Mat imgCoordinate()
    {
        cv::Mat img = imgBlank.clone();
        const int subX = 2;
        const int subY = 2;
        std::string Text = "X=" + std::to_string(posX) + " Y=" + std::to_string(posY);
        putText(img, Text, cv::Point(posX + subX, posY + subY), 
                cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(blue, green, red), 1);
        return img;
    }

    /// @brief 生成输出GUI图像
    cv::Mat getImgGUI() {
        if (imgBlank.empty()) {
            updateParams();
        }
        return imgBlank + crosshair() + imgCoordinate();
    }

private:
    // 黑色背景图像
    cv::Mat imgBlank;
    // 图像尺寸参数
    int height = 0;
    int width = 0;
};

使用示例

// 实例化类
GUI_1 gui;
// 给输入源图像赋值
gui.original = imread("test.jpg");
// 更新参数
gui.updateParams();
// 赋值坐标
gui.posX = 100;
gui.posY = 100;
// 获取生成的GUI图像
Mat guiImg = gui.getImgGUI();
imshow("GUI", guiImg);

内容的提问来源于stack exchange,提问作者Grey Cat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 11:15:05