cv::Mat与QImage间的转换

4 篇文章 0 订阅

这里将记录一些收集的Mat和QImage间转换的方法,但这些方法不一定是最好的。


一、将cv::Mat转换为QImage

1、共享数据内存

QImage mat_to_qimage_ref(cv::Mat &mat, QImage::Format format)
{
  return QImage(mat.data, mat.cols, mat.rows, mat.step, format);
}

注意:cv::Mat中的内存可能进行扩展(4字节对齐),mat.step表示实际的航长度。如果没有这个参数,结果可能正确,也可能不正确,如下例所示。

QImage mat_to_qimage_ref(cv::Mat &mat, QImage::Format format)
{
  return QImage(mat.data, mat.cols, mat.rows, format);
}

注意:在OpenCV中,图像颜色平面的顺序默认是BGR,因此,应先将其转换为RGB格式。

cv::cvtColor(src, dst, CV_BGR2RGB);


2、拷贝数据

QImage mat_to_qimage_cpy(mat.data, mat.cols, mat.rows, 
                         QImage::Format_ARGB32)
{
   QImage(mat.rows, mat.cols, QImage::Format_ARGB32);
   for (int i = 0;i != image.height(); ++i) {
     memcpy(image.scanline(i), mat.ptr(i), mat.step);
   }
}

上例中的方法看似正确,实际上是有问题的。因为创建QImage时,并不能指定每一行应该有多少字节。下面的方法是正确的解

QImage mat_to_qimage_cpy(cv::Mat const &mat, 
                         QImage::Format format)
{
    return QImage(mat.data, mat.cols, mat.rows, 
                  mat.step, format).copy();
}


二、将QImage转换为cv::Mat

1、共享内存

cv::Mat qimage_to_mat_ref(QImage &img, int format)
{
    return cv::Mat(img.height(), img.width(), 
            format, img.bits(), img.bytesPerLine());
}

2、拷贝内存

cv::Mat qimage_to_mat_cpy(QImage const &img, int format)
{    
    return cv::Mat(img.height(), img.width(), format, 
                   const_cast<uchar>(img.bits()), 
                   img.bytesPerLine()).clone();
}

这里使用了const_cast,可能并不是一个好的方法。


参考文献:

[1] http://qtandopencv.blogspot.com/2013/08/how-to-convert-between-cvmat-and-qimage.html

当你已经得到预处理后的 `cv::Mat` 对象 `processed_image` 并想要转换成 NCNN 需要的 `ncnn::Mat` 格式时,你需要先确保 `cv::Mat` 的类型兼容,因为 NCNN 可能期望的是一个包含单通道灰度图或三通道彩色图的数据结构。下面是转换过程: 1. **将BGR图像转换为RGB(如果需要)**:NCNN通常使用RGB作为颜色空,尽管这取决于具体的模型配置。如果你的 `cv::Mat` 是BGR格式,可以这样做: ```cpp cv::cvtColor(processed_image, processed_image, cv::COLOR_BGR2RGB); ``` 2. **创建NCNN Mat对象**: ```cpp ncnn::Mat ncnn_processed_image; ncnn_processed_image.w = processed_image.cols; ncnn_processed_image.h = processed_image.rows; ncnn_processed_image.c = 3; // 三通道 ncnn_processed_image.data指针指向processed_image.data,即复制 cv::Mat 中的像素数据 ``` 注意这里假设 `processed_image` 是三通道的,如果不是,请根据实际情况调整 `ncnn_processed_image.c`。 3. **检查数据类型**:NCNN 支持多种数据类型,如 float16 和 float32。如果 `cv::Mat` 数据是 uint8_t 类型,你可能需要做进一步的量化或浮点化处理。例如,如果是float32: ```cpp ncnn_processed_image.format = ncnn::DataFormat::f32; // 单精度浮点数 ``` 4. **设置NCNN Mat的数据格式**: ```cpp ncnn_processed_image.step[0] = ncnn_processed_image.w * ncnn_processed_image.c; // 设置行步长 ``` 完成上述操作后,你就有了一个 NCNN 可以直接使用的 `ncnn::Mat` 格式的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值