常用Photoshop的玩家都知道Unsharp Mask(USM)锐化,它是一种增强图像边缘的锐化算法,原理在,如果你想使用这个算法,强烈推荐看一下。本文进行一下简单的介绍,USM锐化一共分为三步,第一步生成原始图片src的模糊图片和高对比度图片,记为blur和contrast.第二,把src和blur作差,得到一张差分图片,记为diff,它就是下图的UnsharpMask。然后把src和contras按一定的比例相加,这个比例由diff控制,最终得到锐化图片。USM有一个缺点,锐化后最大和最小的像素值会超过原始图片,如下图红色虚线和白色实线所示。
代码如下:
void MyTreasureBox::UnsharpMask(const IplImage* src, IplImage* dst, float amount, float radius, uchar threshold, int contrast){ if(!src)return ; int imagewidth = src->width; int imageheight = src->height; int channel = src->nChannels; IplImage* blurimage = cvCreateImage(cvSize(imagewidth,imageheight), src->depth, channel); IplImage* DiffImage = cvCreateImage(cvSize(imagewidth,imageheight), 8, channel); //原图的高对比度图像 IplImage* highcontrast = cvCreateImage(cvSize(imagewidth,imageheight), 8, channel); AdjustContrast(src, highcontrast, contrast); //原图的模糊图像 cvSmooth(src, blurimage, CV_GAUSSIAN, radius); //原图与模糊图作差 for (int y=0; ythreshold) { //最终图像 = 原始*(1-r) + 高对比*r val.val[k] = ori.val[k] *(100-amount) + hc.val[k] *amount; val.val[k] /= 100; } else { val.val[k] = ori.val[k]; } } cvSet2D(dst, y, x, val); } } cvReleaseImage(&blurimage); cvReleaseImage(&DiffImage);}
其中用到一个调整图像对比度的函数
void MyTreasureBox::AdjustContrast(const IplImage* src, IplImage* dst, int contrast){ if (!src)return ; int imagewidth = src->width; int imageheight = src->height; int channel = src->nChannels; //求原图均值 CvScalar mean = { 0,0,0,0}; for (int y=0; y-255 && contrast <= 0) { //(1)nRGB = RGB + (RGB - Threshold) * Contrast / 255 // 当增量大于-255且小于0时,直接用上面的公式计算图像像素各分量 //公式中,nRGB表示调整后的R、G、B分量,RGB表示原图R、G、B分量,Threshold为给定的阀值,Contrast为处理过的对比度增量。 for (int y=0; y 0 && contrast <255) { //当增量大于0且小于255时,则先按下面公式(2)处理增量,然后再按上面公式(1)计算对比度: //(2)、nContrast = 255 * 255 / (255 - Contrast) - 255 //公式中的nContrast为处理后的对比度增量,Contrast为给定的对比度增量。 CvScalar nRGB; int nContrast = 255 *255 /(255 - contrast) - 255; for (int y=0; y mean.val[k]) { rgb.val[k] = 255; } else { rgb.val[k] = 0; } } cvSet2D(dst, y, x, rgb); } } }}