OpenCV 学习 (Split 和 Merge)

来源:互联网 发布:苍云正太脸型数据 编辑:程序博客网 时间:2024/05/22 10:39

OpenCV 学习 (Split 和 Merge)

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

split 函数

用于将一幅多通道的图像的各个通道分离。
这个函数的原型如下:

void split(const Mat& src, vector<Mat_<_Tp> >& mv)

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

merge 函数

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

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

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

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

QList<QImage> split(const QImage &image);QImage merge(const QImage &channel_R, const QImage &channel_G, const QImage &channel_B);

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

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

#include <QImage>#include <QVector>inline 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_G, 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))    {        // 如果图像占用的内存是连续的,则可以只用一个循环来处理        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;}QList<QImage> split(const QImage &image){    QList<QImage> rgb;    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, 0));            rgb[1].setColor(i, qRgb(0, i, 0));            rgb[2].setColor(i, qRgb(0, 0, 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;}
4 1
原创粉丝点击