精华内容
下载资源
问答
  • opencv 高斯模糊

    2018-06-29 11:00:00
    opencv 高斯模糊 import numpy as np import cv2 from scipy import ndimage k33=np.array([[-1,-1,-1], [-1,8,-1], [-1,-1,-1]]) k33d=n...

    opencv 高斯模糊

    import numpy as np
    import cv2
    from scipy import ndimage
    
    k33=np.array([[-1,-1,-1],
                  [-1,8,-1],
                  [-1,-1,-1]])
    
    
    
    k33d=np.array([[1,1,1],
                  [1,-8,1],
                  [1,1,1]])
    
    
    img=cv2.imread('psu.jpeg',0)
    lg=cv2.GaussianBlur(img,(11,11),0)
    
    
    
    gg=img-lg
    
    #cv2.imwrite('gauss', gg)
    cv2.imshow('test',gg)
    cv2.waitKey()
    cv2.imwrite('gauss', gg)
    
    

    这里写图片描述

    这里写图片描述

    posted on 2018-06-29 11:00 luoganttcc 阅读(...) 评论(...) 编辑 收藏

    展开全文
  • OpenCV 高斯模糊

    千次阅读 2019-03-27 16:26:05
    高斯滤波器相比于均值滤波器对图像个模糊程度较小。 高斯公式 matlab代码 clear; a=0;sigma=0.8; x=-10:0.0001:10; figure(1) y=(1/((sqrt(2*pi))*sigma))*exp(-((x-a).^2)/(2*sigma.^2)); plot(x,y,'b','...

    高斯滤波器能够有效的抑制噪声,平滑图像。高斯滤波器相比于均值滤波器对图像个模糊程度较小。

    高斯公式

    matlab代码

    clear;
    a=0;sigma=0.8; 
    x=-10:0.0001:10;
    figure(1)
    y=(1/((sqrt(2*pi))*sigma))*exp(-((x-a).^2)/(2*sigma.^2));
    plot(x,y,'b','LineWidth',1.5);
    hold on;
    sigma=1.1
    y=(1/((sqrt(2*pi))*sigma))*exp(-((x-a).^2)/(2*sigma.^2));
    plot(x,y,'r','LineWidth',1.5);
    legend('sigma = 0.8','sigma = 1.1')

    从函数的结果来看,sigma值越大,曲线越“胖”;sigma值越小,曲线越“瘦”;对图像过滤来说,sigma值越大,滤波器中心点的权重也就越大,图像也就没有那么模糊。看一下代码原型和实例 

    OpenCV高斯函数原型即部分源码解析

    函数原型为

    //_src _IN_ 输入的源影像
    //_dst _OUT_ 输出的目标影像
    //kSize 核大小 如果大小为负数的话,那么根据输入的sigma进行计算
    //ksize 大小可以为1,3,5,7,最大值为7
    //计算的公式为 sigma = 0.3\*((ksize - 1)\*0.5 - 1) + 0.8
    //sigmal1 X方向上的sigma值
    //sigmal2 Y方向上的sigma值
    //如果sigmal值为负数的话,那么使用默认的滤波过滤器
    void cv::GaussianBlur( InputArray _src, OutputArray _dst, Size ksize,
                       double sigma1, double sigma2,
                       int borderType )

     部分函数解析

    void cv::GaussianBlur( InputArray _src, OutputArray _dst, Size ksize,
                       double sigma1, double sigma2,
                       int borderType )
    {
        int type = _src.type();//获取通道类型 CV_8UC3 CV_8UC1...
        Size size = _src.size();//获取影像的大小 宽度和高度
        _dst.create( size, type );//创建目标影像,和源影像的大小和类型是相同的
    
    	//borderType 边界类型参照的博客
    	//https://blog.csdn.net/zhanggusheng/article/details/70197051
        if( borderType != BORDER_CONSTANT && (borderType & BORDER_ISOLATED) != 0 )
        {
            if( size.height == 1 )
                ksize.height = 1;
            if( size.width == 1 )
                ksize.width = 1;
        }
    
    	//如果内核的宽度和高度都是1的话,那么源影像和目标影像是相同的
        if( ksize.width == 1 && ksize.height == 1 )
        {
            _src.copyTo(_dst);
            return;
        }
    
    #ifdef HAVE_TEGRA_OPTIMIZATION
        Mat src = _src.getMat();
        Mat dst = _dst.getMat();
        if(sigma1 == 0 && sigma2 == 0 && tegra::useTegra() && tegra::gaussian(src, dst, ksize, borderType))
            return;
    #endif
    
    #if IPP_VERSION_X100 >= 801 && 0 // these functions are slower in IPP 8.1
        CV_IPP_CHECK()
        {
            int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
    
            if ((depth == CV_8U || depth == CV_16U || depth == CV_16S || depth == CV_32F) && (cn == 1 || cn == 3) &&
                    sigma1 == sigma2 && ksize.width == ksize.height && sigma1 != 0.0 )
            {
                IppiBorderType ippBorder = ippiGetBorderType(borderType);
                if (ippBorderConst == ippBorder || ippBorderRepl == ippBorder)
                {
                    Mat src = _src.getMat(), dst = _dst.getMat();
                    IppiSize roiSize = { src.cols, src.rows };
                    IppDataType dataType = ippiGetDataType(depth);
                    Ipp32s specSize = 0, bufferSize = 0;
    
                    if (ippiFilterGaussianGetBufferSize(roiSize, (Ipp32u)ksize.width, dataType, cn, &specSize, &bufferSize) >= 0)
                    {
                        IppFilterGaussianSpec * pSpec = (IppFilterGaussianSpec *)ippMalloc(specSize);
                        Ipp8u * pBuffer = (Ipp8u*)ippMalloc(bufferSize);
    
                        if (ippiFilterGaussianInit(roiSize, (Ipp32u)ksize.width, (Ipp32f)sigma1, ippBorder, dataType, 1, pSpec, pBuffer) >= 0)
                        {
    #define IPP_FILTER_GAUSS(ippfavor, ippcn) \
            do \
            { \
                typedef Ipp##ippfavor ippType; \
                ippType borderValues[] = { 0, 0, 0 }; \
                IppStatus status = ippcn == 1 ? \
                    ippiFilterGaussianBorder_##ippfavor##_C1R(src.ptr<ippType>(), (int)src.step, \
                        dst.ptr<ippType>(), (int)dst.step, roiSize, borderValues[0], pSpec, pBuffer) : \
                    ippiFilterGaussianBorder_##ippfavor##_C3R(src.ptr<ippType>(), (int)src.step, \
                        dst.ptr<ippType>(), (int)dst.step, roiSize, borderValues, pSpec, pBuffer); \
                ippFree(pBuffer); \
                ippFree(pSpec); \
                if (status >= 0) \
                { \
                    CV_IMPL_ADD(CV_IMPL_IPP); \
                    return; \
                } \
            } while ((void)0, 0)
    
                            if (type == CV_8UC1)
                                IPP_FILTER_GAUSS(8u, 1);
                            else if (type == CV_8UC3)
                                IPP_FILTER_GAUSS(8u, 3);
                            else if (type == CV_16UC1)
                                IPP_FILTER_GAUSS(16u, 1);
                            else if (type == CV_16UC3)
                                IPP_FILTER_GAUSS(16u, 3);
                            else if (type == CV_16SC1)
                                IPP_FILTER_GAUSS(16s, 1);
                            else if (type == CV_16SC3)
                                IPP_FILTER_GAUSS(16s, 3);
                            else if (type == CV_32FC1)
                                IPP_FILTER_GAUSS(32f, 1);
                            else if (type == CV_32FC3)
                                IPP_FILTER_GAUSS(32f, 3);
    #undef IPP_FILTER_GAUSS
                        }
                    }
                    setIppErrorStatus();
                }
            }
        }
    #endif
    	//创建高斯内核函数
        Mat kx, ky;
    	//创建高斯内核函数
        createGaussianKernels(kx, ky, type, ksize, sigma1, sigma2);
    	//_src是源影像
    	//_dst是目标影像
    	//CV_MAT_DEPTH(type) 是CV_8U或者CV_16U
    	//kx是滤波内核
    	//ky是滤波内核
    	//
        sepFilter2D(_src, _dst, CV_MAT_DEPTH(type), kx, ky, Point(-1,-1), 0, borderType );
    }
    static void createGaussianKernels( Mat & kx, Mat & ky, int type, Size ksize,
                                       double sigma1, double sigma2 )
    {
        int depth = CV_MAT_DEPTH(type);//获取影像的深度 CV_8U、CV_16U...
        if( sigma2 <= 0 )
            sigma2 = sigma1;//如果sigma2小于0的话,那么sigma2和sigma相同
    
        // automatic detection of kernel size from sigma
    	//自动决定sigma的大小
        if( ksize.width <= 0 && sigma1 > 0 )//如果内核的宽度小于0并且sigma1大于的0的话
    		//如果数据类型为CV_8U的话 那么宽度大小为
    		//(sigmal*3*2+1)|1 
    		//'|'的操作原因是内核的宽度必须是奇数
            ksize.width = cvRound(sigma1*(depth == CV_8U ? 3 : 4)*2 + 1)|1;
        if( ksize.height <= 0 && sigma2 > 0 )//和内核的宽度获取是相同的
            ksize.height = cvRound(sigma2*(depth == CV_8U ? 3 : 4)*2 + 1)|1;
    
    	//内核的宽度必须大于0,并且是奇数的。
    	//内核的高度也是相同的
        CV_Assert( ksize.width > 0 && ksize.width % 2 == 1 &&
            ksize.height > 0 && ksize.height % 2 == 1 );
    
    	//sigma值是大于等于0的
        sigma1 = std::max( sigma1, 0. );
        sigma2 = std::max( sigma2, 0. );
    
    	//获取x方向的高斯内核
        kx = getGaussianKernel( ksize.width, sigma1, std::max(depth, CV_32F) );
    	//如果内核的宽度和高度相同,并且sigma1和sigma2几乎相同的话,那么就是使用x方向的内核
        if( ksize.height == ksize.width && std::abs(sigma1 - sigma2) < DBL_EPSILON )
            ky = kx;
        else
            ky = getGaussianKernel( ksize.height, sigma2, std::max(depth, CV_32F) );
    }
    cv::Mat cv::getGaussianKernel( int n, double sigma, int ktype )
    {
        const int SMALL_GAUSSIAN_SIZE = 7;
        static const float small_gaussian_tab[][SMALL_GAUSSIAN_SIZE] =
        {
            {1.f},//内核大小为1
            {0.25f, 0.5f, 0.25f},//内核大小为3
            {0.0625f, 0.25f, 0.375f, 0.25f, 0.0625f},//内核大小为5
            {0.03125f, 0.109375f, 0.21875f, 0.28125f, 0.21875f, 0.109375f, 0.03125f}//内核大小为7
        };
    
    	//如果sigma小于0的话,那么内核数组规则为
    	//1、奇数
    	//2、小于等于7
    	//3、sigma 小于等于0
    	//n>>1 就是n/2
        const float* fixed_kernel = n % 2 == 1 && n <= SMALL_GAUSSIAN_SIZE && sigma <= 0 ?
            small_gaussian_tab[n>>1] : 0;
    
    	//断言,数据类型必须为CV_32F 或者CV_64F,也就是float或者double类型
        CV_Assert( ktype == CV_32F || ktype == CV_64F );
    	//内核矩阵为n行1列
        Mat kernel(n, 1, ktype);
    	//获取内核数据的指针,分别指向float或者double类型
        float* cf = kernel.ptr<float>();
        double* cd = kernel.ptr<double>();
    
    	//如果sigma是大于0的话,就是sigma的大小
    	//如果sigma小于等于0的话,就是默认的大小
    
        double sigmaX = sigma > 0 ? sigma : ((n-1)*0.5 - 1)*0.3 + 0.8;
    	//-sigma *sigmma/2
        double scale2X = -0.5/(sigmaX*sigmaX);
    	//求和,是为了进行归一化处理
        double sum = 0;
    
        int i;
    
        for( i = 0; i < n; i++ )
        {
            double x = i - (n-1)*0.5;//例子如果n为3的话,那么x的值分别为-1、0、1。如果是5的话,那么x的值为-2,-1,0,1,2
            double t = fixed_kernel ? (double)fixed_kernel[i] : std::exp(scale2X*x*x);
            if( ktype == CV_32F )
            {
                cf[i] = (float)t;
                sum += cf[i];
            }
            else
            {
                cd[i] = t;
                sum += cd[i];
            }
        }
    
        sum = 1./sum;
        for( i = 0; i < n; i++ )
        {
            if( ktype == CV_32F )
                cf[i] = (float)(cf[i]*sum);
            else
                cd[i] *= sum;
        }
    
        return kernel;
    }

     

     

     

    //包含OpenCV的头文件
    //参照github https://github.com/yoyoyo-yo/Gasyori100knock 
    #include <opencv2/opencv.hpp>
    #include <iostream>
    using namespace  std;
    //使用OpenCV的命名空间
    using namespace cv;
    //
    //频道改变
    int main()
    {
    	//读取源影像
    	Mat Src = imread("C:/Users/GuSheng/Desktop/标准测试图片/Fig0638(a)(lenna_RGB).tif", IMREAD_COLOR);
    	if (Src.empty())
    	{
    		return 0;
    	}
    	//创建目标影像,影像格式、大小和源影像相同
    	//sigma = 0.8
    	Mat Dst1 = Mat(Src.size(), Src.type());
    	//sigma = 1.5
    	Mat Dst2 = Mat(Src.size(), Src.type());
    	//创建目标影像失败
    	if (Dst1.empty() || Dst2.empty())
    	{
    		return 0;
    	}
    	GaussianBlur(Src, Dst1, cv::Size(5, 5), 0.8,0.8);
    	GaussianBlur(Src, Dst2, cv::Size(5, 5), 1.5, 1.5);
    	namedWindow("Src", WINDOW_AUTOSIZE);
    	namedWindow("Dst sigma = 0.8", WINDOW_AUTOSIZE);
    	namedWindow("Dst sigma = 1.5", WINDOW_AUTOSIZE);
    	imshow("Src", Src);
    	imshow("Dst sigma = 0.8", Dst1);
    	imshow("Dst sigma = 1.5", Dst2);
    	waitKey(0);
    	return 0;
    }
    源影像

                                   

    sigma = 0.8
    sigma = 1.5
    展开全文
  • OpenCV高斯模糊方法

    千次阅读 2016-08-17 19:04:06
    纯粹阅读,请移步OpenCV高斯模糊方法效果图源码KqwOpenCVBlurDemo步骤 将获取到的Bitmap图片转成Mat对象 // Bitmap转为Mat Mat src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4); Utils....

    纯粹阅读,请移步OpenCV高斯模糊方法

    效果图

    高斯模糊方法

    高斯模糊方法

    源码

    KqwOpenCVBlurDemo

    步骤

    1. 将获取到的Bitmap图片转成Mat对象
    // Bitmap转为Mat
    Mat src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4);
    Utils.bitmapToMat(bitmap, src);
    1. 调用OpenCV的高斯模糊方法
    // 高斯模糊方法
    Imgproc.GaussianBlur(src, src, new Size(91, 91), 0);
    1. 将处理完的Mat数据转成Bitmap对象
    // Mat转Bitmap
    Bitmap processedImage = Bitmap.createBitmap(src.cols(), src.rows(), Bitmap.Config.ARGB_8888);
    Utils.matToBitmap(src, processedImage);

    封装

    这里我用到了RxJava。主要是因为图片处理是耗时操作,会阻塞线程,为了防止界面卡顿,这里使用RxJava进行了线程切换。

    package kong.qingwei.kqwopencvblurdemo;
    
    import android.graphics.Bitmap;
    
    import org.opencv.android.Utils;
    import org.opencv.core.CvType;
    import org.opencv.core.Mat;
    import org.opencv.core.Size;
    import org.opencv.imgproc.Imgproc;
    
    import rx.Observable;
    import rx.Subscriber;
    import rx.android.schedulers.AndroidSchedulers;
    import rx.functions.Func1;
    import rx.schedulers.Schedulers;
    
    /**
     * Created by kqw on 2016/8/17.
     * 图片虚化的工具类
     */
    public class BlurUtil {
    
        private Subscriber<Bitmap> mSubscriber;
    
        public BlurUtil(Subscriber<Bitmap> subscriber) {
            mSubscriber = subscriber;
        }
    
        /**
         * 高斯模糊方法
         *
         * @param bitmap 要处理的图片
         */
        public void gaussianBlur(Bitmap bitmap) {
            // RxJava处理图片虚化
            if (null != mSubscriber)
                Observable
                        .just(bitmap)
                        .map(new Func1<Bitmap, Bitmap>() {
    
                            @Override
                            public Bitmap call(Bitmap bitmap) {
                                // Bitmap转为Mat
                                Mat src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4);
                                Utils.bitmapToMat(bitmap, src);
    
                                // 高斯模糊方法
                                Imgproc.GaussianBlur(src, src, new Size(91, 91), 0);
    
                                // Mat转Bitmap
                                Bitmap processedImage = Bitmap.createBitmap(src.cols(), src.rows(), Bitmap.Config.ARGB_8888);
                                Utils.matToBitmap(src, processedImage);
    
                                return processedImage;
                            }
                        })
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(mSubscriber);
        }
    }

    工具类的初始化

    图片处理在子线程处理,处理完通过回调返回。

    // 图片模糊处理的工具类
    mBlurUtil = new BlurUtil(new Subscriber<Bitmap>() {
        @Override
        public void onCompleted() {
            // 图片处理完成
            dismissProgressDialog();
        }
    
        @Override
        public void onError(Throwable e) {
            // 图片处理异常
            dismissProgressDialog();
        }
    
        @Override
        public void onNext(Bitmap bitmap) {
            // 获取到处理后的图片
            mIvImageProcessed.setImageBitmap(bitmap);
        }
    });

    图片模糊处理

    // 高斯模糊算法处理图片
    mBlurUtil.gaussianBlur(mSelectImage);
    展开全文
  • OpenCV 高斯模糊函数的调用测试1.图片读入,彩色转灰度2.计算第一次高斯模糊3.计算第二次高斯模糊4.计算两次高斯模糊的差5.结果归一化 1.图片读入,彩色转灰度 2.计算第一次高斯模糊 3.计算第二次高斯模糊 4.计算...

    1.图片读入,彩色转灰度

    在这里插入图片描述

    2.计算第一次高斯模糊

    在这里插入图片描述

    3.计算第二次高斯模糊

    在这里插入图片描述

    4.计算两次高斯模糊的差

    在这里插入图片描述

    5.结果归一化

    在这里插入图片描述

    	Mat src, dst;
    	src = imread("D:\\001.jpg");
    	if (!src.data)
    	{
    		printf("could not load data···");
    		return -1;
    	}
    	char INPUT_WIN[] = "input image";
    	char OUTPUT_WIN[] = "output image";
    	namedWindow(INPUT_WIN, WINDOW_AUTOSIZE);
    	namedWindow(OUTPUT_WIN, WINDOW_AUTOSIZE);
    	imshow(INPUT_WIN, src);
    	//DOG 高斯不同
    	Mat gray_src, g1, g2, dogImg;
    	cvtColor(src, gray_src, COLOR_BGR2GRAY);
    	GaussianBlur(gray_src, g1, Size(7, 7), 0, 0);
    	GaussianBlur(g1, g2, Size(7, 7), 0, 0);
    	subtract(g1, g2,dogImg, Mat());
    	normalize(dogImg, dogImg, 255, 0, NORM_MINMAX);
    	imshow(OUTPUT_WIN, dogImg);
    
    展开全文
  • python+opencv 高斯模糊

    2020-01-31 18:49:59
    高斯模糊对高斯噪声有抑制作用 假设高斯函数是G(x),对于图像,假设高斯核是1*3的,则x是-1, 0,1,对应于G(-1),G(0)、G(1),sum=G(-1)+G(0)+G(1),则 G(-1)/sum + G(0)/sum + G(1)/sum = 1 import cv2 as cv ...
  • 在 Python 中使用 OpenCV 高斯模糊我这张的丑脸

    千次阅读 多人点赞 2021-06-06 14:00:08
    在本篇博客中,你将学习如何使用 Python 中的 OpenCV模糊图像和视频中的人脸。 为了模糊图像中显示的人脸,首先检测这些人脸及其在图像中的位置。对此,查看之前的一篇关于人脸检测的教程,在这里使用人脸检测的...
  • Opencv 高斯模糊 Gaussian Blur ()

    千次阅读 2018-01-24 14:23:41
    高斯模糊原理的图解(2张) 右图中,2是中间点,周边点都是1。 "中间点"取"周围点"的平均值,就会变成1。在数值上,这是一种"平滑化"。在图形上,就相当于产生"模糊"效果,"中间点"失去细节。 显然,计算平均值...
  • openCV 高斯模糊及原理

    千次阅读 2014-08-13 16:30:57
    // Example4.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "highgui.h" ...高斯模糊原理 http://www.ruanyifeng.com/blog/2012/11/gaussian_blur.html

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,023
精华内容 409
关键字:

opencv高斯模糊