zoukankan      html  css  js  c++  java
  • unmix和conditional average:消混叠和条件均值

    unmix

     该程序用来消除“像素混叠”。所谓像素混叠,是值在自然场景的图像中,边缘线成像到cmos的像素上时,某些像素会刚好跨在该边缘线上。

    这样的像素特点就是,其R、G、B三色像素梯度值不一致。比如说cmos上,每个彩色像素有R、G、B三色传感器组成,其排列方式是依次从左向右排序。

    那么,如果刚好有一条倾斜的边缘线该像素的G位置,且该边缘线上部为背景、下部为物体,那么其三色梯度值不同,且dR>dB,反之则dB>dR.。类似于这样

    的像素,我们可以通过unmix的方法将其消除。方法很简单,就是将该像素邻域内梯度相同或相近的像素替换该像素。下面是程序代码:

    Mat unmix(const Mat&img,int neibourSize)
    {
        Mat imgCopy=img.clone();
        int nr=neibourSize/2;
        int cols=img.cols,rows=img.rows;
        Mat kernel_x=(Mat_<int>(1,2)<<-1,1);
        Mat kernel_y=(Mat_<int>(2,1)<<-1,1);
        Mat img_dx,img_dy;//预声明X、Y方向的梯度矩阵
        filter2D(img,img_dx,CV_32F,kernel_x);
        filter2D(img,img_dy,CV_32F,kernel_y);
    
        Mat Gradient=abs(img_dx)+abs(img_dy);
    
        Mat theta=getGradientDirect(img_dy,img_dx);//该函数参见:https://www.cnblogs.com/phoenixdsg/p/11352623.html
    
        Mat  thetaGray;
        cvtColor(theta,thetaGray,COLOR_RGB2GRAY);//转成灰度图像便于处理
    
        ///unmix()函数
        for(int i=nr;i<rows-nr;i++)
        {
            for(int j=nr;j<cols-nr;j++)
            {
                float* pG=CV_MAT_ELEM2(Gradient,float,i,j);
                float R=pG[2],G=pG[1],B=pG[2];
                if(R!=B||R!=G||B!=G)
                {
                    Mat tmp=thetaGray(Rect(j-nr,i-nr,neibourSize,neibourSize));
                    Mat tmpr=tmp.clone();//截取邻域像素
                    float Pij=*(CV_MAT_ELEM2(thetaGray,float,i,j));//获取当前像素值
                    tmpr =abs(tmpr-Pij);
                    tmpr.at<float>(nr,nr)=7;
    
                    double minv;
                    Point minLoc;
                    minMaxLoc(tmpr,&minv,0,&minLoc);
                    minLoc=Point(nr,nr)-minLoc;
    //                cout<<"minv="<<minv<<" ; "
    //                   <<"minLoc="<<minLoc<< endl;
                    int ii=minLoc.y+i,jj=minLoc.x+j;
                    for(int k=0;k<3;k++)
                    {
                        imgCopy.ptr<Vec3b>(i)[j][k]=
                                img.ptr<Vec3b>(ii)[jj][k];
                    }
                }
            }
        }
        return imgCopy;
    }
    

      该函数有两个参数,第一个是待处理的图像,第二个参数是邻域尺寸,尺寸必须是3、5、7等奇数。函数返回值,即是unmix的结果。

    conditional average

    设当前像素为N0,其邻域像素集合为S,从S中挑选有效像素{Ni}。求取有效像素均值N0',并替代N0

    其中S={Ni: |Ni=N0|<T}。其中n是有效像素个数。注意S中始终包含N0。该程序会产生下面的效果:

    1)在一个同质区域中,平滑掉小量噪声,噪声的相对值小于T;

    2)在区域边界附近,对比度要大于T,刚好跨在边界上的像素不作均值处理。这样在平滑图像时,只对边界两边的像素作均值处理。

        这与普通的均值模糊不同,普通的均值模糊连边界也被模糊了;

    3)该程序只平滑一定梯度范围内的噪声,但不会将梯度平滑掉;

    4)在纹理区域,如果纹理像素之间会有小量的差异(小于T),那么这些像素将被平滑为通知区域,也就是消除纹理。

         如果纹理像素之间差值大于T,那么将不做平滑处理。

    程序代码如下:

    void conditionalAerage(Mat&img,int T)
    {
        int rows=img.rows,cols=img.cols;
        int neighborSize=3;
        int nr=neighborSize/2;
        for(int i=nr;i<rows-nr;i++)
        {
            for(int j=nr;j<cols-nr;j++)
            {
                int ctn=0;
                vector<Vec3b> nv;
                Vec3b P0=img.at<Vec3b>(i,j);
                float P0m=float(P0[0]+P0[1]+P0[1])/3.;
                for(int in=i-nr;in<neighborSize;in++)
                {
                    for(int jn=i-nr;jn<neighborSize;jn++)
                    {
                        Vec3b Pn=img.at<Vec3b>(in,jn);
                        float Pnm=float(Pn[0]+Pn[1]+Pn[1])/3.;
                        if(abs(Pnm-P0m)<T)
                        {
                            nv.push_back(Pn);
                        }
                    }
                    Vec3b sum(0,0,0);
                    ctn=nv.size();
                    for(int v=0;v<ctn;v++)
                    {
                        sum +=nv[v];
                    }
                    Vec3b aver=sum/ctn;
                    for(int k=0;k<img.channels();k++)
                        img.at<Vec3b>(i,j)[k]=aver[k];
                }
    
            }
        }
    }
    

      

  • 相关阅读:
    Springboot打包成WAR包独立布署后找不到静态js文件
    layui实现数据分页功能(ajax异步)
    layer.prompt(options, yes)
    layer回调函数
    Html中的position:absolute的意思
    SQL基础-DML
    mysql的pager命令
    由于rngd进程导致的tomcat 启动慢
    elasticsearch安装
    zookeeper的observer模式
  • 原文地址:https://www.cnblogs.com/phoenixdsg/p/11359122.html
Copyright © 2011-2022 走看看