分数阶微分,Grumwald-Letnikov定义在图像的数值实现中更为准确:
Gamma函数:
若s(t)的持续期t [a,t],将函数持续期间[a,t]按单位间隔h=1进行等分,得到:
推到一元函数是s(t)的 v 阶分数阶微分差分表达式为:
这n个非零系数只有常数“1”,其他都是n-1个都是分数阶微分阶次的函数。n个系数分别为:
微分近似掩模算子
分数阶微分( 0.1阶 ~ 0.9阶), 则可以检测到或部分检测到那些模糊边界和细微的弱边界, 而且还可以减少图像噪声的增加。
下左图:原图,下右图:0.5阶分数阶微分处理结果(v=0.5)
void CShowPicView::OnFractionalCalculus( ) // 分数阶微积分 灰度图 单通道 { CShowPicDoc* pDoc = GetDocument(); CDC* pDC=GetDC(); CString str; int i,j; double temp ; int **g; g = new int *[intHeight]; for(i=0; i<intHeight ;i++) g[i]=new int [intWidth]; for(j = 0; j < intWidth; j++) for(i = 0; i <intHeight ; i++) g[i][j]=0; double a0 , a1 , a2 ,v= 0.8 ; a0=1; a1=-v; a2=(-v)*(-v+1)/2; double temp_1=(8+4*v*v-12*v); for(j = 2; j < intWidth-2; j++) for(i = 2; i <intHeight-2 ; i++) { temp = a2*(Data[i-2][j-2]+Data[i-2][j]+Data[i-2][j+2] +Data[i][j-2] +Data[i][j+2] +Data[i+2][j-2]+Data[i+2][j]+Data[i+2][j+2]); temp+= a1*(Data[i-1][j-1]+Data[i-1][j]+Data[i-1][j+1] +Data[i][j-1] +Data[i][j+1] +Data[i+1][j-1]+Data[i+1][j]+Data[i+1][j+1]); temp+= 8*a0*Data[i][j]; temp = temp/ temp_1; if(temp<0) temp=0; g[i][j] = (int)temp; pDC->SetPixel(j+intWidth,i,RGB(g[i][j],g[i][j],g[i][j])); } for(j = 0; j < intWidth; j++) for(i = 0; i <intHeight ; i++) Data[i][j]=g[i][j]; for(i=0; i<intHeight ;i++) delete [] g[i]; delete []g; ReleaseDC(pDC); } void CShowPicView::OnFractionalCalculusRGB() // 分数阶微积分RGB { CShowPicDoc* pDoc = GetDocument(); CDC* pDC=GetDC(); CString str; int i,j; double temp_R , temp_G , temp_B ; int **g; g = new int *[intHeight]; for(i=0; i<intHeight ;i++) g[i]=new int [intWidth]; double **m_imgData_R, **m_imgData_G, **m_imgData_B ; double **I_enhanced_R , **I_enhanced_G , **I_enhanced_B ; m_imgData_R=new double *[intHeight]; m_imgData_G=new double *[intHeight]; m_imgData_B=new double *[intHeight]; I_enhanced_R=new double *[intHeight]; I_enhanced_G=new double *[intHeight]; I_enhanced_B=new double *[intHeight]; for(i=0; i<intHeight; i++) { m_imgData_R[i] = new double [intWidth]; m_imgData_G[i] = new double [intWidth]; m_imgData_B[i] = new double [intWidth]; I_enhanced_R[i] = new double [intWidth]; I_enhanced_G[i] = new double [intWidth]; I_enhanced_B[i] = new double [intWidth]; } for(j = 0; j < intWidth; j++) for(i = 0; i < intHeight ; i++) { m_imgData_R[i][j]=pDoc->pic[i][j][0]; m_imgData_G[i][j]=pDoc->pic[i][j][1]; m_imgData_B[i][j]=pDoc->pic[i][j][2]; I_enhanced_R[i][j]=pDoc->pic[i][j][0]; I_enhanced_G[i][j]=pDoc->pic[i][j][1]; I_enhanced_B[i][j]=pDoc->pic[i][j][2]; g[i][j]=0; } double a0 , a1 , a2 , v= 0.3; a0=1; a1=-v; a2=(-v)*(-v+1)/2; double temp_1=(8+4*v*v-12*v); for(j = 2; j < intWidth-2; j++) for(i = 2; i <intHeight-2 ; i++) { temp_R = a2*(pDoc->pic[i-2][j-2][0]+pDoc->pic[i-2][j][0]+pDoc->pic[i-2][j+2][0] +pDoc->pic[i][j-2][0] +pDoc->pic[i][j+2][0] +pDoc->pic[i+2][j-2][0]+pDoc->pic[i+2][j][0]+pDoc->pic[i+2][j+2][0]); temp_G = a2*(pDoc->pic[i-2][j-2][1]+pDoc->pic[i-2][j][1]+pDoc->pic[i-2][j+2][1] +pDoc->pic[i][j-2][1] +pDoc->pic[i][j+2][1] +pDoc->pic[i+2][j-2][1]+pDoc->pic[i+2][j][1]+pDoc->pic[i+2][j+2][1]); temp_B = a2*(pDoc->pic[i-2][j-2][2]+pDoc->pic[i-2][j][2]+pDoc->pic[i-2][j+2][2] +pDoc->pic[i][j-2][2] +pDoc->pic[i][j+2][2] +pDoc->pic[i+2][j-2][2]+pDoc->pic[i+2][j][2]+pDoc->pic[i+2][j+2][2]); temp_R += a1*(pDoc->pic[i-1][j-1][0]+pDoc->pic[i-1][j][0]+pDoc->pic[i-1][j+1][0] +pDoc->pic[i][j-1][0] +pDoc->pic[i][j+1][0] +pDoc->pic[i+1][j-1][0]+pDoc->pic[i+1][j][0]+pDoc->pic[i+1][j+1][0]); temp_G += a1*(pDoc->pic[i-1][j-1][1]+pDoc->pic[i-1][j][1]+pDoc->pic[i-1][j+1][1] +pDoc->pic[i][j-1][1] +pDoc->pic[i][j+1][1] +pDoc->pic[i+1][j-1][1]+pDoc->pic[i+1][j][1]+pDoc->pic[i+1][j+1][1]); temp_B += a1*(pDoc->pic[i-1][j-1][2]+pDoc->pic[i-1][j][2]+pDoc->pic[i-1][j+1][2] +pDoc->pic[i][j-1][2] +pDoc->pic[i][j+1][2] +pDoc->pic[i+1][j-1][2]+pDoc->pic[i+1][j][2]+pDoc->pic[i+1][j+1][2]); temp_R += 8*a0*pDoc->pic[i][j][0]; temp_R = temp_R/ temp_1; if(temp_R<0) temp_R=0; else if(temp_R>255) temp_R=255; temp_G += 8*a0*pDoc->pic[i][j][1]; temp_G = temp_G/ temp_1; if(temp_G<0) temp_G=0; else if(temp_G>255) temp_G=255; temp_B += 8*a0*pDoc->pic[i][j][2]; temp_B = temp_B/ temp_1; if(temp_B<0) temp_B=0; else if(temp_B>255) temp_B=255; I_enhanced_R[i][j]=(int)temp_R; I_enhanced_G[i][j]=(int)temp_G; I_enhanced_B[i][j]=(int)temp_B; pDC->SetPixel(j+intWidth,i,RGB(I_enhanced_R[i][j],I_enhanced_G[i][j],I_enhanced_B[i][j])); } for(j = 0; j < intWidth; j++) for(i = 0; i <intHeight ; i++) { pDoc->pic[i][j][0]=I_enhanced_R[i][j]; pDoc->pic[i][j][1]=I_enhanced_G[i][j]; pDoc->pic[i][j][2]=I_enhanced_B[i][j]; } for(i=0; i<intHeight ;i++) delete [] g[i]; for(i=0; i<intHeight; i++) { delete [] m_imgData_R[i]; delete [] m_imgData_G[i]; delete [] m_imgData_B[i]; delete [] I_enhanced_R[i]; delete [] I_enhanced_G[i]; delete [] I_enhanced_B[i]; } delete m_imgData_R; delete m_imgData_G; delete m_imgData_B; delete I_enhanced_R ; delete I_enhanced_G ; delete I_enhanced_B ; ReleaseDC(pDC); delete []g; ReleaseDC(pDC); }
原图,0.5阶增强效果
最近有网友问我:直接把程序copy到vc里面,为什么运行不了?
答:那是当然运行不了,只是提供了分数阶微分的部分代码,并没有上传全部代码,需要把代码相应的接口修改并放到自己的代码里面才能运行。所以索性把所有的代码都打包上传,想要的自己下载吧。
链接: https://pan.baidu.com/s/16y6g_HWQk6oin3k8MLilzg 提取码: a2ah