图像增强之03锐化

来源:互联网 发布:plsql查看存储过程源码 编辑:程序博客网 时间:2024/06/01 08:40

之前讲述的是通过做直方图均衡化的方法达到增强图像的方法。除此之外,锐化也是常用的一种手段。通过锐化处理之后的图像,可以使得边缘清晰,颜色更鲜明,可以用于进一步提取图像的边缘进行图像分割,区域形状提取等。

0 锐化方法

       图像锐化的方法,通常分为基于空间域的微分法和基于频域的高通滤波法,本文暂时只讲述微分法,之后会补充高通滤波法。

       微分法的原理其实就是数学的逆运算,通常图像模糊可能是经过平滑处理(平均或积分运算)的原因。所以从数学角度考虑,进行逆运算,即微分运算可在一定程度增强图像。而微分运算其实也属于梯度运算。所以基于微分法的图像锐化其实是基于梯度的一种处理。如果单纯以梯度值(梯度幅值)进行替换,则会破坏图像。

       另外,用梯度算子卷积进行微分锐化时,因为算子分为X和Y方向,所以锐化也分X和Y方向,但如果不是特殊说明都是指进行二阶即同时XY运算(所以选择的梯度算子通常是二阶的)。

1 微分算法实现

       虽然原理上是基于梯度算子的卷积运算,但是一些细节的处理上还是有不同的方法的。又可以分为三类,基于标准梯度公式,基于锐化算子模板和较为复杂的USIM。

1.1    基于标准梯度公式

正如你能在网上查阅到的绝大多数资料那样,梯度的算法是标准的公式。最终概括如下图。


       通常近似为。


之后需要进一步后处理,也有不同的算法可以辅助,如下所述。

0)辅以阀值判断设T为阀值,像素的梯度值大于T,则像素的灰度(或者RGB的分量)加上某一个值(如100),加上某一个值(如100)像素的灰度值(或RGB的分量值)后若大于255,取255。


1)设以某一特定值设t为阀值,像素的梯度值大于T,则像素的灰度(或者RGB的分量)设置为某一定值La。


2)二值化图像设T为阀值,像素的梯度值大于T,则像素的灰度(或者RGB的分量)设置为255,否则设置为0。


1.2 基于算子模板

       即设计一个可以满足二阶运算的梯度算子模板,如下图。

-1

-1

-1

-1

12

-1

-1

-1

-1

       后处理的方法,是设计缩放因子scale,其值等于梯度算子中各个值的累加和。在完成卷积运算后,进行scale处理,即除以缩放因子。

       另外模板的选取方面,需要选择满足二阶的梯度算子。如下。

       如果是基于缩放的后处理方法,那么scale = 12-1-1-1-1-1-1-1-1= 4。通常中心元素的设计需要保证最终的scale大于0。

       效果如果下所示。很明显,锐化之后在边缘效果的表示方面得到了增强。


1.3 USM

       UnsharpMask。注Photoshop中的USM锐化是一种特例的USM锐化方法。经典的实现方法如下图。y(n,m) = x(n,m) + λ z(n,m)。其中, x(n,m)为输入图像,y(n,m)为输出图像,而z(n,m)为校正信号,一般是通过对x进行高通滤波获取。λ是用于控制增强效果的的一个缩放因子。

       其中z(n,m)通常是x(n,m)经过模板卷积运算后的结果。这个模板要求只体现出差异(因为最终像素是它与原像素的累加和),如下所示,中心像素是4不是5。

0

-1

0

-1

5

-1

0

-1

0

       而λ则是一个比例值。如下代码片段所示。

void USMSharp(cv::Mat&src_img,cv::Mat&dst_img,double ratio) {

  cv::Matkernel = (cv::Mat_<int>(3, 3)<< 0, -1, 0, -1, 4, -1, 0, -1, 0);

  cv::filter2D(src_img,dst_img, -1,kernel);

  for (inti = 0;i < src_img.rows; ++i) {

    for (intj = 0;j < src_img.cols; ++j) {

      for (intk = 0;k < 3; ++k) {

        int value = src_img.at<cv::Vec3b>(i,j)[k] +ratio * dst_img.at<cv::Vec3b>(i,j)[k];

        dst_img.at<cv::Vec3b>(i,j)[k] =cv::saturate_cast<uchar>(value);

      }

    }

  }

}

效果图如下,从上至下从左至右λ分别为0,0.25,0.5,1。


但是这种方法也有一个很明显的缺点,即在图像边缘的地方很容易出现增强过头的现象。同时细细观察,也可以看到引入了噪声。(如右下角的帽子边缘处),因为线性滤波很容易对噪声敏感。

       因此又有人提出了另外一些改进的算法,如https://www.ncbi.nlm.nih.gov/pubmed/18255421。

1.3.1 Photoshop中的USM算法

       除半径之外又引入了数量、阈值两个参数,其内部算法可以简单。如下所示。

void ps_usm_sharp(cv::Mat&src_img,cv::Mat&dst_img,int radius, int thresh,doubleratio) {

  cv::GaussianBlur(src_img,dst_img,cv::Size(radius,radius), 0, 0);

  for (inti = 0;i < src_img.rows; ++i) {

    for (intj = 0;j < src_img.cols; ++j) {

      for (intk = 0;k < src_img.channels(); ++k) {

        int value = src_img.at<cv::Vec3b>(i,j)[k];

        int diff = src_img.at<cv::Vec3b>(i,j)[k] -dst_img.at<cv::Vec3b>(i,j)[k];

        diff = diff < 0 ? -diff : diff;

        if (diff >=thresh) {

          value =src_img.at<cv::Vec3b>(i,j)[k] +ratio * dst_img.at<cv::Vec3b>(i,j)[k];

        }

        dst_img.at<cv::Vec3b>(i,j)[k] =cv::saturate_cast<uchar>(value);

      }

    }

  }

}

       固定thresh为0,ratio为0.5;从上至下,从左至右,原图,以及radius分别设置为3,5,9的图。如下所示。


原创粉丝点击