非线性变换_透视变换是线性变换还是非线性变换 - CSDN
  • MATLAB的非线性变换

    2019-01-24 10:37:34
    下面来简单介绍一下基于MATLAB的非线性变换处理图像: 1、首先打开MATLAB的主界面,在其中的编辑器中写入如下代码: I=imread('G:\MATLAB练习\bm.bmp'); %读取保存路径下的图片 I1=rgb2gray(I); subplot(1,2,1...

    下面来简单介绍一下基于MATLAB的非线性变换处理图像:

    1、首先打开MATLAB的主界面,在其中的编辑器中写入如下代码:

     I=imread('G:\MATLAB练习\bm.bmp');              %读取保存路径下的图片
     I1=rgb2gray(I);
     subplot(1,2,1),imshow(I1);
     title(' 灰度图像');
     axis([50,250,50,200]);
     grid on;                  %显示网格线
     axis on;                  %显示坐标系
     J=double(I1);
     J=40*(log(J+1));
     H=uint8(J);
     subplot(1,2,2),imshow(H);
     title(' 对数变换图像');
     axis([50,250,50,200]);
     grid on;                  %显示网格线
     axis on;                  %显示坐标系

     

    2、代码命名保存好之后,点击运行会出现下图所示结果

    至此,关于非线性变换的内容就介绍完毕了,欢迎大家继续关注!!

    展开全文
  • 通常有两种类型的非线性变换:分位数变换、幂变换。这两种变换都是单调变换,这样,保证了变换前后的秩关系是一致的。 分位数变换 假设特征 XXX, 累积分布 F(X)F(X)F(X), 所有特征的共同输出分布 GGG. 分位数变换将...

    论文合作、课题指导请联系QQ2279055353

    通常有两种类型的非线性变换:分位数变换、幂变换。这两种变换都是单调变换,这样,保证了变换前后的秩关系是一致的。

    分位数变换

    假设特征 XX, 累积分布 F(X)F(X), 所有特征的共同输出分布 GG. 分位数变换将所有特征变换到相同的分布,根据 G1(F(X))G^{-1}(F(X)), G1G^{-1}GG 的分位数函数。该式根据以下事实:

    • 如果 F(X)F(X) 是连续的,那么 F(X)F(X) 是[0, 1] 上的均匀分布。
    • 如果 UU 是[0, 1] 上的均匀分布,那么 G1(U)G^{-1}(U) 有分布 GG.

    通过秩变换,分位数变换平滑了特殊分布,因而受离群点的影响小。然而,它也破环了特征间的相关性与距离。

    幂变换

    幂变换是一族参数变换,它将任意分布的数据映射到近似正态分布。

    映射到均匀分布

    sklearn.preprocessing库的类QuantileTransformer, quantile_transform提供了一个非参数变换,将数据映射到[0, 1] 上的均匀分布。

     from sklearn.datasets import load_iris
     from sklearn.model_selection import train_test_split
     X, y = load_iris(return_X_y=True)
     X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
     quantile_transformer = preprocessing.QuantileTransformer(random_state=0)
     X_train_trans = quantile_transformer.fit_transform(X_train)
     X_test_trans = quantile_transformer.transform(X_test)
     np.percentile(X_train[:, 0], [0, 25, 50, 75, 100]) 
    

    array([ 4.3, 5.1, 5.8, 6.5, 7.9])

    映射到正态分布

    特征的正态分布特性很常见,而幂变换将来自任意分布的数据变成近似正态的,稳定方差且最小化偏度。类class sklearn.preprocessing.PowerTransformer提供两种形式的幂变换。

    • Yeo-Johnson 变换
      在这里插入图片描述
    • Box-Cox 变换
      在这里插入图片描述
      Box-Cox变换仅能应用到正值数据上。这两种变换里的参数 λ\lambda 的值,由最大似然估计确定。下面,我们举一个Box-Cox变换的例子,它将来自对数正态分布的样本变换到正态分布。
      在这里插入图片描述
    展开全文
  • 非线性转换

    2016-11-02 23:13:16
    我们之前的课程都是假设数据是线性可分的,那么我们就可以用一条直线将其分开。 比如,想这样 然而现实生活中并不是这样的   像上面的那张图,无论我们用怎样的线性模型都无法将其很好的分开。但是我们发现一...

    我们之前的课程都是假设数据是线性可分的,那么我们就可以用一条直线将其分开。
    比如,想这样
    这里写图片描述
    然而现实生活中并不是这样的
    这里写图片描述 
    像上面的那张图,无论我们用怎样的线性模型都无法将其很好的分开。但是我们发现一个圆可以很好的解决这个问题
    这里写图片描述
    他的分类器方程为
    这里写图片描述
    那么我们把1,x21x22设定为z0,z1,z2,就相当于得到了一条关于z的线性方程。
    这里写图片描述
    也就是说,我们可以通过一个函数Φ(x)把x映射到z上面,那么就可以把可用圆分开的数据集xn,yn,转换成可用直线分开的数据集zn,yn
    这里写图片描述
    就把上面左边的图映射到右边的图了。

    那具体该怎么做呢???
    首先我们把x域的数据点{x,y}通过函数Φ(x)全部映射到z域,即
    这里写图片描述
    然后用z域的数据 { z , y } 训练模型,即
    这里写图片描述
    以后,每来一个新样本(x,y),我们救将其转化到z域上面,得到(z,y),然后用上面的模型对该新样本(z,y)进行分类即可。
    这里写图片描述

    可是,这个Φ(x)该怎么选呢???并不知道啊!!!求大神告知!!!(可以参考svm的核函数)

    貌似,我们可以通过这种方法表示出所有的模型,但是这并不是全能的,他有很大的缺点限制这他的使用。
    当x的次数越高,模型就越复杂,就会把一些误差给记住,那么虽然Ein此时很低,但是并不能使得E=Ein。过拟合。
    当x次数太低,模型简单,虽然能保证E=Ein,但是不能保证Ein此时低。欠拟合。

    还有我们怎么确定Φ(x),也就是x的形式是怎样的。我们之前的例子x的形式是椭圆,即有x21,x22,这样就知道了Φ(x)。那么问题就是,凭什么是圆,其实椭圆也是可以的。其实这是根据我们肉眼观察的,这样的做法是不科学的。首先,如果是10维的话,我们肉眼是看不出来的。即使可以看出来,由于结果是我们人脑学习出来的,所以我们计算出来的错误虽小,但是并没有把我们人脑引起的误差算进去。也就是,可能其实用椭圆比用圆更好。所以Φ(x)的形式,不能根据人眼观察得到。

    最后一个知识点是:
    这里写图片描述 
    对于上面的图形我们并不陌生。我们最终的目的是希望 out-of-sample error最小,而不是 in-sample error最小。所以,我们应该最先建立一个很简单的模型,逐渐改进;千万不要一开始就弄一个复制的模型,那样就不好评估,你估计还以为你的算法很好,其实早已经过拟合了。

    展开全文
  • 在之前介绍的分类问题中,所涉及的分类的模型都是线性的,在非线性变换这一节中,我们将模型延伸到非线性的情况下来进行数据的分类。 二次假设(Quadratic Hypotheses) 我们看到上面的例子,在左图中,圆圈和...

    引言

    在之前介绍的分类问题中,所涉及的分类的模型都是线性的,在非线性变换这一节中,我们将模型延伸到非线性的情况下来进行数据的分类。

    二次假设(Quadratic Hypotheses)


    我们看到上面的例子,在左图中,圆圈和红叉的数据无法用一条直线将其分成两类,那么这这个例子中,我们其实可以用一个大圆圈将数据分类,所以现在我们考虑假设,该假设hSEP(x)是一个过原点的圆圈,这启示我们可以用系统化的方法结合之前我们学习的线性分类的方法,来解决更加广泛的问题。
    还是拿上面的这个圆圈的Φ假设为例,h(x)=sign(0.6· 1 + (-1) ·x1^2 + (-1) ·x2^2)。我们令w0=0.6,w1=-1,w2=-1;而z0=1,z1=x1^2,z2=x2^2。通过这种方式我们就可以将之前的h(x)变化成sign(wT * z),这个熟悉的形式就是我们之前学习的线性分类的形式,我们唯一做的不同的事情就是将之前的x的空间转换成新的z的空间。我们把x空间的每一个点转换到z空间的每一个点的过程称作特征转换(Feature Transform)。这里值得一提的是,x空间里用二次假设可分的情况,可以得到在z空间的 线性可分,但是反过来则不可以,因为在z空间里的直线不见得在x空间里都是正圆形,还有可能是双曲线之类的二次曲线,所以在z空间使得数据线性可分的直线对应x空间的特定的曲线。


    我们可以考虑一个更加广泛的二次假设,这个假设是使得在z空间里让数据线性可分的假设,那其中的转换函数如下图定义。


    非线性变换(Nonlinear Transform)

    我们可以总结这个非线性转换的步骤,即先通过Φ(x)将x空间的点转换成z空间的点,而在z空间上得到一个线性的假设,再恢复到原来的x空间中得到一个二次的假设(这个反运算的过程不一定存在)。


    其实这个特征转换是非常重要的,比如在手写数字分类的案例中,我们将原始的像素的特征数据转换到更加具体的、具有物理意义的特征上去,进而进行分类的求解。这个例子其实就是在新的特征空间中做线性分类,而对于原始的像素空间里其实是一个非线性的假设。


    非线性变换的代价(Price of Nonlinear Transform)

    计算/存储的代价(Computation/Storage Price)

    现在我们考虑一个很一般化(general)的非线性变换,将刚才的二次变成Q次的多项式转换。


    我们用d来表示在z空间的维度,我们需要得到d维的不同的组合方法,复杂度是O(Q^d)。
    这个数字代表我们需要这样的计算复杂度来计算Φ(x)变换、计算参数w(因为一些训练算法的时间复杂度和数据的维度是有关的),还有存储w的话也需要付出代价。


    模型复杂度(Model Complexity Price)

    我们知道这个z空间的模型的参数是1+d个,这个相当于是z空间的vc维,所以当Q变大的时候,vc维也变大了。


    泛化问题(Generalization Issue)

    我们再回到机器学习的一个基本都是平衡折中问题上,如果d(Q)大的时候,我们可以让Ein很小,但是这会导致Ein和Eout差别很大;当d(Q)小的时候,可以使得Ein和Eout差别小,但是又不能保证Ein很小。


    结构化的假设集合(Structured Hypothesis Sets)

    现在我们把多项式的变换做一个递归式的定义,先定义0次的变换,再定义1次的变换,其中包括之前的0次变换和所有的一次式,以此类推,Q次的变换包含之前的Q-1次的变换和所有的Q次式。


    上面的定义中,因为每个变换都包含了前面的变换,即前面的变换是后面变换的一个特例。从假设集合的角度,复杂的变换对应的假设集合是包含相对简单的变换对应的假设集合。


    有了之前复杂度不同的假设集合的包含关系,可以得到以下的关系,即vc维随着假设集合的数量越累越多而变得越来越大,而Ein随着这些假设集合中的选择越来越多而呈下降的趋势。


    这个关系如下图所示,这告诉我们一个高维度的变换因为付出了很大的模型复杂度,所以会使得Eout和Ein偏离较远。那么,在未来的模型选择中,可以首先选择线性的模型,因为线性模型简单、有效、安全并且工作效果好。


    转载请注明作者Jason Ding及其出处
    Github主页(http://jasonding1354.github.io/)
    CSDN博客(http://blog.csdn.net/jasonding1354)
    简书主页(http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)


    展开全文
  • 转自https://blog.csdn.net/eastmount/article/details/46312145本文主要讲述基于VC++6.0 ...包括图像灰度线性变换、灰度非线性变换、图像阈值化处理、图像均衡化处理等知识,并结合前一篇论文灰度直方图进行展示 。...

     转自https://blog.csdn.net/eastmount/article/details/46312145

    本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程《数字图像处理》及课件进行讲解,主要通过MFC单文档视图实现显示BMP图片点运算处理,包括图像灰度线性变换、灰度非线性变换、图像阈值化处理、图像均衡化处理等知识,并结合前一篇论文灰度直方图进行展示 。同时文章比较详细基础,希望该篇文章对你有所帮助,尤其是初学者和学习图像处理的学生。

           【数字图像处理】一.MFC详解显示BMP格式图片
           【数字图像处理】二.MFC单文档分割窗口显示图片
           【数字图像处理】三.MFC实现图像灰度、采样和量化功能详解
           【数字图像处理】四.MFC对话框绘制灰度直方图
            
    免费资源下载地址:
            http://download.csdn.net/detail/eastmount/8764373


    一. 点运算与初始操作

            图像的点运算是图像处理中非常基础的技术,它主要用于改变一篇图像的灰度分布范围,通过一定的变换函数将图像的像素进行转换,最终生成一幅新的图像。点运算的最大特点就是输出像素值只与当前输入像素值相关。定义如下。
            点运算(Point Operation)指对于一幅输入图像,将产生一幅输出图像,输出图像的每个像素点的灰度值由输入像素点决定。
            点运算由灰度变换函数(Grap Scale Transformation,GST)确定:B(x,y)=F[A(x,y)]

            需要注意一下几点:
            (1).与局部或邻域运算的差别,输入像素和输出像素是一一对应的;(2).与几何运算的差别,不改变图像的空间关系;(3).又称为对比增强,对比拉伸或灰度变换。


            在前面第四篇博客的基础上增加点运算处理。
            第一步:在资源视图中Menu中添加“图像点运算”菜单栏如下所示:


            对应的ID值为:
            线性变换 ID_DYS_XXYD(点运算 线性移动) ID_DYS_XXZQ( 点运算 线性增强)
                           ID_DYS_XXJX(点运算 线性减小)  ID_DYS_XXQB(点运算 线性求补)
            非线性变换 ID_DYS_FXXPF(点运算 非线性平方) ID_DYS_FXXHS(非线性函数)
            阈值变换 ID_DYS_YZBH(点运算 阈值变换) 图像均衡化 ID_DYS_JHH

            第二步:打开类向导(Ctrl+W),为点运算每个ID菜单添加相应的功能处理函数,如下图所示:选择类CImageProcessingView,在选择IDs为ID_DYS_...(点运算)添加函数OnDysXxqb()线性求补。


    二. 线性变换

            图像线性变换是通过建立灰度映射来调整资源图像的灰度,从而达到图像增强的目的。其中GST函数f(D)为线性的,即:


            若a=1,b=0图像像素不发生变化
            若a=1,b!=0图像所有灰度值上移或下移
            若a>1输出图像对比度增强
            若0<a<1输出图像对比度减小
            若a<0暗区域变亮,亮区域变暗,图像求补


            1.D(B)=D(A)+50
            首先是图像移动,代码如下:
    1. /**********************************************************************/  
    2. /* 图像点运算 4种线性变化直方图:                                                 
    3. /* ID_DYS_XXYD:表示线性灰度变化移动 D(B)=D(A)+50  灰度值上移下移         
    4. /* ID_DYS_XXZQ:表示线性灰度变化增强 D(B)=1.5*D(A) 图像对比度增强        
    5. /* ID_DYS_XXJX:表示线性灰度变化减小 D(B)=0.8*D(A) 图像对比度减小        
    6. /* ID_DYS_XXQB:表示线性灰度求补 D(B)=-1*D(A)+255  图像暗区变亮,亮区变暗  
    7. /**********************************************************************/  
    8.   
    9. // 1.点运算 线性灰度变化移动 D(B)=D(A)+50  
    10. void CImageProcessingView::OnDysXxyd()   
    11. {  
    12.     // TODO: Add your command handler code here  
    13.     if(numPicture==0) {  
    14.         AfxMessageBox("载入图片后才能线性灰度运算!",MB_OK,0);  
    15.         return;  
    16.     }  
    17.     AfxMessageBox("线性灰度直方图-灰度变化移动 D(B)=D(A)+50!",MB_OK,0);  
    18.     int i;  
    19.     //打开临时的图片  
    20.     FILE *fpo = fopen(BmpName,"rb");  
    21.     FILE *fpw = fopen(BmpNameLin,"wb+");  
    22.     //读取文件  
    23.     fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
    24.     fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);  
    25.     fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);  
    26.     fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);  
    27.     //灰度图像  
    28.     unsigned char color;  
    29.     unsigned char red,green,blue;  
    30.     for( i=0; i<m_nImage/3; i++ )  
    31.     {  
    32.         fread(&red,sizeof(char),1,fpo);  
    33.         fread(&green,sizeof(char),1,fpo);  
    34.         fread(&blue,sizeof(char),1,fpo);  
    35.   
    36.         if( (int)red+50 >255 )  
    37.             red=255;  
    38.         else  
    39.             red=(int)red+50;  
    40.   
    41.         if( (int)green+50>255 )  
    42.             green=255;  
    43.         else  
    44.             green=(int)green+50;    
    45.   
    46.         if( (int)blue+50>255 )  
    47.             blue=255;  
    48.         else  
    49.             blue=(int)blue+50;  
    50.   
    51.         fwrite(&red,sizeof(char),1,fpw);  
    52.         fwrite(&green,sizeof(char),1,fpw);  
    53.         fwrite(&blue,sizeof(char),1,fpw);  
    54.     }  
    55.     fclose(fpo);  
    56.     fclose(fpw);  
    57.     numPicture = 2;  
    58.     level=101;       //赋值101在ShowBitmap中调用显示处理后的图片  
    59.     Invalidate();  
    60. }  

            同时修改void CImageProcessingView::ShowBitmap(CDC *pDC, 
    CString BmpName)函数中的代码:

    1. else        //图像点运算 线性变化  
    2. if(level=101)  
    3. {  
    4.     m_hBitmapChange = (HBITMAP) LoadImage(NULL,BmpNameLin,IMAGE_BITMAP,0,0,  
    5.         LR_LOADFROMFILE|LR_DEFAULTSIZE|LR_CREATEDIBSECTION);  
    6. }  
            运行效果如下图所示,同时我截取了直方图(RGB相同只显示一种)。

            可以发现图像的灰度上移了50,图像更白了(黑0-255白)。

            2.D(B)=1.5*D(A)
    1. // 2.点运算 线性灰度变化增强 D(B)=1.5*D(A)  
    2. void CImageProcessingView::OnDysXxzq()   
    3. {  
    4.     if(numPicture==0) {  
    5.         AfxMessageBox("载入图片后才能线性灰度运算!",MB_OK,0);  
    6.         return;  
    7.     }  
    8.     AfxMessageBox("线性灰度直方图-灰度变化增强 D(B)=1.5*D(A)!",MB_OK,0);  
    9.     int i;  
    10.     //打开临时的图片  
    11.     FILE *fpo = fopen(BmpName,"rb");  
    12.     FILE *fpw = fopen(BmpNameLin,"wb+");  
    13.     fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
    14.     fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);  
    15.     fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);  
    16.     fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);  
    17.     //灰度图像  
    18.     unsigned char color;  
    19.     unsigned char red,green,blue;  
    20.     for( i=0; i<m_nImage/3; i++ )  
    21.     {  
    22.         fread(&red,sizeof(char),1,fpo);  
    23.         fread(&green,sizeof(char),1,fpo);  
    24.         fread(&blue,sizeof(char),1,fpo);  
    25.   
    26.         if( (int)red*1.5 >255 )  
    27.             red=255;  
    28.         else  
    29.             red=(int)red*1.5;  
    30.   
    31.         if( (int)green*1.5>255 )  
    32.             green=255;  
    33.         else  
    34.             green=(int)green*1.5;    
    35.           
    36.         if( (int)blue*1.5>255 )  
    37.             blue=255;  
    38.         else  
    39.             blue=(int)blue*1.5;  
    40.   
    41.         fwrite(&red,sizeof(char),1,fpw);  
    42.         fwrite(&green,sizeof(char),1,fpw);  
    43.         fwrite(&blue,sizeof(char),1,fpw);  
    44.     }  
    45.     fclose(fpo);  
    46.     fclose(fpw);  
    47.     numPicture = 2;  
    48.     level=101;      //线性变化 ShowBitmap中调用  
    49.     Invalidate();  
    50. }  
            运行效果如下图所示,图像对比度增强,平均灰度122*1.5=181

            3.D(B)=0.8*D(A)
    1. // 3.点运算 线性灰度变化减小D(B)=0.8*D(A)  
    2. void CImageProcessingView::OnDysXxjx()   
    3. {  
    4.     if(numPicture==0) {  
    5.         AfxMessageBox("载入图片后才能线性灰度处理!",MB_OK,0);  
    6.         return;  
    7.     }  
    8.     AfxMessageBox("线性灰度直方图-灰度减小 D(B)=0.8*D(A)!",MB_OK,0);  
    9.     int i;  
    10.     //打开临时的图片  
    11.     FILE *fpo = fopen(BmpName,"rb");  
    12.     FILE *fpw = fopen(BmpNameLin,"wb+");  
    13.     fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
    14.     fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);  
    15.     fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);  
    16.     fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);  
    17.     //灰度图像  
    18.     unsigned char color;  
    19.     unsigned char red,green,blue;  
    20.     for( i=0; i<m_nImage/3; i++ )  
    21.     {  
    22.         fread(&red,sizeof(char),1,fpo);  
    23.         fread(&green,sizeof(char),1,fpo);  
    24.         fread(&blue,sizeof(char),1,fpo);  
    25.   
    26.         red=(int)red*0.8;  
    27.         green=(int)green*0.8;    
    28.         blue=(int)blue*0.8;  
    29.   
    30.         fwrite(&red,sizeof(char),1,fpw);  
    31.         fwrite(&green,sizeof(char),1,fpw);  
    32.         fwrite(&blue,sizeof(char),1,fpw);  
    33.     }  
    34.     fclose(fpo);  
    35.     fclose(fpw);  
    36.     numPicture = 2;  
    37.     level=101;  
    38.     Invalidate();  
    39. }  
            运行如下图所示,图像减弱。



            4.D(B)=-1*D(A)+255
    1. // 4.点运算 线性灰度求补 D(B)=-1*D(A)+255  
    2. void CImageProcessingView::OnDysXxqb()   
    3. {  
    4.     if(numPicture==0) {  
    5.         AfxMessageBox("载入图片后才能线性灰度处理!",MB_OK,0);  
    6.         return;  
    7.     }  
    8.     AfxMessageBox("线性灰度直方图-灰度求补 D(B)=-1*D(A)+255!",MB_OK,0);  
    9.     int i;  
    10.     //打开临时的图片  
    11.     FILE *fpo = fopen(BmpName,"rb");  
    12.     FILE *fpw = fopen(BmpNameLin,"wb+");  
    13.     fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
    14.     fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);  
    15.     fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);  
    16.     fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);  
    17.     //灰度图像  
    18.     unsigned char color;  
    19.     unsigned char red,green,blue;  
    20.     for( i=0; i<m_nImage/3; i++ )  
    21.     {  
    22.         fread(&red,sizeof(char),1,fpo);  
    23.         fread(&green,sizeof(char),1,fpo);  
    24.         fread(&blue,sizeof(char),1,fpo);  
    25.   
    26.         red=(int)red*(-1)+255;  
    27.         green=(int)green*(-1)+255;    
    28.         blue=(int)blue*(-1)+255;  
    29.   
    30.         fwrite(&red,sizeof(char),1,fpw);  
    31.         fwrite(&green,sizeof(char),1,fpw);  
    32.         fwrite(&blue,sizeof(char),1,fpw);  
    33.     }  
    34.     fclose(fpo);  
    35.     fclose(fpw);  
    36.     numPicture = 2;  
    37.     level=101;  
    38.     Invalidate();  
    39. }  
            运行效果如下图所示,它是图像的求补,发现直方图是互补的。

            PS:注意图片下面的直方图应该还有一个处理后的直方图,但原理都一样,我不想重复工作,你自己可以去简单实现下,参考第四篇文章。同时这些图片制作还挺麻烦的,只是为了给你更好的呈现它们的变化,希望对你有用和尊重作者,不喜勿喷~

    三. 非线性变换

            灰度非线性变换主要包括对数变换、幂次变换、指数变换、分段函数变换,通过非线性关系对图像进行灰度处理,下面主要讲解课件中的两个函数对其进行处理。其中对数变换实现了扩展低灰度值而压缩高灰度值的效果,图像灰度分布更符合而你的视觉特征。


            1.D(B)=D(A)*D(A)/252
    1. /************************************************************************/  
    2. /* 2种非线性变化直方图:                                                 
    3. /* ID_DYS_FXXPF:表示非线性平方灰度变化,D(B)=D(A)*D(A)/255                 
    4. /* ID_DYS_FXXHS:表示非线性函数灰度变化,D(B)=D(A)+0.8*D(A)*(255-D(A))/255  
    5. /************************************************************************/  
    6.   
    7. // 非线性平方灰度变化 D(B)=D(A)*D(A)/252  
    8. void CImageProcessingView::OnDysFxxpf()   
    9. {  
    10.     if(numPicture==0)  
    11.     {  
    12.         AfxMessageBox("载入图片后才能非线性灰度处理!",MB_OK,0);  
    13.         return;  
    14.     }  
    15.     AfxMessageBox("非线性灰度变化 D(B)=D(A)*D(A)/255!",MB_OK,0);  
    16.     int i;  
    17.     //打开临时的图片  
    18.     FILE *fpo = fopen(BmpName,"rb");  
    19.     FILE *fpw = fopen(BmpNameLin,"wb+");  
    20.     //读取文件  
    21.     fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
    22.     fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);  
    23.     fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);  
    24.     fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);  
    25.     //灰度图像  
    26.     unsigned char color;  
    27.     unsigned char red,green,blue;  
    28.     for( i=0; i<m_nImage/3; i++ )  
    29.     {  
    30.         fread(&red,sizeof(char),1,fpo);  
    31.         fread(&green,sizeof(char),1,fpo);  
    32.         fread(&blue,sizeof(char),1,fpo);  
    33.   
    34.         red=(int)red*(int)red/255;  
    35.         green=(int)green*(int)green/255;  
    36.         blue=(int)blue*(int)blue/255;  
    37.   
    38.         fwrite(&red,sizeof(char),1,fpw);  
    39.         fwrite(&green,sizeof(char),1,fpw);  
    40.         fwrite(&blue,sizeof(char),1,fpw);  
    41.     }  
    42.     fclose(fpo);  
    43.     fclose(fpw);  
    44.     numPicture = 2;  
    45.     level=101;  
    46.     Invalidate();  
    47. }  
            运行效果如下图所示:

            2.D(B)=D(A)+0.8*D(A)*(255-D(A))/255
    1. // 非线性函数灰度变化 D(B)=D(A)+0.8*D(A)*(255-D(A))/255  
    2. void CImageProcessingView::OnDysFxxhs()   
    3. {  
    4.     if(numPicture==0)  
    5.     {  
    6.         AfxMessageBox("载入图片后才能非线性灰度处理!",MB_OK,0);  
    7.         return;  
    8.     }  
    9.     AfxMessageBox("线性灰度直方图-灰度变化增强 D(B)=D(A)+0.8*D(A)*(255-D(A))/255!",MB_OK,0);  
    10.     int i;  
    11.   
    12.     FILE *fpo = fopen(BmpName,"rb");  
    13.     FILE *fpw = fopen(BmpNameLin,"wb+");  
    14.     fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
    15.     fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);   
    16.     fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);  
    17.     fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);  
    18.   
    19.     unsigned char color;  
    20.     unsigned char red,green,blue;  
    21.     for( i=0; i<m_nImage/3; i++ )  
    22.     {  
    23.         fread(&red,sizeof(char),1,fpo);  
    24.         fread(&green,sizeof(char),1,fpo);  
    25.         fread(&blue,sizeof(char),1,fpo);  
    26.   
    27.         if( ((int)red+0.8*(int)red*(255-(int)red)/255) > 255 )  
    28.             red=255;  
    29.         else  
    30.             red=(int)red+0.8*(int)red*(255-(int)red)/255;  
    31.   
    32.         if( ((int)green+0.8*(int)green*(255-(int)green)/255) > 255 )  
    33.             green=255;  
    34.         else  
    35.             green=(int)green+0.8*(int)green*(255-(int)green)/255;    
    36.           
    37.         if( ((int)blue+0.8*(int)blue*(255-(int)blue)/255) > 255 )  
    38.             blue=255;  
    39.         else  
    40.             blue=(int)blue+0.8*(int)blue*(255-(int)blue)/255;  
    41.   
    42.         fwrite(&red,sizeof(char),1,fpw);  
    43.         fwrite(&green,sizeof(char),1,fpw);  
    44.         fwrite(&blue,sizeof(char),1,fpw);  
    45.     }  
    46.     fclose(fpo);  
    47.     fclose(fpw);  
    48.     numPicture = 2;  
    49.     level=101;  
    50.     Invalidate();  
    51. }  
            运行效果如下图所示:


            写到此处你会发现图像灰度的线性变换和非线性变换是非常简单的,主要是通过以下步骤完成:
            第一步:赋值处理后图像的BMP头信息
                FILE *fpo = fopen(BmpName,"rb");
                FILE *fpw = fopen(BmpNameLin,"wb+");
                fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);
                fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);
                fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);
                fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);

            第二步:通过循环和线性变换或非线性便函函数处理每一个像素
                for( i=0; i<m_nImage/3; i++ )
                {
                     fread(&red,sizeof(char),1,fpo);
                     处理像素RBG 如:red=(int)red*(int)red/255;
                     fwrite(&red,sizeof(char),1,fpw);
                }

             第三步:调用ShowBitmap自定义函数并重绘图像
                numPicture = 2;
                level=101;
                Invalidate();
            
    而它的主要应用包括:光度学标定,希望数字图像的灰度能够真实反映图像的物理特性;对比度增强和对比度扩展;显示标定和轮廓线确定(阈值化)。

    四. 灰度阈值化

            阈值又称为临界值,它的目的是确定出一个范围,然后这个范围内的部分使用同一种方法处理,而阈值之外的部分则使用另一种处理方法或保持原样。常用的包括产生二值图:当x<T时y=0,当x>=T时y=255(其中T是阈值)。阈值变换在生物学上的应用比较广泛,常用语细胞图像分割等。
            打开类向导(Ctrl+W)生成选择ImageProcessingView类,IDs选择ID_DYS_YZBH后添加相应的函数。代码如下:

    1. /**************************************************************/  
    2. /* ID_DYS_YZBH:表示点运算阈值变换 也看做灰度拉伸                    
    3. /* 此处的拉伸是:阈值化(thresholding)可以看作是削波的一个特例  
    4. /* 只要令削波中的g1old=g2old就实现了阈值化。                   
    5. /* 阈值就象个门槛,比它大就是白,比它小就是黑,二值             
    6. /**************************************************************/  
    7.   
    8. void CImageProcessingView::OnDysYzbh()   
    9. {  
    10.     if(numPicture==0)  
    11.     {  
    12.         AfxMessageBox("载入图片后才能点运算阈值化处理!",MB_OK,0);  
    13.         return;  
    14.     }  
    15.     AfxMessageBox("图像点运算阈值化处理!",MB_OK,0);  
    16.     //读写文件  
    17.     FILE *fpo = fopen(BmpName,"rb");  
    18.     FILE *fpw = fopen(BmpNameLin,"wb+");  
    19.     fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
    20.     fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);  
    21.     fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);  
    22.     fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);  
    23.     //处理  
    24.     unsigned char color;  
    25.     unsigned char red,green,blue;  
    26.     for(int i=0; i<m_nImage/3; i++ )  
    27.     {  
    28.         fread(&red,sizeof(char),1,fpo);  
    29.         fread(&green,sizeof(char),1,fpo);  
    30.         fread(&blue,sizeof(char),1,fpo);  
    31.   
    32.         if( (int)red > 128 )  
    33.             red=255;  
    34.         else  
    35.             red=0;  
    36.   
    37.         if( (int)green > 128 )  
    38.             green=255;  
    39.         else  
    40.             green=0;    
    41.           
    42.         if( (int)blue > 128 )  
    43.             blue=255;  
    44.         else  
    45.             blue=0;  
    46.   
    47.         fwrite(&red,sizeof(char),1,fpw);  
    48.         fwrite(&green,sizeof(char),1,fpw);  
    49.         fwrite(&blue,sizeof(char),1,fpw);  
    50.     }  
    51.     fclose(fpo);  
    52.     fclose(fpw);  
    53.     numPicture = 2;  
    54.     level=101;  
    55.     Invalidate();  
    56. }  
            运行效果如下图所示,感觉还挺好看的,显然此时的直方图就是0和255两条直线。


    五. 灰度均衡化

            灰度均衡化的目的是使一输入图像转换为在每一灰度级上都有相同的像素点(即输出的直方图是平的),它可以产生一幅灰度级分布概率均衡的图像。
            换句话说,经过均衡化后的图像在每一级灰度上像素点的数量相差不大,对应的灰度直方图的每一级高度也相差不大。它是增强图像的有效手段之一。
            研究思路是通过直方图变换公式实现:


            它的步骤如下图所示:

            例:有一幅图象,共有16级灰度,其直方图分布为Pi, i=0,1,…,15,求经直方图均衡化后,量化级别为10级的灰度图象的直方图分布Qi,其中Pi和Qi为分布的概率,即灰度i出现的次数与总的点数之比。
            Pi:0.03, 0, 0.06, 0.10, 0.20, 0.11, 0, 0, 0, 0.03, 0, 0.06, 0.10, 0.20, 0.11, 0
            步骤1:用一个数组s记录Pi,即s[0]=0.03,s[1]=0,s[2]=0.06,…,s[14]=0.11,s[15]=0
            步骤2:i从1开始,令s[i]=s[i]+s[i-1],得到的结果是s: 0.03,  0.03, 0.09,  0.19,  0.39, 0.50,  0.50,  0.50, 0.50,  0.53,  0.53, 0.59,  0.69,  0.89, 1.0,  1.0
            步骤3:用一个数组L记录新的调色板索引值,即令L[i]=s[i]×(10-1),得到的结果是L:0,0,1,2,4,5,5,5,5,5,5,5,6,8,9,9
            这样就找到了原来的调色板索引值和新的调色板索引值之间的对应关系,即
            0→0,  1→0, 2→1,  3→2,  4→4, 5→5,  6→5,  7→5, 8→5,  9→5,  10→5, 11→5,  12→6,  13→8, 14→9,  15→9。
           步骤4:将老的索引值对应的概率合并,作为对应的新的索引值的概率。例如,原来的索引值0,1都对应了新的索引值0,则灰度索引值为0的概率为P0+P1=0.03;新的索引值3和7找不到老的索引值与之对应,所以令Q3和Q7为0。最后得到的结果是Qi:0.03,  0.06, 0.10,  0,  0.20, 0.20,  0.10,  0, 0.20,  0.11 

            代码中有详细注释如下:
    1. // ID_DYS_JHH:表示图像均衡化 相见算法  
    2. void CImageProcessingView::OnDysJhh()   
    3. {  
    4.     if(numPicture==0) {  
    5.         AfxMessageBox("载入图片后才能图像均衡化!",MB_OK,0);  
    6.         return;  
    7.     }  
    8.     AfxMessageBox("图像均衡化!",MB_OK,0);  
    9.   
    10.     //第一步:获取图像的数据信息  
    11.     //此操作可以在打开图片时就进行 在直方图采样(ZFTCY)中也有该代码  
    12.     FILE *fpo = fopen(BmpName,"rb");  
    13.     fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
    14.     fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);  
    15.   
    16.     int i,j,k;  
    17.     for(j=0;j<256;j++) { //定义数组并清零  
    18.         Red[j]=0;  
    19.         Green[j]=0;  
    20.         Blue[j]=0;  
    21.     }  
    22.       
    23.     //计算4个数据  
    24.     unsigned char red,green,blue;  
    25.     int IntRed,IntGreen,IntBlue;                  //强制转换  
    26.     double sumRedHD=0,sumGreenHD=0,sumBlueHD=0;   //记录像素总的灰度值和  
    27.     for(i=0; i<m_nImage/3; i++ )  
    28.     {  
    29.         fread(&red,sizeof(char),1,fpo);  
    30.         IntRed=int(red);  
    31.         sumRedHD=sumRedHD+IntRed;  
    32.         if( IntRed>=0 && IntRed<256 ) Red[IntRed]++;  
    33.           
    34.         fread(&green,sizeof(char),1,fpo);  
    35.         IntGreen=int(green);  
    36.         sumGreenHD=sumGreenHD+IntGreen;  
    37.         if( IntGreen>=0 && IntGreen<256 ) Green[IntGreen]++;  
    38.           
    39.         fread(&blue,sizeof(char),1,fpo);  
    40.         IntBlue=int(blue);  
    41.         sumBlueHD=sumBlueHD+IntBlue;  
    42.         if( IntBlue>=0 && IntBlue<256 ) Blue[IntBlue]++;  
    43.     }  
    44.     fclose(fpo);  
    45.   
    46.     /*****************************************************************/  
    47.     /* 图像均衡化处理                                                 
    48.     /* 利用全局变量 Red[256] Blue[256] Green[256]                     
    49.     /* 第一步:用3个数组Count..记录0-255灰度出现的概率,即             
    50.     /*        概率=该灰度出现次数*3/总得像素 (因为分成3部分RGB)       
    51.     /* 第二步:i从1开始,令s[i]=s[i]+s[i-1] 记录新概率数               
    52.     /* 第三步:用一个数组L记录新的调色板索引值,即                     
    53.     /*        L[i]=s[i]×(256-1)结果四舍五入2.8即为3                  
    54.     /* 第四步:将老的索引值对应的概率合并,作为对应的新的索引值的概率  
    55.     /*   1.原来的索引值0,1都对应了新的索引值0,则灰度索引值为0的概率  
    56.     /*     为P0+P1=0.03                                               
    57.     /*   2.新的索引值3和7找不到老的索引值与之对应,所以令Q3和Q7为0    
    58.     /*****************************************************************/  
    59.   
    60.     //记录出现的概率,会加到1 用于相加到调色板  
    61.     float CountRed[256],CountGreen[256],CountBlue[256];        
    62.     //记录原始数据,不会相加到1 用于计算新灰度概率  
    63.     float CountRedLin[256],CountGreenLin[256],CountBlueLin[256];     
    64.   
    65.     for( k=0 ; k<256 ; k++ )  
    66.     {  
    67.         CountRed[k]=(float)(Red[k])*3/m_nImage;  
    68.         CountRedLin[k]=CountRed[k];  
    69.         CountGreen[k]=(float)(Green[k])*3/m_nImage;  
    70.         CountGreenLin[k]=CountGreen[k];  
    71.         CountBlue[k]=(float)(Blue[k])*3/m_nImage;  
    72.         CountBlueLin[k]=CountBlue[k];  
    73.     }  
    74.       
    75.     for( k=1 ; k<256 ; k++ )  
    76.     {   
    77.         CountRed[k]=CountRed[k]+CountRed[k-1];  
    78.         CountGreen[k]=CountGreen[k]+CountGreen[k-1];  
    79.         CountBlue[k]=CountBlue[k]+CountBlue[k-1];  
    80.     }  
    81.   
    82.     /****************************************************/  
    83.     /* 此处百度到一个四舍五入浮点型的算法:               
    84.     /* float a=3.456;   保留到小数点后两位               
    85.     /* float b=(int)((a * 100) + 0.5) / 100.0;           
    86.     /* output b=3.46                                     
    87.     /****************************************************/  
    88.   
    89.     int LRed[256],LGreen[256],LBlue[256];   //记录调色板  
    90.     for( k=0 ; k<256 ; k++ )  
    91.     {  
    92.         LRed[k]=(int)(CountRed[k]*(256-1)+0.5);  
    93.         LGreen[k]=(int)(CountGreen[k]*(256-1)+0.5);  
    94.         LBlue[k]=(int)(CountBlue[k]*(256-1)+0.5);  
    95.     }  
    96.   
    97.     //第三步:处理均衡化图像写入 打开临时的图片  
    98.     fpo = fopen(BmpName,"rb");  
    99.     fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);  
    100.     fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);  
    101.   
    102.     FILE *fpw = fopen(BmpNameLin,"wb+");  
    103.     fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);  
    104.     fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);  
    105.   
    106.     //m_nWidth*m_nHeight 读取图片最后一行不为m_nWidth时会报错 改为m_nImage/3  
    107.     for( i=0; i<m_nImage/3 ; i++ )  
    108.     {     
    109.         fread(&red,sizeof(char),1,fpo);  
    110.         fread(&green,sizeof(char),1,fpo);  
    111.         fread(&blue,sizeof(char),1,fpo);  
    112.   
    113.         red=LRed[int(red)];  
    114.         green=LGreen[int(green)];  
    115.         blue=LBlue[int(blue)];  
    116.   
    117.         fwrite(&red,sizeof(char),1,fpw);  
    118.         fwrite(&green,sizeof(char),1,fpw);  
    119.         fwrite(&blue,sizeof(char),1,fpw);  
    120.     }  
    121.     fclose(fpw);  
    122.     numPicture = 2;  
    123.     level=101;  
    124.     Invalidate();     
    125. }  
            运行结果如下图所示,图像增强而且异常清晰:


            最后介绍下图像对比度拉伸,它就是把你感兴趣的灰度范围拉开,使得该范围内像素,亮的更亮,暗的更暗,从而达到增强对比度的目的。
            如下图所示,a、b、c为三段直线的斜率,g1old和g2old表示途中要进行对比度扩展的范围,g1new和g2new表示对应的新值。当g1old=g2old就是二值图像阈值化处理。
     
              由于灰度界别也是255这个约束,所以满足

           其中g1old=100,g2old=150,b=3.0的运行效果如下所示:
    展开全文
  • 非线性变换 在线性回归模型中,会发现有些变量与预测变量不是线性关系,所以需要非线性变换,把非线性关系转换为线性关系。 一、单变量做变换 载入boston房价数据 from sklearn.datasets import load_boston from...
  • 1.线性变换 (1)两个基本性质 a.加性:两个向量的和经过变换后等于两个向量变换后的和 b.齐性:一个向量缩放一个倍数变换等于先变换再缩放一个倍数 (2)点积和投影 a.点积::通俗意义上的内积,表示两个...
  • 图片的非线性变换的实验才疏学浅,难免疏漏,敬请批评指正对数变换Clear[a, da, db, b]; a = Import["addA.tif"]; da = ImageData[a]; db = 0.8 Log[1 + da]; b = Image[db]; Grid[{{a, b}}] 效果图 指数变换Clear...
  • 非线性转化

    2018-03-13 09:06:21
    我们之前的课程都是假设数据是线性可分的,那么我们就可以用一条直线将其分开。 比如,想这样 然而现实生活中并不是这样的 像上面的那张图,无论我们用怎样的线性模型都无法将其很好的分开。但是我们发现一个圆...
  • 2、对数、指数变换、取反等多种非线性变换的效果对比 变换结果与分析 分段线性变换 1)变换函数 2)分段线性变换结果 3)分段线性变换对比分析 通过变换,将灰度值小于82的变小,将灰度值大于173的增大,...
  • MATLAB非线性变换

    2020-02-10 12:17:02
    非线性变换 对图像进行灰度变换 clear all; R=imread('peppers.png'); G=rgb2gray(R); J=double(G); H=(log(J+1)/10); subplot(121);imshow(G); title('灰度图像'); subplot(122);imshow(H); title('非线性变换图像'...
  • 前面讲过的“非0即1法”,固定阈值法,双固定阈值法等都属于非线性变换。这里再补充几种常用的非线性变换。 一、灰度对数变换  对数变换实现了图像的灰度扩展和压缩的功能。它扩展低灰度值而压缩高灰度值,让图像...
  • 前一篇文章讲解了图像灰度化处理及线性变换知识,结合OpenCV调用cv2.cvtColor()函数实现图像灰度操作,本篇文章主要讲解非线性变换,使用自定义方法对图像进行灰度化处理,包括对数变换和伽马变换。本文主要讲解灰度...
  • 图像灰度非线性变换 文章目录1 原理2 Matlab实现3 OpenCV实现3.1 实现3.2 注意4 效果图 1 原理   图像灰度的非线性变换主要有对数变换、指数变换、幂次变换等。本文主要讨论对数变换。   对数变换的基本形式...
  • 很多人知道sigmoid函数是神经网络中常用的非线性变换方式,有几人知道为什么sigmoid函数比别的非线性变换更有吸引力吗?在评论和转发中已经看到不少有趣的见解了,我就不一一总结了(包括可导等数学性质,更多的可以...
  • 使用C++、opencv实现对图像的对数变换及非线性变换,实现图像增强 相关API: void normalize(InputArray src, OutputArray dst, double alpha=1, double beta=0, int norm_type=NORM_L2, int dtype=-1, Input...
  • DataScience:深入探讨与分析机器学习中的数据处理之非线性变换—log对数变换、sigmoid/softmax变换 目录 深入探讨与分析机器学习中的数据处理之非线性变换 log对数变换 sigmoid/softmax变换 Sigmoid函数...
  • 分类: 数学天地2013-09-09 ...本文整理自 @老师木 的一条图片新浪微博,从另一个角度给出为何采用 sigmoid 函数作非线性变换的解释。 为什么我们喜欢用 sigmoid 这类 S 型非线性变换?
  •  [函数名称] ...图像非线性变换函数NonlinearTransformProcess(WriteableBitmap src,int k )  [函数代码] /// /// Nonlinear transform process. /// /// The source image. /// Param
  • 非线性变换 空间变换 非线性变换的代价 z空间的维度 z空间的计算和存储代价二次方程的hypothesis对于非线性的数据分类,如果我们使用线性模型,就会使得Ein很大,分得不好。对称中心在原点的二次方程现在我们考虑...
1 2 3 4 5 ... 20
收藏数 75,819
精华内容 30,327
关键字:

非线性变换