zoukankan      html  css  js  c++  java
  • 中值滤波C语言优化

    中值滤波C语言优化

    图像平滑是图像预处理的基本操作,本文首先用不同的方法对一张图片做预处理比较它们效果的不同,然后针对中值滤波,实现了一种快速实现.(其实是copyopencv实现,呵呵).因为opencv的实现方法感觉太好了,今天就特别写下来.既有备忘的作用,同时如果谁看到这篇文章,也可以借鉴下opencv的实现.

    1 原始图像

    clip_image001

    2 均值滤波图像

    clip_image002

    3 中值滤波图像

    clip_image003

    4 双边滤波图像

    clip_image004

    5高斯滤波图像

    clip_image005

    上图的代码

    void CDialogTest2013Dlg::OnBnClickedMfcbutton1()

    {

        char file[10]="e:\1.jpg";

       

        IplImage *src = cvLoadImage(file,0);

        CvSize picSize;

        picSize.width = src->width;

        picSize.height = src->height;

        IplImage *dst_midian= cvCreateImage(picSize,8,1);

        IplImage *dst_blur = cvCreateImage(picSize,8,1);

        IplImage *dst_gaussian = cvCreateImage(picSize,8,1);

        IplImage *dst_bilateral = cvCreateImage(picSize,8,1);

        cvSmooth(src, dst_midian, CV_MEDIAN,3,3);

        cvSmooth(src, dst_blur, CV_BLUR,3,3);

        cvSmooth(src, dst_gaussian, CV_GAUSSIAN,3,3);

        cvSmooth(src, dst_bilateral, CV_BILATERAL,3,3);

       

    }

    均值滤波原理:把一个点周围点求均值,这个均值给这个点.

    中值滤波原理:把一个点周围的点排序,把中位数给这个点.

    双边滤波原理:这个一句话说不清楚,可以看这个博文 http://blog.csdn.net/bugrunner/article/details/7170471

    高斯滤波原理:均值滤波对一个点周围点求和是每个点的权重都是1,高斯滤波的权重不是1,是一个类似高斯分布的权重分布,距离目标点

    近的地方权重高点,距离目标点远的地方,权重低些.

    中值滤波的opencv实现

    template<class Op, class VecOp>

    staticvoid

    medianBlur_SortNet(const Mat& _src, Mat& _dst,int m )

    {

        typedef typename Op::value_type T;

        typedef typename Op::arg_type WT;

        typedef typename VecOp::arg_type VT;

        const T* src =(const T*)_src.data;

        T* dst =(T*)_dst.data;

        int sstep =(int)(_src.step/sizeof(T));

        int dstep =(int)(_dst.step/sizeof(T));

        Size size = _dst.size();

        int i, j, k, cn = _src.channels();

        Op op;

        VecOp vop;

        volatile bool useSIMD = checkHardwareSupport(CV_CPU_SSE2);

        if( m ==3)

        {

            if( size.width ==1|| size.height ==1)

            {

                int len = size.width + size.height -1;

                int sdelta = size.height ==1? cn : sstep;

                int sdelta0 = size.height ==1?0: sstep - cn;

                int ddelta = size.height ==1? cn : dstep;

                for( i =0; i < len; i++, src += sdelta0, dst += ddelta )

                    for( j =0; j < cn; j++, src++)

                    {

                        WT p0 = src[i >0?-sdelta :0];

                        WT p1 = src[0];

                        WT p2 = src[i < len -1? sdelta :0];

                        op(p0, p1); op(p1, p2); op(p0, p1);

                        dst[j]=(T)p1;

                    }

                return;

            }

            size.width *= cn;

            for( i =0; i < size.height; i++, dst += dstep )

            {

                const T* row0 = src + std::max(i -1,0)*sstep;

                const T* row1 = src + i*sstep;

                const T* row2 = src + std::min(i +1, size.height-1)*sstep;

                int limit = useSIMD ? cn : size.width;

                for(j =0;;)

                {

                    for(; j < limit; j++)

                    {

                        int j0 = j >= cn ? j - cn : j;

                        int j2 = j < size.width - cn ? j + cn : j;

                        WT p0 = row0[j0], p1 = row0[j], p2 = row0[j2];

                        WT p3 = row1[j0], p4 = row1[j], p5 = row1[j2];

                        WT p6 = row2[j0], p7 = row2[j], p8 = row2[j2];

                        op(p1, p2); op(p4, p5); op(p7, p8); op(p0, p1);  //op(p1, p2)  交换p1p2两个数

                        op(p3, p4); op(p6, p7); op(p1, p2); op(p4, p5);

                        op(p7, p8); op(p0, p3); op(p5, p8); op(p4, p7);

                        op(p3, p6); op(p1, p4); op(p2, p5); op(p4, p7);

                        op(p4, p2); op(p6, p4); op(p4, p2);

                        dst[j]=(T)p4;

                    }

                    if( limit == size.width )

                        break;

                    for(; j <= size.width - VecOp::SIZE - cn; j += VecOp::SIZE )

                    {

                        VT p0 = vop.load(row0+j-cn), p1 = vop.load(row0+j), p2 = vop.load(row0+j+cn);

                        VT p3 = vop.load(row1+j-cn), p4 = vop.load(row1+j), p5 = vop.load(row1+j+cn);

                        VT p6 = vop.load(row2+j-cn), p7 = vop.load(row2+j), p8 = vop.load(row2+j+cn);

                        vop(p1, p2); vop(p4, p5); vop(p7, p8); vop(p0, p1);

                        vop(p3, p4); vop(p6, p7); vop(p1, p2); vop(p4, p5);

                        vop(p7, p8); vop(p0, p3); vop(p5, p8); vop(p4, p7);

                        vop(p3, p6); vop(p1, p4); vop(p2, p5); vop(p4, p7);

                        vop(p4, p2); vop(p6, p4); vop(p4, p2);

                        vop.store(dst+j, p4);

                    }

                    limit = size.width;

                }

            }

        }

    }

    }

  • 相关阅读:
    C# 日志本地化工具
    javascript面向对象的写法01
    VM12-Pro 安装CentOS7 并配置静态IP出坑记
    基于CentOS7.x安装Nginx-1.18.0
    程序员思维导图、web初学者必备、web前端知识集锦-不断更新中...
    js知识
    swiper的使用
    web 移动端键盘处理-vue移动端那些事
    vue学习计划-vuex生态
    vue 组件复用
  • 原文地址:https://www.cnblogs.com/guopengfei/p/4745676.html
Copyright © 2011-2022 走看看