学习opencv:PS滤镜—等高线

        摸索了两天,终于把等高线效果做出来了,摸索的过程也有记录的意义。下面开始。

        等高线滤镜有色阶、较低、较高三个控制项,根据PS书籍记载,选择"较低"选项时将在基准亮度以下的轮廓上产生等高线,反之,在基准亮度以上的轮廓上产生等高线,这里的基准亮度就是指色阶。根据描述,可知这里进行了阈值处理,可以确定选择“较低”选项时,高于基准亮度的部分会被忽略,即置零,至于低于基准亮度的部分是保持不变还是置为统一值,还不能下结论,下面我们使用photoshop对一张图片应用等高线滤镜,观察结果以得出跟进一步的结论。设置色阶为128,较低,如下所示:

学习opencv:PS滤镜—等高线_第1张图片           学习opencv:PS滤镜—等高线_第2张图片

        首先可以看到结果是一幅边缘图像,简单起见,直接调用Canny算法实现这个效果;其次,背景为白色,说明进行了反色处理;最后,处理结果中的颜色数量很少,只有黑,白,红,绿,蓝,黄(红绿组合),品红(红蓝组合),青(绿蓝组合)这8种,可见像素各通道的值只有两种(0和255),通过软件读取图像像素值可以发现确实如此,由此可以得出结论,进行阈值处理时,一部分像素被置零,另一部分被置为255,而不是保持不变,可见,等高线滤镜的本质是以基准色阶为界限,将图像分为明暗两部分,它们的分界线就是滤镜处理的结果。

        等高线滤镜处理步骤:阈值处理;求边缘;反色。代码如下:

#include  
#include   
#include 
#include   

using namespace std;

int main()
{
	int TH = 128; //基准色阶
	int flag = 0; //0: 较低  其他:较高
	cv::Mat img = cv::imread("D:\\timg.jpg");
	cv::Mat Result;
	vector channels, outline(3);
	cv::ThresholdTypes mode;
	cv::split(img, channels);

	if (flag == 0)
	{
		TH--;  //PS精确观察结果,不自减对结果影响不大
		mode = cv::THRESH_BINARY_INV;
	}
	else
	{
		mode = cv::THRESH_BINARY;
	}
	cv::threshold(channels[0], channels[0], TH, 255, mode);
	cv::threshold(channels[1], channels[1], TH, 255, mode);
	cv::threshold(channels[2], channels[2], TH, 255, mode);
	cv::Canny(channels[0], outline[0], 255, 255);
	cv::Canny(channels[1], outline[1], 255, 255);
	cv::Canny(channels[2], outline[2], 255, 255);
	cv::merge(outline, Result);
	Result = cv::Scalar(255, 255, 255) - Result;
	cv::imshow("result", Result);
	cv::waitKey(200000);
	return 0;
}

处理结果

学习opencv:PS滤镜—等高线_第3张图片

        与photoshop的处理结果在细微处略有差别,可能是边缘算法上有所区别,但总体上是基本一致的。 

 

你可能感兴趣的:(图像处理)