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
相关文章推荐
- 从uboot传参数给linux驱动
- Linux vi命令
- 6.gitbash同步vs工程
- hadoop2.x集群的安装
- 使用安装在linux端的loadgenerator,在controller加载并发人数受限的问题解决
- linux c fopen修改已经存在的文件
- 使用corosync+pacemaker构建高可用集群
- centos6.5安装php5.6版本
- Eclipse部署不成功的问题(部署到tomcat中,只有个空文件夹)
- 在linux中数据库备份遇到的问题
- IIS绑定Active Directory账号自动登录网站的方法
- php获取网站根目录
- Linux下如何使用grep命令查找带有tab(退格)的字符
- OpenCV滤波之copyMakeBorder和borderInterpolate
- nginx + tomcat 部署反向代理加负载均衡
- 旧文备份: CANopen的LSS子协议中文翻译
- (转)Linux环境进程间通信系列(五):共享内存
- linux下 eclipse装svn报failed to load javahl library的解决办法
- Linux下如何批量建立文件连接
- 数据导数据工具xtrabackup之xtrabackup_binlog_pos_innodb和xtrabackup_binlog_info区别