您的位置:首页 > 运维架构

OpenCV实现USM锐化与测试

2015-10-21 14:55 423 查看

OpenCV实现USM锐化

【转】http://www.programdevelop.com/4964391/

USM (Unsharp masking) is a common operation of image processing. From the Internet search a bit, there are basically three different ways. Only 2 lines of code, there are hundreds of the most complex line. These three methods below summary records for later use.

最简单的方法:

cv::GaussianBlur(frame, image, cv::Size(0, 0), 3);
cv::addWeighted(frame, 1.5, image, -0.5, 0, image);


Followed by the simple method, derived from "only want to hear a good story" programdevelop.com blog.

常用photoshop的一般都会用到usm (unsharp mask)锐化,它的原理非常简单,使用opencv进行实现只需要4行代码

最终实现效果如下:

double sigma = 3;
int threshold = 0;
float amount = 1;
imgsrc = imread("thankyou.jpg");
GaussianBlur(imgsrc, imgblurred, cv::size(0,0), sigma, sigma)  #对于图形size(0,0)效果最好。why?看高斯滤波原理
#GaussianBlur(imgsrc, imgblurred, cv::size(5,5), sigma, sigma)
#GaussianBlur(imgsrc, imgblurred, size(), sigma, sigma)
lowcontrastmask = abs(imgsrc-imgblurred)<threshold;
imgdst = imgsrc*(1+amount)+imgblurred*(-amount);
imgsrc.copyTo(imgdst, lowcontrastmask);
imshow("SUM", imgdst);


===================================================

void UnsharpMask(const IplImage* src, IplImage* dst, float amount=80, float radius=5, uchar threshold=0, intcontrast=100)
{
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; y<imageheight; y++)
{
for (int x=0; x<imagewidth; x++)
{
CvScalar ori = cvGet2D(src, y, x);
CvScalar blur = cvGet2D(blurimage, y, x);
CvScalar val;
val.val[0] = abs(ori.val[0] - blur.val[0]);
val.val[1] = abs(ori.val[1] - blur.val[1]);
val.val[2] = abs(ori.val[2] - blur.val[2]);

cvSet2D(DiffImage, y, x, val);
}
}

//
for (int y=0; y<imageheight; y++)
{
for (int x=0; x<imagewidth; x++)
{
CvScalar hc = cvGet2D(highcontrast, y, x);
CvScalar diff = cvGet2D(DiffImage, y, x);
CvScalar ori = cvGet2D(src, y, x);
CvScalar val;

for (int k=0; k<channel; k++)
{
if (diff.val[k] > threshold)
{
// = *(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);
}
//?contrast[-255,255]
void 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<imageheight; y++)
{
for (int x=0; x<imagewidth; x++)
{
for (int k=0; k<channel; k++)
{
CvScalar ori = cvGet2D(src, y, x);
for (int k=0; k<channel; k++)
{
mean.val[k] += ori.val[k];
}
}
}
}
for (int k=0; k<channel; k++)
{
mean.val[k] /= imagewidth * imageheight;
}

//
if (contrast <= -255)
{
//-255???RGB??1??
for (int y=0; y<imageheight; y++)
{
for (int x=0; x<imagewidth; x++)
{
cvSet2D(dst, y, x, mean);
}
}
}
else if(contrast > -255 &&  contrast <= 0)
{
//(1)nRGB = RGB + (RGB - Threshold) * Contrast / 255
// -2550?
//?nRGBR?G?B?RGBR?G?B?Threshold?Contrast?
for (int y=0; y<imageheight; y++)
{
for (int x=0; x<imagewidth; x++)
{
CvScalar nRGB;
CvScalar ori = cvGet2D(src, y, x);
for (int k=0; k<channel; k++)
{
nRGB.val[k] = ori.val[k] + (ori.val[k] - mean.val[k]) *contrast /255;
}
cvSet2D(dst, y, x, nRGB);
}
}
}
else if(contrast >0 && contrast <255)
{
//0255?(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<imageheight; y++)
{
for (int x=0; x<imagewidth; x++)
{
CvScalar ori = cvGet2D(src, y, x);
for (int k=0; k<channel; k++)
{
nRGB.val[k] = ori.val[k] + (ori.val[k] - mean.val[k]) *nContrast /255;
}
cvSet2D(dst, y, x, nRGB);
}
}
}
else
{
// 255????8?
//??????
for (int y=0; y<imageheight; y++)
{
for (int x=0; x<imagewidth; x++)
{
CvScalar rgb;
CvScalar ori = cvGet2D(src, y, x);
for (int k=0; k<channel; k++)
{
if (ori.val[k] > mean.val[k])
{
rgb.val[k] = 255;
}
else
{
rgb.val[k] = 0;
}
}
cvSet2D(dst, y, x, rgb);
}
}
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: