OpenCV(九)—————图像通道合并与分离(C++)

1.分离

将一张图像分别分成三个通道的图像.

使用split()函数,分离之后的数据存到一个Mat对象的容器中.

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;


int main(int argc,char** argv)
{
    //  读入图像
    Mat src = imread("../meizi.jpg");
    if(src.empty())
    {
        printf("不能找到文件。\n");
        return -1;
    }
    namedWindow("input",WINDOW_AUTOSIZE);
    imshow("input", src);

    vector<Mat> mv;
    split(src,mv);
    imshow("blue channel",mv[0]);
    imshow("green channel",mv[1]);
    imshow("red channel",mv[2]);

    waitKey(0);
    destroyAllWindows();
    return 0;
}

输出结果:

原图:

blue通道:

red通道:

green通道:

可明显看出来红色通道亮度最高,即占比最大.

2.合并

将红色通道去掉再合并的效果:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;


int main(int argc,char** argv)
{
    //  读入图像
    Mat src = imread("../meizi.jpg");
    if(src.empty())
    {
        printf("不能找到文件。\n");
        return -1;
    }
    namedWindow("input",WINDOW_AUTOSIZE);
    imshow("input", src);

    //  分离
    vector<Mat> mv;
    split(src,mv);

    //  合并,将红色通道去掉再合并的效果
    mv[2] = Scalar(0);
    Mat dst;
    merge(mv,dst);
    imwrite("../result.jpg",dst);
    imshow("result",dst);

    waitKey(0);
    destroyAllWindows();
    return 0;
}

结果:

假如绿色通道缺失:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;


int main(int argc,char** argv)
{
    //  读入图像
    Mat src = imread("../meizi.jpg");
    if(src.empty())
    {
        printf("不能找到文件。\n");
        return -1;
    }
    namedWindow("input",WINDOW_AUTOSIZE);
    imshow("input", src);

    //  分离
    vector<Mat> mv;
    split(src,mv);

    //  合并,green通道缺失的情况
    mv[1] = Scalar(0);
    Mat dst;
    merge(mv,dst);
    imwrite("../result.jpg",dst);
    imshow("result",dst);

    waitKey(0);
    destroyAllWindows();
    return 0;
}

结果:

蓝色通道缺失:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;


int main(int argc,char** argv)
{
    //  读入图像
    Mat src = imread("../meizi.jpg");
    if(src.empty())
    {
        printf("不能找到文件。\n");
        return -1;
    }
    namedWindow("input",WINDOW_AUTOSIZE);
    imshow("input", src);

    //  分离
    vector<Mat> mv;
    split(src,mv);

    //  合并,blue通道缺失的情况
    mv[0] = Scalar(0);
    Mat dst;
    merge(mv,dst);
    imwrite("../result.jpg",dst);
    imshow("result",dst);

    waitKey(0);
    destroyAllWindows();
    return 0;
}

结果:

将绿色通道取反再令其缺失:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;


int main(int argc,char** argv)
{
    //  读入图像
    Mat src = imread("../meizi.jpg");
    if(src.empty())
    {
        printf("不能找到文件。\n");
        return -1;
    }
    namedWindow("input",WINDOW_AUTOSIZE);
    imshow("input", src);

    //  分离
    vector<Mat> mv;
    split(src,mv);
    //  将绿色通道比重增大(取反)
    bitwise_not(mv[2],mv[2]);

    //  合并,增大后的green通道缺失的情况
    mv[2] = Scalar(0);
    Mat dst;
    merge(mv,dst);
    imwrite("../result.jpg",dst);
    imshow("result",dst);

    waitKey(0);
    destroyAllWindows();
    return 0;
}

结果:

3.补充API---ROI

这个api是用来截图图像的,通过设置参数可以截取部分图像,要注意一个问题,截取的图像改变的话,是会改变原图像的,因为两者指向的是同一个内存对象.

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;


int main(int argc,char** argv)
{
    //  读入图像
    Mat src = imread("../meizi.jpg");
    if(src.empty())
    {
        printf("不能找到文件。\n");
        return -1;
    }
    namedWindow("input",WINDOW_AUTOSIZE);
    imshow("input", src);

    //  分离
    vector<Mat> mv;
    split(src,mv);

    Rect roi;
    roi.x = 100;
    roi.y = 100;
    roi.width = 250;
    roi.height = 200;
    Mat sub = src(roi);
    rectangle(src,roi,Scalar(255,255,0),1,8);
    imshow("roi",sub);
    imshow("input",src);

    waitKey(0);
    destroyAllWindows();
    return 0;
}

输出结果:

如果想要截取的图像不能改变原图像:

Mat sub = src(roi).clone();

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章