图像处理中的一阶偏导数和二阶偏导数
http://blog.csdn.net/xiaofengsheng/article/details/6023368
http://www.cnblogs.com/german-iris/p/4840647.html
1. 一阶差分:
2. 二阶偏导数的推导和近似:
3. 上式以点(i+1,j)为中心,用i代换i+1可得以(i,j)为中心的二阶偏导数则有:
4. 同理:
5. 进而可推导:
6. 这样我们就可以很好的运用其他的一阶偏导的定义,如SIFT特征OpenCV实现版本中的一阶以及二阶偏导:
- /*
- Computes the partial derivatives in x, y, and scale of a pixel in the DoG
- scale space pyramid.
- @param dog_pyr DoG scale space pyramid
- @param octv pixel's octave in dog_pyr
- @param intvl pixel's interval in octv
- @param r pixel's image row
- @param c pixel's image col
- @return Returns the vector of partial derivatives for pixel I
- { dI/dx, dI/dy, dI/ds }^T as a CvMat*
- */
- static CvMat* deriv_3D( IplImage*** dog_pyr, int octv, int intvl, int r, int c )
- {
- CvMat* dI;
- double dx, dy, ds;
- dx = ( pixval32f( dog_pyr[octv][intvl], r, c+1 ) -
- pixval32f( dog_pyr[octv][intvl], r, c-1 ) ) / 2.0;
- dy = ( pixval32f( dog_pyr[octv][intvl], r+1, c ) -
- pixval32f( dog_pyr[octv][intvl], r-1, c ) ) / 2.0;
- ds = ( pixval32f( dog_pyr[octv][intvl+1], r, c ) -
- pixval32f( dog_pyr[octv][intvl-1], r, c ) ) / 2.0;
- dI = cvCreateMat( 3, 1, CV_64FC1 );
- cvmSet( dI, 0, 0, dx );
- cvmSet( dI, 1, 0, dy );
- cvmSet( dI, 2, 0, ds );
- return dI;
- }
- /*
- Computes the 3D Hessian matrix for a pixel in the DoG scale space pyramid.
- @param dog_pyr DoG scale space pyramid
- @param octv pixel's octave in dog_pyr
- @param intvl pixel's interval in octv
- @param r pixel's image row
- @param c pixel's image col
- @return Returns the Hessian matrix (below) for pixel I as a CvMat*
- / Ixx Ixy Ixs / <BR>
- | Ixy Iyy Iys | <BR>
- / Ixs Iys Iss /
- */
- static CvMat* hessian_3D( IplImage*** dog_pyr, int octv, int intvl, int r, int c )
- {
- CvMat* H;
- double v, dxx, dyy, dss, dxy, dxs, dys;
- v = pixval32f( dog_pyr[octv][intvl], r, c );
- dxx = ( pixval32f( dog_pyr[octv][intvl], r, c+1 ) +
- pixval32f( dog_pyr[octv][intvl], r, c-1 ) - 2 * v );
- dyy = ( pixval32f( dog_pyr[octv][intvl], r+1, c ) +
- pixval32f( dog_pyr[octv][intvl], r-1, c ) - 2 * v );
- dss = ( pixval32f( dog_pyr[octv][intvl+1], r, c ) +
- pixval32f( dog_pyr[octv][intvl-1], r, c ) - 2 * v );
- dxy = ( pixval32f( dog_pyr[octv][intvl], r+1, c+1 ) -
- pixval32f( dog_pyr[octv][intvl], r+1, c-1 ) -
- pixval32f( dog_pyr[octv][intvl], r-1, c+1 ) +
- pixval32f( dog_pyr[octv][intvl], r-1, c-1 ) ) / 4.0;
- dxs = ( pixval32f( dog_pyr[octv][intvl+1], r, c+1 ) -
- pixval32f( dog_pyr[octv][intvl+1], r, c-1 ) -
- pixval32f( dog_pyr[octv][intvl-1], r, c+1 ) +
- pixval32f( dog_pyr[octv][intvl-1], r, c-1 ) ) / 4.0;
- dys = ( pixval32f( dog_pyr[octv][intvl+1], r+1, c ) -
- pixval32f( dog_pyr[octv][intvl+1], r-1, c ) -
- pixval32f( dog_pyr[octv][intvl-1], r+1, c ) +
- pixval32f( dog_pyr[octv][intvl-1], r-1, c ) ) / 4.0;
- H = cvCreateMat( 3, 3, CV_64FC1 );
- cvmSet( H, 0, 0, dxx );
- cvmSet( H, 0, 1, dxy );
- cvmSet( H, 0, 2, dxs );
- cvmSet( H, 1, 0, dxy );
- cvmSet( H, 1, 1, dyy );
- cvmSet( H, 1, 2, dys );
- cvmSet( H, 2, 0, dxs );
- cvmSet( H, 2, 1, dys );
- cvmSet( H, 2, 2, dss );
- return H;
- }
参考:
(1)http://hi.baidu.com/shareshow/blog/item/34abdf544725cf54d109069b.html
(2)SIFT的OpenCV实现
OpenCV-跟我一起学数字图像处理之拉普拉斯算子
Laplace算子和Sobel算子一样,属于空间锐化滤波操作。起本质与前面的Spatial Filter操作大同小异,下面就通过Laplace算子来介绍一下空间锐化滤波,并对OpenCV中提供的Laplacian函数进行一些说明。
- 数学原理
离散函数导数
离散函数的导数退化成了差分,一维一阶差分公式和二阶差分公式分别为,
Laplace算子的差分形式
分别对Laplace算子x,y两个方向的二阶导数进行差分就得到了离散函数的Laplace算子。
在一个二维函数f(x,y)中,x,y两个方向的二阶差分分别为,
所以Laplace算子的差分形式为,
写成filter mask的形式如下,
0 | 1 | 0 |
1 | -4 | 1 |
0 | 1 | 0 |
1 | 1 | 1 |
1 | -8 | 1 |
1 | 1 | 1 |
注:
有时我们也会见到不同于上述结果的Laplace算子的filter mask,
0 | -1 | 0 |
-1 | 4 | -1 |
0 | -1 | 0 |
-1 | -1 | -1 |
-1 | 8 | -1 |
-1 | -1 | -1 |
其原因是在定义二阶导数的时候采用了相反的定义,这个无关紧要,但是要注意,当用Laplace算子滤波后的图像与原图叠加时,混合操作是加还是减因上述的定义而异。
图像的Laplace操作
如同本文开始时说的那样,将Laplace算子写成filter mask后,其操作大同小异于其他的空间滤波操作。将filter mask在原图上逐行移动,然后mask中数值与其重合的像素相乘后求和,赋给与mask中心重合的像素,对图像的第一,和最后的行和列无法做上述操作的像素赋值零,就得到了拉普拉斯操作结果。
拉普拉斯操作结果与原图的混合
因为Laplace算子是二阶导数操作,其在强调图像素中灰度不连续的部分的同时也不在强调灰度值连续的部分。这样会产生一个具有很明显的灰度边界,但是没有足够特征的黑色背景。背景特征可以通过原图像与Laplace算子操作后的图像混合恢复。用公式,
其中的参数c的取值和上面的两种mask定义有关,当mask中心的数值取正时c=-1,相反c=1;
- 基于OpenCV的Laplace算子的计算
OpenCV中Laplacian函数可以实现对图像的Laplace操作,具体用法如下,
Laplacian( src_gray, dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT );
参数意义为,
- src_gray,输入图像
- dst,Laplace操作结果
- ddepth,输出图像深度,因为输入图像一般为CV_8U,为了避免数据溢出,输出图像深度应该设置为CV_16S
- kernel_size,filter mask的规模,我们的mask时3x3的,所以这里应该设置为3
- scale,delta,BORDER_DEFAULT,默认设置就好
基于OpenCV的Laplace算子仿真代码段如下,
//load the Original Image and get some informations Mat src = imread("012.jpg",0); namedWindow("OriginalImage"); imshow("OriginalImage",src); CV_Assert(src.depth() == CV_8U);//OpenCV solution - Laplacian Mat dst,abs_dst_laplace; Laplacian(src,dst,CV_16S,3); convertScaleAbs(dst,abs_dst_laplace);//show the result namedWindow("result_laplacian"); imshow("result_laplacian",abs_dst_laplace);
其中convertScaleAbs函数功能是将CV_16S型的输出图像转变成CV_8U型的图像。
仿真结果:
原图:
Laplace操作结果:
- 基于mask operation原理仿真
Laplace算子滤波仿真
根据数学原理中介绍的算法,编写相应代码,进行相关仿真。其中对Laplace操作结果进行了图像拉伸显示,因为Laplace操作结果的像素值范围可能落在了[0,255]之外,而计算机在显示的时候将赋值全部置为0,大于255的像素全部显示成255。
代码段如下,
//get some informations of original image int nr = src.rows; int nc = src.cols; int n = nr*nc; int arr[9] = {0};//scan the whole pixels of original image //and do Laplacian Operation int* table_lap = new int[n]; int* table_orig = new int[n]; int l; for (int i=0;i<n;i++) {table_lap[i] = 0;table_orig[i] = 0; } for (int i=1;i<nr-1;i++) {const uchar* previous = src.ptr<uchar>(i-1);const uchar* current = src.ptr<uchar>(i);const uchar* next = src.ptr<uchar>(i+1);for (int j=1;j<nc-1;j++){for (int k=0;k<3;k++){arr[k] = previous[j+k-1];arr[k+3] = current[j+k-1];arr[k+6] = next[j+k-1];}l = nc*i+j; //calculate the location in the table of current pixel Lmaskoperation(table_lap,arr,l);table_orig[l] = arr[4];} }//pixels scale uchar* La_scaled = new uchar[n]; table_scale(table_lap,La_scaled,n);//padding values Mat LaResult_own; LaResult_own.create(src.size(),src.type()); uchar* p = NULL; for (int i=0;i<nr;i++) {p = LaResult_own.ptr<uchar>(i);for (int j=0;j<nc;j++){l = nc*i+j;p[j] = La_scaled[l];} }//show results namedWindow("LaResult_own"); imshow("LaResult_own",LaResult_own);
其中Lmaskoperation是我写的mask为Laplace mask的mask operation操作函数,函数段如下,
//**********************// //Laplacian mask operation //**********************// void Lmaskoperation(int* table,int* arr,int l) {int tmp[9] = {-1,-1,-1,-1,8,-1,-1,-1,-1};for (int i=0;i<9;i++){table[l] = table[l] + tmp[i]*arr[i];} }
tabel_scale函数就是我写的图像拉伸函数,将Laplace操作结果拉伸到[0,255],具体函数段如下,
//*****************************// //scale the pixels to [0 255] //*****************************// void table_scale(int* table,uchar* result,int n) {int min = table[0];int max = table[0];for (int i=0;i<n;i++){if(min>table[i]){min = table[i];}if(max<table[i]){max = table[i];}}for (int i=0;i<n;i++){result[i] = (uchar)(255*(table[i]-min)/(max-min));} }
仿真结果,拉伸后Laplace算子的操作结果
以灰色为主色调的显示结果就是Laplace算子操作拉伸后显示的一大特点。
Laplace滤波图像与原图像的混合
我使用的mask中心值为正,所以混合操作需要原图减去Laplace滤波图像,代码段如下,
//blending with the original image using Eq g(x,y)=f(x,y)+c*Lap(x,y) int* table_blend = new int[n]; for(int i=0;i<n;i++) {table_blend[i] = table_orig[i] - table_lap[i];if(table_blend[i]<0){table_blend[i] = 0;}else if (table_blend[i]>255){table_blend[i] = 255;} }//padding values to blending result Mat Blresult; Blresult.create(src.size(),src.type()); for (int i=0;i<nr;i++) {p = Blresult.ptr<uchar>(i);for(int j=0;j<nc;j++){l = nc*i+j;p[j] = table_blend[l];} }//show blending result namedWindow("blending result_laplacian"); imshow("blending result_laplacian",Blresult);
仿真结果:
最后给出冈萨雷斯在介绍Laplacian时所给素材的仿真结果
图像处理中的一阶偏导数和二阶偏导数相关推荐
- 图像运算中的一阶导与二阶导
首先,图像是离散的数据,若求其导数就要用差分的方法,常用的差分方法是前向差分(forward differencing)与中心差分(central differencing).一阶导本质上求的是斜率, ...
- Opencv--图像处理之一阶和二阶偏导数
1. 一阶差分: 2. 二阶偏导数的推导和近似: 3. 上式以点(i+1,j)为中心,用i代换i+1可得以(i,j)为中心的二阶偏导数则有: 4. 同理: 5. 进而可推导: 6. 这样我们就可以很好 ...
- 数字图像处理:(2)一阶微分和二阶微分在数字图像处理中的应用
1.微分定义 2.微分性质 微分是对函数局部变化率的一种表示. 在图像处理中有基于一阶微分和二阶微分的锐化空间滤波器(图像锐化是增强图像的突变部分),其实一阶微分和二阶微分算子都可以得到图像的边缘,只 ...
- 图像处理之高斯一阶及二阶导数计算
图像处理之高斯一阶及二阶导数计算 图像的一阶与二阶导数计算在图像特征提取与边缘提取中十分重要.一阶与二阶导数的 作用,通常情况下: 一阶导数可以反应出图像灰度梯度的变化情况 二阶导数可以提取出图像的细 ...
- CV笔记6:图像边缘检测之一阶微分算子、二阶微分算子、Canny边缘检测(基于python-opencv实现)
目录 一.边缘简介 1.1 何为边缘 1.2 产生原因 二.边缘检测方法 2.1 一阶微分算子计算原理 2.2 噪声对一阶微分算子的影响及解决方案 2.3 常见的一阶微分算子 2.3.1 Robert ...
- 图像处理中的梯度、导数如何求?(Robert算子,Sobel算子,Prewitt算子,Laplace算子)
梯度的求法是多种多样的,根据不同的处理需要选择合适的算子(模版). 1.水平垂直差分法 2.Robert 梯度算子 3.Sobel算子 垂直方向 ...
- 一阶动量和二阶动量及Adam等优化算法笔记
就按照 从动量和矩的角度探讨优化理论的内涵(以动量法.AdaGrad和Adam举例) - 知乎 的讲解学习,讲的挺细的.这里补充一些笔记方便以后自己复习用. 1.AdaGrad算法 其中说到了&quo ...
- 图像处理中各种边缘检测的微分算子简单比较(Sobel,Robert, Prewitt,Laplacian,Canny)
图像处理中各种边缘检测的微分算子简单比较(Sobel,Robert, Prewitt,Laplacian,Canny) 不同图像灰度不同,边界处一般会有明显边缘,利用此特征可以分割图像.需要说明的是: ...
- 数字图像的一阶微分和二阶微分
数字图像的微分也就是数字函数的微分有很多不用的定义,但是任何定义都必须保证一下几点: 一阶微分:(1)在恒定灰度区域的微分值为零: (2)在灰度台阶或斜坡处微分值非零: (3)沿着斜坡的微分值非零: ...
- 图像处理中几个基本的处理方法c#代码实现
图像是人类获取和交换信息的主要来源,因此,图像处理的应用领域必然涉及到人类生活和工作的方方面面.随着人类活动范围的不断扩大,图像处理的应用领域也将随之不断扩大.(1)航天和航空技术方面的应用 数字图像 ...
最新文章
- 阿里DataV可视化大屏基本操作
- github上传本地代码
- JS 字符串编码函数(解决URL特殊字符传递问题):escape()、encodeURI()、encodeURIComponent()区别详解...
- 【2016年第1期】基于大数据的玉米田四代棉铃虫发生量的预测模型
- 九、装配bean--通过properties文件注入值
- uban服务器系统,Web服务器-并发服务器-Epoll(3.4.5)
- 【渝粤教育】国家开放大学2018年春季 0176-21T电机学(一) 参考试题
- 嵌入式学习二:怎么学习Linux操作系统
- 计算机病毒的危害与防范
- 开发多语言常用国家地区对照表(最全的各国地区对照表) 多语言简称
- 【SVM分类】基于遗传算法优化支持向量机实现葡萄酒分类附matlab代码
- android 6 root权限,安卓一键root(权限获取)
- Beaglebone Black 和树莓派
- 捆绑影视IP,玩跨界营销,你真学不会!
- iOS 9的App Thinning方案如何节省存储空间
- java试题汽车接口_Java接口和包的实现之小汽车实例
- 关于java的毕业设计_我的java毕业设计之路回顾
- 雷军曾说芯片将如沙子那么便宜,然而沙子涨价促使芯片进一步涨价
- 未转变者推荐服务器pve,Unturned服务器大全 pvp pve随你挑
- F12控制视频倍速播放