图像处理
1.数值滤波(5种)
高斯滤波:(正态分布的概率分布)ksize高宽都必须为正数和奇数,double的sigmaX就是X方向标准差,sigmaY一样。这几个最好是都设置。
GaussianBlur(img, dst1, Size(5, 5), 0, 0);
中值滤波:去除小颗粒等有效,基本思想就是用像素点领域灰度值的中值来代替当前的灰度值,当然运行时间也会更久medianBlur(img, dst2, 5);
,5就是孔径的线性尺寸。
双边滤波:好处就是可以做边缘保存
bilateralFilter(img, dst3, 25, 25 * 2, 25 / 2);
第三个参数是像素领域的直径
2.形态学滤波
膨胀(dilate)和腐蚀(erode)都是对白色即高亮部分而言,膨胀就是求局部最大值的操作,核与图形卷积,计算覆盖区域的最大值,并赋给参考点。,腐蚀则恰恰相反,即求最小值的操作。
膨胀(腐蚀也一样):
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
//getStructuringElement有三种形状,上面的矩形,还有MORPH_CROSS 十字形,MORPH_ELLIPSE椭圆形
dilate(img, dst1, element);
//第三个参数是膨胀操作的核element,一般都是用getStructuringElement来定义
下面是这两个综合的一个示例,也是加了个Trackbar
//-----------------------------------【全局变量声明部分】--------------------------------------
// 描述:全局变量声明
//-----------------------------------------------------------------------------------------------
Mat g_srcImage, g_dstImage;//原始图和效果图
int g_nTrackbarNumer = 0;//0表示腐蚀erode, 1表示膨胀dilate
int g_nStructElementSize = 3; //结构元素(内核矩阵)的尺寸
//-----------------------------------【全局函数声明部分】--------------------------------------
// 描述:全局函数声明
//-----------------------------------------------------------------------------------------------
void Process();//膨胀和腐蚀的处理函数
void on_TrackbarNumChange(int, void *);//回调函数
void on_ElementSizeChange(int, void *);//回调函数
void ShowHelpText();
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main( )
{
//改变console字体颜色
system("color 2F");
//载入原图
g_srcImage = imread("1.jpg");
if( !g_srcImage.data ) { printf("读取srcImage错误~! \n"); return false; }
ShowHelpText();
//显示原始图
namedWindow("【原始图】");
imshow("【原始图】", g_srcImage);
//进行初次腐蚀操作并显示效果图
namedWindow("【效果图】");
//获取自定义核
Mat element = getStructuringElement(MORPH_RECT, Size(2*g_nStructElementSize+1, 2*g_nStructElementSize+1),Point( g_nStructElementSize, g_nStructElementSize ));
erode(g_srcImage, g_dstImage, element);
imshow("【效果图】", g_dstImage);
//创建轨迹条
createTrackbar("腐蚀/膨胀", "【效果图】", &g_nTrackbarNumer, 1, on_TrackbarNumChange);
createTrackbar("内核尺寸", "【效果图】", &g_nStructElementSize, 21, on_ElementSizeChange);
//输出一些帮助信息
cout<<endl<<"\t运行成功,请调整滚动条观察图像效果~\n\n"
<<"\t按下“q”键时,程序退出。\n";
//轮询获取按键信息,若下q键,程序退出
while(char(waitKey(1)) != 'q') {}
return 0;
}
//-----------------------------【Process( )函数】------------------------------------
// 描述:进行自定义的腐蚀和膨胀操作
//-----------------------------------------------------------------------------------------
void Process()
{
//获取自定义核
Mat element = getStructuringElement(MORPH_RECT, Size(2*g_nStructElementSize+1, 2*g_nStructElementSize+1),Point( g_nStructElementSize, g_nStructElementSize ));
//进行腐蚀或膨胀操作
if(g_nTrackbarNumer == 0) {
erode(g_srcImage, g_dstImage, element);
}
else {
dilate(g_srcImage, g_dstImage, element);
}
//显示效果图
imshow("【效果图】", g_dstImage);
}
//-----------------------------【on_TrackbarNumChange( )函数】------------------------------------
// 描述:腐蚀和膨胀之间切换开关的回调函数
//-----------------------------------------------------------------------------------------------------
void on_TrackbarNumChange(int, void *)
{
//腐蚀和膨胀之间效果已经切换,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来
Process();
}
//-----------------------------【on_ElementSizeChange( )函数】-------------------------------------
// 描述:腐蚀和膨胀操作内核改变时的回调函数
//-----------------------------------------------------------------------------------------------------
void on_ElementSizeChange(int, void *)
{
//内核尺寸已改变,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来
Process();
}
高阶运用
开运算:先腐蚀后膨胀,用来消除小物体,在纤细点处分离物体
闭运算:先膨胀后腐蚀,排除小型黑色区域。
形态学阶梯:膨胀-腐蚀,用以突出边缘。
顶帽运算(Top Hat):原图-开运算,突出了比原图轮廓周围的区域更明亮的区域
黑帽:闭运算-原图,分离比邻近点暗一点的斑块,可以提出非常完美的轮廓