按照网上专业一些的教程,接下来应该讲讲图像平滑、直方图,但是我前面刚讲完色彩处理,突然又发现了一个无缝融合的应用,也可以改颜色的,索性就先把它讲了,包括四个函数,反正这四个函数在具体工程项目上的实际意义都没有后面的平滑、直方图重要,主打的就是一个好玩,类似于PhotoShop中的某些特效。
无缝融合的应用,按照Emgu.CV的源头----OpenCV的叫法,是属于Seamless Cloning这一部分,看这个网址有介绍:
OpenCV: Seamless Cloning
Emgu.CV也保留了这一部分,今天先讲ColorChange()函数,它可以改变指定目标区域的颜色,函数是这样定义的:
public static void ColorChange (
IInputArray src, // 输入图像
IInputArray mask, // 掩码图,单通道或者三通道都可以,非零部分不起作用
IOutputArray dst, // 输出图像
float redMul = 1f, // 红色通道乘积因子(建议值0.5~2.5)
float greenMul = 1f, // 绿色通道乘积因子(建议值0.5~2.5)
float blueMul = 1f // 蓝色通道乘积因子(建议值0.5~2.5)
)
这个函数使用起来也很简单,首先选取要改变颜色的区域,生成一个和原图像尺寸相同的掩码图,再利用redMul、greenMul 、blueMul 三个参数,就可以改变图像的颜色了。以一张青红苹果图片为例,通过设定能将青苹果包住ROI,生成掩码图,再改变三个通道的乘积因子,就能将青苹果改成你想要的颜色,如下图:
代码很简单,WPF里面用了四个文本框代表ROI的位置大小,三个Slider实现乘积因子值选择,代码如下:
Mat tempMat = srcMat.Clone(); // 深拷贝
Mat dstMat = new Mat();
Rectangle rect = new Rectangle(Convert.ToInt32(TextBoxX.Text.Trim().ToString()), Convert.ToInt32(TextBoxY.Text.Trim().ToString()), Convert.ToInt32(TextBoxWidth.Text.Trim().ToString()), Convert.ToInt32(TextBoxHeight.Text.Trim().ToString()));
Mat mask = Mat.Zeros(tempMat.Height, tempMat.Width, DepthType.Cv8U, 3);
CvInvoke.Rectangle(mask, rect, new MCvScalar(255, 255, 255), -1, LineType.EightConnected, 0); // thickness = -1,代表实心
float redMul = Convert.ToSingle(Slider1.Value); // 红色通道乘积因子(建议值0.5~2.5)
float greenMul = Convert.ToSingle(Slider2.Value); // 绿色通道乘积因子(建议值0.5~2.5)
float blueMul = Convert.ToSingle(Slider3.Value); // 蓝色通道乘积因子(建议值0.5~2.5)
CvInvoke.ColorChange(tempMat, mask, dstMat, redMul, greenMul, blueMul);
CvInvoke.Rectangle(dstMat, rect, new MCvScalar(255, 255, 255), 1, LineType.EightConnected, 0);
CvInvoke.Imshow("Mask, " + mask.Size.ToString(), mask);
CvInvoke.Imshow("ColorChange image, " + dstMat.Size.ToString(), dstMat);
再如下面这个图,通过增大绿色通道因子值,把西瓜瓤变色的演示。
注意哈,在Emgu.CV中,如果是白色背景的图, ColorChange()函数的使用效果好像不太好,OpenCV里有没有这个问题我还真不知道,比如下面这个图,读者们可以自己试试改变红苹果的颜色,反正我这里是颜色改变的有些乱套。
原创不易,请勿抄袭。共同进步,相互学习。