QImage的指针问题

接着上一篇博客:OpenCV&Qt学习之一——打开图片文件并显示,实现基本的打开图片并转换显示之后接下来将函数在分别进行封装,便于下一步的处理。代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_openButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this,tr("Open Image"),
                                ".",tr("Image Files (*.png *.jpg *.bmp)"));
    qDebug()<<"filenames:"<<fileName;
    image = cv::imread(fileName.toAscii().data());
    qimg = Widget::Mat2QImage(image);
    display(qimg);                      //display by the label
}

QImage Widget::Mat2QImage(const cv::Mat &mat)
{
    QImage img;
    Mat rgb;
    if(mat.channels()==3)
    {
        //cvt Mat BGR 2 QImage RGB
        cvtColor(mat,rgb,CV_BGR2RGB);
        img =QImage((const unsigned char*)(rgb.data),
                    rgb.cols,rgb.rows,
                    rgb.cols*rgb.channels(),
                    QImage::Format_RGB888);
    }
    else
    {
        img =QImage((const unsigned char*)(mat.data),
                    mat.cols,mat.rows,
                    mat.cols*mat.channels(),
                    QImage::Format_RGB888);
    }
    return img;
}

void Widget::display(const QImage img)
{
    ui->imagelabel->setPixmap(QPixmap::fromImage(img));
    ui->imagelabel->resize(ui->imagelabel->pixmap()->size());
}

相对于OpenCV&Qt学习之一——打开图片文件并显示 中间的代码,这里的改动有限,只是把转换的功能单独封装成为一个函数QImage Widget::Mat2QImage(const cv::Mat &mat) 通过返回的方式,再调用void Widget::display(const QImage img) 来显示,本来觉得应该非常简单的,但是一运行显示的不是全白就是全黑的图像,而把

ui->imagelabel->setPixmap(QPixmap::fromImage(img));
    ui->imagelabel->resize(ui->imagelabel->pixmap()->size());

直接放入return之前在函数中显示就没有任何问题,也就是说,img在函数内部没有问题,但是在通过函数调用传出来的时候丢了数据,我以为是由于设置成局部变量被释放的原因,各种尝试之后仍然不行,这个问题让我郁闷了一下午。

由于之前做的多是单片机等嵌入式平台的程序开发,所  以涉及到的语言应用都比较基础,经过多方查找才发现可能是指针问题,这里先看QImage的定义:

img =QImage((const unsigned char*)(rgb.data),
                    rgb.cols,rgb.rows,
                    rgb.cols*rgb.channels(),
                    QImage::Format_RGB888);

QImage格式和Mat是在数据结构上有所不同,这里的img只是对Mat格式的rgb中的数据进行重新组织,其中数据部分还是(const unsigned char*)(rgb.data),是指向rgb的指针,而问题就出在rgb上,rgb是被定义为局部变量的,在函数调用结束后,虽然值能够被正常传递,但是指针指向的位置却被释放了,因此把rgb更改为全局变量问题解决。

这个问题在大量指针的运用中非常容易出错,而且不易发现,看来指针的运用还需要加强学习。

### 关于ESP32-CAM设备中的指针问题 在处理ESP32-CAM设备时,指针问题是常见的开发障碍之一。以下是针对该问题的具体分析和解决方案: #### 1. **图像缓冲区指针 (fb->buf)** 的正确使用 当涉及到从摄像头获取帧并存储到SD卡或其他介质时,`esp_camera_fb_get()` 函数返回的 `camera_frame_t * fb` 结构体包含了指向实际图像数据的指针 `fb->buf`。如果直接操作此指针而不考虑其内存布局,则可能导致数据损坏或不一致。 为了确保能够正确读取完整的图像数据,需注意以下几点: - 图像数据可能分片存储,因此需要逐字节访问整个缓冲区。 - 使用循环逐步移动指针位置以完成连续的数据拷贝[^3]。 示例代码如下所示: ```c #include "esp_camera.h" void save_image_to_sd_card() { camera_fb_t *fb = esp_camera_fb_get(); if (!fb) { Serial.println("Camera capture failed"); return; } File file = SD.open("/image.jpg", FILE_WRITE); if (!file) { Serial.println("Failed to open file for writing"); esp_camera_fb_return(fb); return; } uint8_t* ptr = fb->buf; // 初始化指针至起始地址 size_t remaining_bytes = fb->len; while (remaining_bytes > 0) { size_t bytes_written = file.write(ptr, remaining_bytes); // 单次写入部分数据 if (bytes_written == 0) break; // 如果失败则退出 ptr += bytes_written; // 更新指针偏移量 remaining_bytes -= bytes_written; // 记录剩余未写入长度 } file.close(); // 完成文件关闭动作 esp_camera_fb_return(fb); // 归还帧缓存资源 } ``` 上述方法通过动态调整指针的位置实现了对大块数据的安全管理,并有效规避了因一次性传输过大而导致的问题。 #### 2. 开发环境的选择影响效率 对于复杂项目而言,选用合适的IDE至关重要。Arduino IDE虽然入门门槛低,但在面对大量第三方库集成场景下显得力不从心;相比之下Visual Studio Code配合PlatformIO插件可以提供更强大的调试功能和支持文档检索能力,从而显著提升解决问题的速度与准确性。 例如,在VSCode环境下可以通过断点跟踪变量变化轨迹、快速定位异常源头等功能加速排查过程。此外还能方便查阅官方API手册了解具体参数含义及其适用范围等重要信息。 --- ### 总结 综上所述,解决ESP32-CAM设备上的指针相关难题主要依赖两方面措施:一方面要严格遵循正确的编程逻辑模式去操控那些涉及底层硬件交互的关键结构成员(如这里提到过的frame buffer pointer);另一方面也要重视选取恰当的工作平台以便更好地应对可能出现的各种状况。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值