版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第OpenCV实现图像去噪算法的步骤详解目录一、函数参考1、Primal-dual算法2、非局部均值去噪算法三、OpenCV源码1、源码路径2、源码代码四、效果图像示例
一、函数参考
1、Primal-dual算法
Primal-dualalgorithm是一种用于解决特殊类型的变分问题的算法(即找到一个函数来最小化一些泛函)。
特别是由于图像去噪可以看作是变分问题,因此可以使用原始对偶算法进行去噪,这正是该算法所实现的。
cv::denoise_TVL1(conststd::vectorMatobservations,Matresult,doublelambda=1.0,intniters=30)
observations该数组应包含要恢复的图像的一个或多个噪声版本。result这里将存储去噪图像。无需预先分配存储空间,必要时会自动分配。lambda对应于上述公式中的。当它被放大时,平滑(模糊)的图像比细节(但可能有更多噪点)的图像更受欢迎。粗略地说,随着它变小,结果会更加模糊,但会去除更多的异常值。niters算法将运行的迭代次数。当然,越多的迭代越好,但是这个说法很难量化细化,所以就使用默认值,如果结果不好就增加它。
2、非局部均值去噪算法
使用非局部均值去噪算法,该方法基于一个简单的原理:将像素的颜色替换为相似像素颜色的平均值。但是与给定像素最相似的像素根本没有理由靠近。因此,扫描图像的大部分以寻找真正类似于想要去噪的像素的所有像素是合法的。执行图像去噪,并进行了多种计算优化。噪声预期为高斯白噪声。
cv::cuda::fastNlMeansDenoising(InputArraysrc,OutputArraydst,floath,intsearch_window=21,intblock_size=7,Streamstream=Stream::Null())
cv::fastNlMeansDenoising(InputArraysrc,OutputArraydst,floath=3,inttemplateWindowSize=7,intsearchWindowSize=21)
cv::fastNlMeansDenoising(InputArraysrc,OutputArraydst,conststd::vectorfloath,inttemplateWindowSize=7,intsearchWindowSize=21,int
针对彩色图像的fastNlMeansDenoising函数。
cv::cuda::fastNlMeansDenoisingColored(InputArraysrc,OutputArraydst,floath_luminance,floatphoto_render,intsearch_window=21,intblock_size=7,Streamstream=Stream::Null())
cv::fastNlMeansDenoisingColored(InputArraysrc,OutputArraydst,floath=3,floathColor=3,inttemplateWindowSize=7,intsearchWindowSize=21)
针对图像序列的fastNlMeansDenoising函数。
cv::fastNlMeansDenoisingColoredMulti(InputArrayOfArrayssrcImgs,OutputArraydst,intimgToDenoiseIndex,inttemporalWindowSize,floath=3,floathColor=3,inttemplateWindowSize=7,intsearchWindowSize=21)
cv::fastNlMeansDenoisingMulti(InputArrayOfArrayssrcImgs,OutputArraydst,intimgToDenoiseIndex,inttemporalWindowSize,floath=3,inttemplateWindowSize=7,intsearchWindowSize=21)
cv::fastNlMeansDenoisingMulti(InputArrayOfArrayssrcImgs,OutputArraydst,intimgToDenoiseIndex,inttemporalWindowSize,conststd::vectorfloath,inttemplateWindowSize=7,intsearchWindowSize=21,intnormType=NORM_L2)
执行纯非局部方法去噪,没有任何简化,因此速度不快。
cv::cuda::nonLocalMeans(InputArraysrc,OutputArraydst,floath,intsearch_window=21,intblock_size=7,intborderMode=BORDER_DEFAULT,Streamstream=Stream::Null())
三、OpenCV源码
1、源码路径
opencv\modules\photo\src\denoise_tvl1.cpp
2、源码代码
#include"precomp.hpp"
#includevector
#includealgorithm
#defineABSCLIP(val,threshold)MIN(MAX((val),-(threshold)),(threshold))
namespacecv{
classAddFloatToCharScaled{
public:
AddFloatToCharScaled(doublescale):_scale(scale){}
inlinedoubleoperator()(doublea,ucharb){
returna+_scale*((double)b);
private:
double_scale;
usingstd::transform;
voiddenoise_TVL1(conststd::vectorMatobservations,Matresult,doublelambda,intniters){
CV_Assert(observations.size()0niters0lambda
constdoubleL2=8.0,tau=0.02,sigma=1./(L2*tau),theta=1.0;
doubleclambda=(double)lambda;
doubles=0;
constintworkdepth=CV_64F;
inti,x,y,rows=observations[0].rows,cols=observations[0].cols,count;
for(i=1;i(int)observations.size();i++){
CV_Assert(observations[i].rows==rowsobservations[i].cols==cols);
MatX,P=Mat::zeros(rows,cols,CV_MAKETYPE(workdepth,2));
observations[0].convertTo(X,workdepth,1./255);
std::vectorMat_doubleRs(observations.size());
for(count=0;count(int)Rs.size();count++){
Rs[count]=Mat::zeros(rows,cols,workdepth);
for(i=0;initers;i++)
doublecurrsigma=i==01+sigma:sigma;
//P_=P+sigma*nabla(X)
//P(x,y)=P_(x,y)/max(||P(x,y)||,1)
for(y=0;yrows;y++)
constdouble*x_curr=X.ptrdouble
constdouble*x_next=X.ptrdouble(std::min(y+1,rows-1));
Point2d*p_curr=P.ptrPoint2d
doubledx,dy,m;
for(x=0;xcols-1;x++)
dx=(x_curr[x+1]-x_curr[x])*currsigma+p_curr[x].x;
dy=(x_next[x]-x_curr[x])*currsigma+p_curr[x].y;
m=1.0/std::max(std::sqrt(dx*dx+dy*dy),1.0);
p_curr[x].x=dx*m;
p_curr[x].y=dy*m;
dy=(x_next[x]-x_curr[x])*currsigma+p_curr[x].y;
m=1.0/std::max(std::abs(dy),1.0);
p_curr[x].x=0.0;
p_curr[x].y=dy*m;
//Rs=clip(Rs+sigma*(X-imgs),-clambda,clambda)
for(count=0;count(int)Rs.size();count++){
transformMatIterator_double,MatConstIterator_uchar,MatIterator_double,AddFloatToCharScaled(
Rs[count].begin(),Rs[count].end(),observations[count].beginuchar(),
Rs[count].begin(),AddFloatToCharScaled(-sigma/255.0));
Rs[count]+=sigma*X;
min(Rs[count],clambda,Rs[count]);
max(Rs[count],-clambda,Rs[count]);
for(y=0;yrows;y++)
double*x_curr=X.ptrdouble
constPoint2d*p_curr=P.ptrPoint2d
constPoint2d*p_prev=P.ptrPoint2d(std::max(y-1,0));
//X1=X+tau*(-nablaT(P))
x=0;
s=0.0;
for(count=0;count(int)Rs.size();count++){
s=s+Rs[count](y,x);
doublex_new=x_curr[x]+tau*(p_curr[x].y-p_prev[x].y)-tau*s;
//X=X2+theta*(X2-X)
x_curr[x]=x_new+theta*(x_new-x_curr[x]);
for(x=1;xcols;x++)
s=0.0;
for(count=0;count(int)Rs.size();count++){
s+=Rs[count](y,x);
//X1=X+tau*(-nablaT(P))
x_new=x_curr[x]+tau*(p_curr[x].x-p_c
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论