QImage、cv::Mat 与 HalconCpp::HObject 之间的转换

在机器视觉应用中,不同的图像处理库和框架常使用不同的数据结构来表示图像。常用的库包括 Qt 的 QImage、OpenCV 的 cv::Mat 以及 Halcon 的 HObject。为了在这些库之间实现无缝的数据传递和处理,图像格式的转换成为必不可少的环节。本文将详细介绍如何在 QImagecv::MatHalconCpp::HObject 之间进行相互转换,并提供相应的代码实现。

1. QImage 到 cv::Mat 的转换

QImage 是 Qt 框架中表示图像的类,它支持多种格式(如 RGB32、RGB888、灰度等)。为了将 QImage 转换为 OpenCV 的 cv::Mat,需要根据 QImage 的格式构建不同类型的 cv::Mat。代码如下:

cv::Mat QImageToMat(const QImage& image) {
    switch (image.format()) {
    case QImage::Format_RGB32: {
        // 对于 Format_RGB32 格式,QImage 是 RGBA 格式,4 通道
        cv::Mat mat(image.height(), image.width(), CV_8UC4, const_cast<uchar*>(image.bits()), image.bytesPerLine());
        return mat.clone();  // 需要深拷贝,防止指针问题
    }
    case QImage::Format_RGB888: {
        // 对于 RGB888 格式,QImage 是 RGB 格式,3 通道
        cv::Mat mat(image.height(), image.width(), CV_8UC3, const_cast<uchar*>(image.bits()), image.bytesPerLine());
        return mat.clone();  // 深拷贝
    }
    case QImage::Format_Grayscale8: {
        // 对于 Grayscale8 格式,QImage 是灰度图,1 通道
        cv::Mat mat(image.height(), image.width(), CV_8UC1, const_cast<uchar*>(image.bits()), image.bytesPerLine());
        return mat.clone();  // 深拷贝
    }
    default:
        // 如果遇到不支持的格式,输出警告信息
        qWarning() << "不支持的 QImage 格式!";
        return cv::Mat();
    }
}

这段代码通过检测 QImage 的格式,将其正确地转换为相应的 cv::Mat 格式,并进行深拷贝以防止指针问题。

2. cv::Mat 到 QImage 的转换

在很多情况下,OpenCV 的 cv::Mat 是图像处理的核心数据结构。如果需要将 cv::Mat 转换为 QImage,则需要处理不同的通道数(如单通道灰度图、三通道 BGR 图像、四通道 RGBA 图像等)。以下是转换实现:

QImage MatToQImage(const cv::Mat& mat) {
    switch (mat.type()) {
    case CV_8UC1: {
        // 单通道灰度图
        return QImage(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_Grayscale8).copy();  // 深拷贝
    }
    case CV_8UC3: {
        // 三通道彩色图像,OpenCV 默认是 BGR 格式,需要转换为 RGB
        return QImage(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888).rgbSwapped().copy();  // 深拷贝
    }
    case CV_8UC4: {
        // 四通道 RGBA 图像
        return QImage(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32).copy();  // 深拷贝
    }
    default:
        qWarning() << "不支持的 cv::Mat 格式!";
        return QImage();
    }
}

在这段代码中,如果 cv::Mat 是三通道的 BGR 格式,必须先转换为 RGB 格式。深拷贝是为了避免数据被意外修改或释放。

3. cv::Mat 到 HalconCpp::HObject 的转换

Halcon 是工业机器视觉中广泛使用的库,其 HObject 是处理图像的基础数据结构。将 cv::Mat 转换为 HObject 时,需要分别处理单通道灰度图和三通道彩色图(需要从 BGR 转换为 RGB)。代码如下:

HalconCpp::HObject MatToHObject(const cv::Mat& mat) {
    HalconCpp::HObject hImage;

    if (mat.type() == CV_8UC1) {
        // 单通道灰度图像
        HalconCpp::GenImage1(&hImage, "byte", mat.cols, mat.rows, (Hlong)mat.data);
    } else if (mat.type() == CV_8UC3) {
        // 三通道彩色图像,OpenCV 中是 BGR 格式,需转换为 RGB 格式
        cv::Mat rgbMat;
        cv::cvtColor(mat, rgbMat, cv::COLOR_BGR2RGB);
        HalconCpp::GenImageInterleaved(&hImage, (Hlong)rgbMat.data, "rgb", rgbMat.cols, rgbMat.rows, -1, "byte", 0, 0, 0, 0, -1, 0);
    } else {
        qWarning() << "不支持的 cv::Mat 格式转换为 HalconCpp::HObject!";
    }

    return hImage;
}

通过此方法,我们可以将 OpenCV 的 cv::Mat 格式转化为 Halcon 的 HObject,并且保证彩色图像的通道顺序正确。

4. HalconCpp::HObject 到 cv::Mat 的转换

HObject 转换为 cv::Mat 也涉及到通道数的处理。以下是相应的代码:

cv::Mat HObjectToMat(const HalconCpp::HObject& hImage) {
    HTuple hChannels;
    HalconCpp::CountChannels(hImage, &hChannels);

    if (hChannels[0].I() == 1) {
        HTuple hWidth, hHeight;
        HalconCpp::GetImageSize(hImage, &hWidth, &hHeight);

        cv::Mat mat(hHeight.I(), hWidth.I(), CV_8UC1);
        HalconCpp::GetImagePointer1(hImage, nullptr, nullptr, &hWidth, &hHeight);
        memcpy(mat.data, (void*)hImage.GetDataPointer(), mat.total());

        return mat;
    } else if (hChannels[0].I() == 3) {
        HTuple hWidth, hHeight;
        HalconCpp::GetImageSize(hImage, &hWidth, &hHeight);

        cv::Mat mat(hHeight.I(), hWidth.I(), CV_8UC3);
        HalconCpp::GetImagePointer3(hImage, nullptr, nullptr, nullptr, &hWidth, &hHeight);
        memcpy(mat.data, (void*)hImage.GetDataPointer(), mat.total() * 3);

        cv::cvtColor(mat, mat, cv::COLOR_RGB2BGR);
        return mat;
    } else {
        qWarning() << "不支持的 HObject 格式转换为 cv::Mat!";
        return cv::Mat();
    }
}

此方法通过 Halcon 提供的 API 获取图像的指针,并将数据复制到 cv::Mat 对象中。对于彩色图像,需要将 RGB 格式转换为 OpenCV 的 BGR 格式。

结论

本文介绍了如何在 Qt 的 QImage、OpenCV 的 cv::Mat 和 Halcon 的 HObject 之间进行相互转换,这在图像处理和机器视觉应用中尤为重要。通过这些转换方法,不同库之间的图像处理功能可以被集成到同一个应用程序中,从而实现更强大的图像处理能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极客晨风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值