OpenCV 学习 Split 和 Merge

OpenCV 学习 (Split 和 Merge)

我们在图象处理时,常常要单独对某1个色彩通道进行处理。这时候可以利用 Opencv 提供的 split 和 merge 函数

split 函数

用于将1幅多通道的图象的各个通道分离。
这个函数的原型以下:


void split(const Mat& src,vector& mv)


用法很简单,src 是1幅多通道的图象。
mv 保存各个通道,每一个通道寄存到1个 mat 中。

merge 函数

merge 与split 函数相反。可以将多个单通道图象合成1幅多通道图象。
函数原型以下:


void merge(const Mat* mv,size_t count,OutputArray dst);
void merge(const vector& mv,OutputArray dst );


这两个函数非常简单,所以就不举例子了。

有时,我用Qt写的小程序中也需要这个功能,又不想为了这么点小功能就使用 opencv。所以就自己山寨了两个函数。(实际上是这篇博客实在是太短了,要找些内容来凑数)
两个函数函数声明以下:


QListsplit(const QImage &image);
QImage merge(const QImage &channel_R,const QImage &channel_G,const QImage &channel_B);


这里 merge 函数只能合并 3 个色彩通道。如果需要 alpha 通道,可以在这代码基础上修改

下面是代码,不多解释。希望对大家有用。


#include#includeinline static bool isContinuous(const QImage &image)
{
    bool ret = false;
    switch(image.format())
    {
    case QImage::Format_Indexed8:
        ret = image.bytesPerLine() == image.width();
        break;
    case QImage::Format_ARGB32:
    case QImage::Format_RGB32:
    case QImage::Format_ARGB32_Premultiplied:
    case QImage::Format_RGBX8888:
    case QImage::Format_RGBA8888:
    case QImage::Format_RGBA8888_Premultiplied:
    case QImage::Format_BGR30:
    case QImage::Format_A2BGR30_Premultiplied:
    case QImage::Format_RGB30:
    case QImage::Format_A2RGB30_Premultiplied:
        ret = image.bytesPerLine() == 4 * image.width();
        break;
    case QImage::Format_RGB16:
    case QImage::Format_RGB555:
    case QImage::Format_RGB444:
    case QImage::Format_ARGB4444_Premultiplied:
        ret = image.bytesPerLine() == 2 * image.width();
        break;
    case QImage::Format_ARGB6666_Premultiplied:
    case QImage::Format_ARGB8565_Premultiplied:
    case QImage::Format_RGB666:
    case QImage::Format_ARGB8555_Premultiplied:
    case QImage::Format_RGB888:
        ret = image.bytesPerLine() == 3 * image.width();
    case QImage::Format_Mono:
    case QImage::Format_MonoLSB:
        ret = image.byteCount()* 8 == image.width() * image.height();
    default:
        ret = false;
        break;
    }
    return ret;
}

QImage merge(const QImage &channel_R,const QImage &channel_B)
{
    if(channel_R.size() != channel_G.size() || channel_R.size() != channel_B.size())
    {
        return QImage();
    }
    if(channel_R.format() != QImage::Format_Indexed8 ||
            channel_G.format() != QImage::Format_Indexed8 ||
            channel_B.format() != QImage::Format_Indexed8)
    {
        return QImage();
    }
    QImage image(channel_R.size(),QImage::Format_RGB32);
    int width = image.width();
    int height = image.height();
    if(isContinuous(image) && isContinuous(channel_B) && isContinuous(channel_G) && isContinuous(channel_R))
    {
        // 如果图象占用的内存是连续的,则可以只用1个循环来处理
        width = width * height;
        height = 1;
    }
    for(int j = 0; j < height; j++) { QRgb* line = (QRgb*) image.scanLine(j); const uchar * r = channel_R.constScanLine(j); const uchar * g = channel_G.constScanLine(j); const uchar * b = channel_B.constScanLine(j); for(int i = 0; i < width; i++) { line[i] = qRgb(r[i],g[i],b[i]); } } return image; } QListsplit(const QImage &image) { QListrgb; if(image.isNull()) { return rgb; } QImage::Format f = image.format(); if(f == QImage::Format_RGB32 || f == QImage::Format_ARGB32 || f == QImage::Format_ARGB32_Premultiplied) { rgb.append(QImage()); rgb.append(QImage()); rgb.append(QImage()); rgb[0] = QImage(image.size(),QImage::Format_Indexed8); rgb[1] = QImage(image.size(),QImage::Format_Indexed8); rgb[2] = QImage(image.size(),QImage::Format_Indexed8); for(int i = 0; i < 256; i++) { rgb[0].setColor(i,qRgb(i,0)); rgb[1].setColor(i,qRgb(0,i,0)); rgb[2].setColor(i,i)); } int width = image.width(); int height = image.height(); for(int j = 0; j < height; j++) { const QRgb* line = (QRgb*) image.constScanLine(j); uchar * line_r = rgb[0].scanLine(j); uchar * line_g = rgb[1].scanLine(j); uchar * line_b = rgb[2].scanLine(j); for(int i = 0; i < width; i++) { line_r[i] = qRed(line[i]); line_g[i] = qGreen(line[i]); line_b[i] = qBlue(line[i]); } } } return rgb; }


相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...