目录
1、拆分通道
1.1、实例1-拆分一副BGR图像的通道
1.2、实例2-拆分一副HSV图像的通道
2、合并通道
2.1 实例3-合并通道的顺序不同,图像的显示效果也不通
实例4-合格H通道图像、S通道图像、V通道图像
3、综合运用拆分通道和合并通道
2.2、实例5-只把H通道的值调整为180
4、alpha通道
4.1、实例5-调整A通道的值
一副BGR图像是由B通道、G通道、R通道这3个通道构成的。本篇博客介绍如何对通道进行拆分和合并,从而达到处理图像的目的。
1、拆分通道
OpenCvSharp提供Cv2.Split函数,函数如下:
public static void Split(Mat src, out Mat[] mv)
说明
摘要:
Copies each plane of a multi-channel array to a dedicated array
参数:
src:
The source multi-channel array
mv:
The destination array or vector of arrays; The number of arrays must match mtx.channels()
. The arrays themselves will be reallocated if needed
1.1、实例1-拆分一副BGR图像的通道
代码如下:
Mat mat = Cv2.ImRead("test.jpg");
Cv2.ImShow("SRC", mat);Mat[] mv;
Cv2.Split(mat, out mv);Cv2.ImShow("B", mv[0]);
Cv2.ImShow("G", mv[1]);
Cv2.ImShow("R", mv[2]);Cv2.WaitKey();
Cv2.DestroyAllWindows();
原图如下:
运行代码后得到的B、G、R通道图如下:
1.2、实例2-拆分一副HSV图像的通道
代码如下:
Mat mat = Cv2.ImRead("test.jpg");
Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2HSV);
Mat[] mv;
Cv2.Split(mat, out mv);Cv2.ImShow("H", mv[0]);
Cv2.ImShow("S", mv[1]);
Cv2.ImShow("V", mv[2]);Cv2.WaitKey();
Cv2.DestroyAllWindows();
运行代码后得到的H、S、V通道图如下:
2、合并通道
OpenCvSharp提供Cv2.Merge函数合并通道,函数如下:
public static void Merge(Mat[] mv, Mat dst)
说明
摘要:
makes multi-channel array out of several single-channel arrays
参数:
mv:
dst:
2.1 实例3-合并通道的顺序不同,图像的显示效果也不通
编写程序,先拆分通道,再分别按照BGR的顺序和RGB的顺序合并通道。
代码如下:
Mat mat = Cv2.ImRead("test.jpg");
Mat[] mv;
Cv2.Split(mat, out mv);Mat dst = new Mat();
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2] }, dst);
Cv2.ImShow("BGR", dst);Cv2.Merge(new Mat[] { mv[2], mv[1], mv[0] }, dst);
Cv2.ImShow("RGB", dst);Cv2.WaitKey();
Cv2.DestroyAllWindows();
运行代码后,效果如下:
实例4-合格H通道图像、S通道图像、V通道图像
代码如下:
Mat mat = Cv2.ImRead("test.jpg");
Cv2.ImShow("SRC", mat);
Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2HSV);
Mat[] mv;
Cv2.Split(mat, out mv);Mat dst = new Mat();
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2] }, dst);
Cv2.ImShow("HSV", dst);Cv2.WaitKey();
Cv2.DestroyAllWindows();
运行代码后,效果如下:
3、综合运用拆分通道和合并通道
在HSV色彩空间,如果保持其中两个通道的值不变,调整第3个通道的值,可以得到相应的艺术效果。
2.2、实例5-只把H通道的值调整为180
编写一个程序,首先将测试图片从BGR色彩空间转换到HSV色彩空间;然后拆分得到HSV图像中的通道;接着让S通道和V通道的值保持不变,把H通道的值调整为180;再接着合并拆分后的通道图像,把这个图像从HSV色彩空间转换到BGR色彩空间;最后显示得到的BRG图像。代码如下:
Mat mat = Cv2.ImRead("test.jpg");
Cv2.ImShow("SRC", mat);
Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2HSV);
Mat[] mv;
Cv2.Split(mat, out mv);// 将H通道的值全部调整为180
mv[0] = new Mat(mv[0].Size(), mv[0].Type(), new Scalar(180));Mat dst = new Mat();
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2] }, dst);Cv2.CvtColor(dst, dst, ColorConversionCodes.HSV2BGR);
Cv2.ImShow("NEW", dst);
Cv2.WaitKey();
Cv2.DestroyAllWindows();
运行代码后,效果如下:
如果让H通道和S通道的值保持不变,只把V通道的值调整为255,代码如下:
Mat mat = Cv2.ImRead("test.jpg");
Cv2.ImShow("SRC", mat);Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2HSV);
Mat[] mv;
Cv2.Split(mat, out mv);// 将V通道的值全部调整为255
mv[2] = new Mat(mv[2].Size(), mv[2].Type(), new Scalar(255));Mat dst = new Mat();
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2] }, dst);Cv2.CvtColor(dst, dst, ColorConversionCodes.HSV2BGR);
Cv2.ImShow("NEW", dst);
Cv2.WaitKey();
Cv2.DestroyAllWindows();
效果如下:
如果让H通道和V通道的值保持不变,只把S通道的值调整为255,代码如下:
Mat mat = Cv2.ImRead("test.jpg");
Cv2.ImShow("SRC", mat);Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2HSV);
Mat[] mv;
Cv2.Split(mat, out mv);// 将S通道的值全部调整为255
mv[1] = new Mat(mv[1].Size(), mv[1].Type(), new Scalar(255));Mat dst = new Mat();
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2] }, dst);Cv2.CvtColor(dst, dst, ColorConversionCodes.HSV2BGR);
Cv2.ImShow("NEW", dst);
Cv2.WaitKey();
Cv2.DestroyAllWindows();
效果如下:
4、alpha通道
BGR色彩空间包含3个通道,即B通道、G通道、R通道,OpenCV在这个3个通道的基础上,又增加了一个A通道,即alpha通道,用于设置图像的透明度。这样,一个由B通道、G通道、R通道和A通道这4个通道构成的色彩空间就诞生了,即BGRA通道。在BGRA色彩空间中,alpha通道在区间[0,255]内取值;其中0表示透明,255表示不透明。
4.1、实例5-调整A通道的值
编写一个程序,首先将测试图片从BGR色彩空间转换到BGRA色彩空间;然后拆分得到BGRA图像中的通道;接着把BGRA图像的透明度调整为172;再接着合并拆分后的通道图像,再接着BGRA图像的透明度调整为0后,合并拆分后的通道图像;最后分别显示RGBA图像、透明度为172的RGBA图像和透明度为0的RGBA图像,代码如下:
Mat mat = Cv2.ImRead("test.jpg");
Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2BGRA);
Cv2.ImShow("BGRA", mat);Mat[] mv;
Cv2.Split(mat, out mv);Mat dst_bgra_172 = new Mat();
// 将透明度调整为172(半透明)
mv[3] = new Mat(mv[3].Size(), mv[3].Type(), new Scalar(172));
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2], mv[3] }, dst_bgra_172);Mat dst_bgra_0 = new Mat();
// 将透明度调整为0(透明)
mv[3] = new Mat(mv[3].Size(), mv[3].Type(), new Scalar(0));
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2], mv[3] }, dst_bgra_0);Cv2.ImShow("BGRA A=172", dst_bgra_172);
Cv2.ImShow("BGRA A=0", dst_bgra_0);Cv2.WaitKey();
Cv2.DestroyAllWindows();
效果如下:
虽然在代码中调整了BGRA图像中A通道的值,但是显示图像的效果是一样的。为了显示这3幅图的不同效果,需要用方法将这3幅图像保存到磁盘上,代码如下:
Mat mat = Cv2.ImRead("test.jpg");
Cv2.CvtColor(mat, mat, ColorConversionCodes.BGR2BGRA);
Mat[] mv;
Cv2.Split(mat, out mv);Mat dst_bgra_172 = new Mat();
// 将透明度调整为172(半透明)
mv[3] = new Mat(mv[3].Size(), mv[3].Type(), new Scalar(172));
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2], mv[3] }, dst_bgra_172);Mat dst_bgra_0 = new Mat();
// 将透明度调整为0(透明)
mv[3] = new Mat(mv[3].Size(), mv[3].Type(), new Scalar(0));
Cv2.Merge(new Mat[] { mv[0], mv[1], mv[2], mv[3] }, dst_bgra_0);Cv2.ImWrite("brga.png", mat);
Cv2.ImWrite("brga_0.png", dst_bgra_0);
Cv2.ImWrite("brga_172.png", dst_bgra_172);Cv2.WaitKey();
Cv2.DestroyAllWindows();
效果如下:
说明:PNG图像是一种典型的4通道(即B通道、G通道、R通道和A通道)图像,因此被保存的3幅图像的格式为.png