2019-09-29 12:19:32 qq_38262266 阅读数 70
  • OpenCV3.2 Java图像处理视频学习教程

    OpenCV3.2 Java图像处理视频培训课程:基于OpenCV新版本3.2.0详细讲述Java OpenCV图像处理部分内容,包括Mat对象使用、图像读写、 基于常用核心API讲述基本原理、使用方法、参数、代码演示、图像处理思路与流程讲授。主要内容包括opencv像素操作、滤波、边缘提取、直线与圆检测、形态学操作与分水岭、图像金子塔融合重建、多尺度模板匹配、opencv人脸检测、OpenCV跟Tomcat使用实现服务器端图像处理服务。

    4102 人正在学习 去看看 贾志刚

 

2019-10-18 16:51:30 zbwgycm 阅读数 56
  • OpenCV3.2 Java图像处理视频学习教程

    OpenCV3.2 Java图像处理视频培训课程:基于OpenCV新版本3.2.0详细讲述Java OpenCV图像处理部分内容,包括Mat对象使用、图像读写、 基于常用核心API讲述基本原理、使用方法、参数、代码演示、图像处理思路与流程讲授。主要内容包括opencv像素操作、滤波、边缘提取、直线与圆检测、形态学操作与分水岭、图像金子塔融合重建、多尺度模板匹配、opencv人脸检测、OpenCV跟Tomcat使用实现服务器端图像处理服务。

    4102 人正在学习 去看看 贾志刚

Introduction

滤波是一个信号处理领域的概念。信息通过波的形式传递,滤波就是通过提取相应的频率成分,从而获取有用的信息。图像滤波也是如此。根据提取频率的成分不同,可以将滤波操作分为低通滤波、带通滤波和高通滤波。在图像处理领域,图像低通滤波,也就是图像平滑滤波,是最重要的方向之一。许多与图像相关的工作都需要使用图像滤波做预处理,而图像平滑滤波也广泛应用于图像去噪、图像增强、图像融合、立体视觉、HDR等各个领域。

图像平滑滤波从实现方式上来讲可以分为基于局部信息的滤波和基于全局优化的滤波。基于局部信息的滤波方式由于实现简单,速度一般较快,所以最常见到,如均值滤波、中值滤波、高斯滤波等等。由于这些滤波方式在平滑纹理和噪声的同时往往也会平滑边缘,所以后来一些保边滤波方式,如双边滤波、导向滤波被提出。而基于全局优化的滤波一般来说都是保边性滤波。下面主要按照这个分类介绍一下常见的滤波方式及其应用。

基于局部信息的滤波方式

均值滤波就是利用邻域像素点的平均值代替当前点的像素值。均值滤波可以使用积分图的方式进行加速,从而实现与滤波窗口大小无关的时间开销。而这也是成为对许多滤波器加速的基础,如导向滤波、快速中值滤波都是使用积分图来加速。均值滤波将邻域像素看作是平等的赋予相同的权重,高斯滤波则是根据距离远近依次权重递减。所以高斯滤波往往比均值滤波得到效果更加保持强边缘。中值滤波常用于滤除椒盐噪声,其利用邻域像素点的中值代替当前点的像素值。中值滤波也有较好的保边效果,也常用于立体视觉中视差图的优化。一种快速实现中值滤波的方式就是通过均值滤波实现对局部邻域的直方图统计,从而快速计算局部邻域中值。

上面提到高斯滤波通过距离当前像素点位置的远近来对邻域像素进行加权,而双边滤波则是在此基础上继续延伸,将邻域像素值与当前像素值的差异也作为权重,用两种权重进行加权平均,所以双边滤波是一种保边滤波器,在平滑小纹理和噪声的同时能够保持强边缘。由于双边滤波不同位置的滤波核不同,只能逐点计算,因此速度往往比较慢。有许多方法被提出用于对双边滤波加速,其中一种方法便是使用双边空间。其将像素值作为一个额外维度,使得权重的计算转变成在第三维度上的卷积,从而加快运算速度。这个概念被作者进一步延伸,便有了后来的Bilateral Guided Upsample和Google的HDRnet,有兴趣的可以参考这里。但双边滤波可以保持边缘但不能保持梯度,还会出现梯度翻转现象。

导向滤波来自于Closed-Form Matting,其主要基于局部线性模型假设,即在一个局部邻域中,输入图像qq可以用引导图II线性表出,即
qi=akIi+bk,iωkq_i=a_kI_i+b_k, \forall i \in \omega_k

以此可以利用最小二乘法建立优化方程,并对系数引入正则项约束(岭回归):
E(ak,bk)=iωk(akIi+bkqi)2+ϵak2E(a_k,b_k)=\sum_{i\in \omega_k} (a_kI_i+b_k-q_i)^2+\epsilon a^2_k

对该问题可以直接求解,得到aka_kbkb_k值与局部均值和局部协方差有关,因此可以使用快速均值滤波求解。导向滤波速度很快,而且也不会出现梯度翻转现象,因此无论在学术界还是在工业界都被广泛应用。但有时导向滤波得到的结果会在强边缘附近出现光晕现象(halo artifact)。具体介绍可以参考作者的PPT,还是讲的非常清楚的。另外,作者还提出了导向滤波的加速方式,基本的思想就是在低尺度上求解aka_kbkb_k,然后上采样回去求解平滑图像。

基于全局优化的滤波方式

这一类滤波都是通过建立全局优化方程,然后求解得到滤波结果。其与图像复原任务十分相似且密切相关。一般来说,其优化方程可以表达为:
E(x)=f(x,y)+p(x)E(x) = f(x,y)+p(x)

其由两部分组成,一个是保真项f(x,y)f(x,y),保持平滑后的图像与原图像结构相似;一个是先验项p(x)p(x),指导滤波后的图像应该服从什么分布。通常保真项采用L2L_2范数,不同的滤波方式的主要区别在于先验项的设计。图像平滑滤波常用是局部平滑先验,在梯度域对图像进行约束。详细可以参考这篇文章。常见到的如WLS filter,L1 filter, L0 filter,都是分别对梯度做L2L_2L1L_1L0L_0范数的约束。香港中文大学的Jiajia ya课题组在这个领域做的比较多,可以参考他的个人主页

总结

在不同的任务中,往往需求不同,这也造成了各种各样的滤波方式的出现。图像平滑滤波的方式有很多,其主要的研究方向在于如何实现更快的速度,如何在平滑纹理的同时更好地保持强边缘和结构。

2017-05-08 11:50:52 guduruyu 阅读数 12373
  • OpenCV3.2 Java图像处理视频学习教程

    OpenCV3.2 Java图像处理视频培训课程:基于OpenCV新版本3.2.0详细讲述Java OpenCV图像处理部分内容,包括Mat对象使用、图像读写、 基于常用核心API讲述基本原理、使用方法、参数、代码演示、图像处理思路与流程讲授。主要内容包括opencv像素操作、滤波、边缘提取、直线与圆检测、形态学操作与分水岭、图像金子塔融合重建、多尺度模板匹配、opencv人脸检测、OpenCV跟Tomcat使用实现服务器端图像处理服务。

    4102 人正在学习 去看看 贾志刚

在图像处理中,经常需要对图像进行平滑、锐化、边界增强等滤波处理。在使用PIL图像处理库时,我们通过Image类中的成员函数filter()来调用滤波函数对图像进行滤波,而滤波函数则通过ImageFilter类来定义的。

下面先直接看一个样例:

#-*- coding: UTF-8 -*-     
  
from PIL import Image
from PIL import ImageFilter

def image_filters_test():

    im = Image.open("lenna.jpg")

    #预定义的图像增强滤波器
    im_blur = im.filter(ImageFilter.BLUR)
    im_contour = im.filter(ImageFilter.CONTOUR)

    im_min = im.filter(ImageFilter.MinFilter(3))

    im.show()
    im_blur.show()
    im_contour.show()
    im_min.show()

    return



ImageFilter类中预定义了如下滤波方法:

• BLUR:模糊滤波

• CONTOUR:轮廓滤波

• DETAIL:细节滤波

• EDGE_ENHANCE:边界增强滤波

• EDGE_ENHANCE_MORE边界增强滤波(程度更深)

• EMBOSS:浮雕滤波

• FIND_EDGES:寻找边界滤波

• SMOOTH:平滑滤波

• SMOOTH_MORE:平滑滤波(程度更深)

• SHARPEN:锐化滤波

• GaussianBlur(radius=2):高斯模糊

>radius指定平滑半径。

• UnsharpMask(radius=2, percent=150, threshold=3):反锐化掩码滤波

>radius指定模糊半径;

>percent指定反锐化强度(百分比);

>threshold控制被锐化的最小亮度变化。

• Kernel(size, kernel, scale=None, offset=0):核滤波

当前版本只支持核大小为3x3和5x5的核大小,且图像格式为“L”和“RGB”的图像。

>size指定核大小(width, height);

>kernel指定核权值的序列;

>scale指定缩放因子;

>offset指定偏移量,如果使用,则将该值加到缩放后的结果上。

• RankFilter(size, rank):排序滤波

>size指定滤波核的大小

>rank指定选取排在第rank位的像素,若大小为0,则为最小值滤波;若大小为size * size / 2则为中值滤波;若大小为size * size - 1则为最大值滤波。

• MedianFilter(size=3):中值滤波

>size指定核的大小

• MinFilter(size=3):最小值滤波器

>size指定核的大小

• MaxFilter(size=3):最大值滤波器

>size指定核的大小

• ModeFilter(size=3):波形滤波器

选取核内出现频次最高的像素值作为该点像素值,仅出现一次或两次的像素将被忽略,若没有像素出现两次以上,则保留原像素值。

>size指定核的大小


上例的滤波处理结果如下




2017.05.08

2019-12-02 22:18:51 zjyang12345 阅读数 35
  • OpenCV3.2 Java图像处理视频学习教程

    OpenCV3.2 Java图像处理视频培训课程:基于OpenCV新版本3.2.0详细讲述Java OpenCV图像处理部分内容,包括Mat对象使用、图像读写、 基于常用核心API讲述基本原理、使用方法、参数、代码演示、图像处理思路与流程讲授。主要内容包括opencv像素操作、滤波、边缘提取、直线与圆检测、形态学操作与分水岭、图像金子塔融合重建、多尺度模板匹配、opencv人脸检测、OpenCV跟Tomcat使用实现服务器端图像处理服务。

    4102 人正在学习 去看看 贾志刚

一.均值滤波:

 

 

图片中一个方块区域(一般为3*3)内,中心点的像素为全部点像素值的平均值。均值滤波就是对于整张图片进行以上操作。

 

我们可以看下图的矩阵进行理解

 

缺陷:均值滤波本身存在着固有的缺陷,即它不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。

 

原图:

 

对比图:

 

 

 

  • 方框滤波

 

 

原理:当normalize=True时,与均值滤波结果相同, normalize=False,表示对加和后的结果不进行平均操作,大于255的使用255表示

用途:

非归一化(normalized=False)的方框滤波用于计算每个像素邻域内的积分特性,比如密集光流算法(dense optical flow algorithms)中用到的图像倒数的协方差矩阵(covariance matrices of image derivatives)

 

 

import cv2
from pylab import *

def BoxFilter(Imge,dim,dim2,flag):       #Image为待处理图像,dim为滤波器的大小dim*dim2
    im=array(Imge)
    #序列化
    sigema=0
    #滤波求和

    for i in range(int(dim/2), im.shape[0] - int(dim/2)):
        for j in range(int(dim2/2), im.shape[1] - int(dim2/2)):
            for a in range(-int(dim/2), -int(dim/2)+dim):
                for b in range(-int(dim2/2), -int(dim2/2)+dim2):
                    sigema = sigema + img[i + a, j + b]
                    #对于滤波范围内求和,从左到右,从上到下扫

            if(flag):
                im[i, j] = sigema / (dim*dim2)

            else:
                im[i,j]=min(sigema,255)
            #归一化则与均值滤波一致,不归一化的话超过255用255表示
            sigema = 0
            #滤波移动
    return im


img=cv2.imread('20170522171941388.png',0)
#读取图像
x=int(input("输入滤波长度:\n"))
y=int(input("输入滤波宽度:\n"))
flag=int(input("是否归一化(1/0)?\n"))

im=BoxFilter(img,x,y,flag)
#im= cv2.boxFilter(img, -1, (3, 3), normalize=False)
#im= cv2.blur(source, (3, 3))

#第一个为手写的方框滤波,第二个为opencv调包的方框滤波,第三个为调包的均值滤波

cv2.imshow('After',im)
cv2.imshow('Origin',img)
cv2.waitKey()
cv2.destroyAllWindows()
#显示结果

 

2017-12-01 16:27:44 weixin_37051000 阅读数 1890
  • OpenCV3.2 Java图像处理视频学习教程

    OpenCV3.2 Java图像处理视频培训课程:基于OpenCV新版本3.2.0详细讲述Java OpenCV图像处理部分内容,包括Mat对象使用、图像读写、 基于常用核心API讲述基本原理、使用方法、参数、代码演示、图像处理思路与流程讲授。主要内容包括opencv像素操作、滤波、边缘提取、直线与圆检测、形态学操作与分水岭、图像金子塔融合重建、多尺度模板匹配、opencv人脸检测、OpenCV跟Tomcat使用实现服务器端图像处理服务。

    4102 人正在学习 去看看 贾志刚

图像的频率域:图像像元灰度值随位置变化的空间频率,以频谱表示空间分布特征,如傅里叶变换将图片从空间域转向频率域,原图灰度突变区域、图像结构复杂区域,图像细节及干扰噪声等集中在高频区域,灰度变化平缓部分信号集中在低频区域。

空间域->频率域:可以通过傅里叶变换实现(当然还有DCT\DWT等等)
傅里叶同学告诉我们,任何周期函数,都可以看做是不同振幅、不同相位正弦波的叠加。
傅里叶变换告诉我们,非周期函数,曲线有限情况下,也可以用正弦和、余弦乘以加权函数的积分表示。

1)图像滤波
目的:突出图像的空间信息,压抑其他无关的信息,或者去除图像的某些信息,恢复其他的信息,因为,图像滤波也是一种图像增强的方法。
2)图像噪声
高斯噪声:噪声的像素值分布可以使用高斯概率密度来描述,0均值的高斯噪声指每个像素值中附加了0均值的,具有高斯概率密度的函数值
椒盐噪声:椒盐噪声随机改变了一些像素值,在二值图像上表现为使一些像素点变白,一些像素点变黑。
周期噪声:是一种空间依赖型噪声,噪声具有周期性
3)图像平滑
为了抑制噪声、改善图像质量所做的处理称为图像平滑。
线性:均值滤波是一种线性低通滤波器;中指滤波是一种非线性的平滑滤波器。
方法:均值滤波是取领域像素值的平均作为该像素的新值;中值滤波是将窗口内的所有像素值按大到小排序后,取中间值作为中心像素的新值。
效果:均值滤波造成图像模糊,对图像的边缘和细节削弱很多;中值滤波抑制噪声的同时还能有效地保留边缘,减少模糊。
4)同态滤波
同态滤波是减少低频增加高频,从而减少光照变化并锐化边缘或细节的图像滤波方法。

中值滤波C++代码

typedef unsigned char ElementType;
void TwodimenMediumFilterEdge(ElementType* signal,ElementType* result,int N,int M)
{
    if(!signal||N<1||M<1)
        return;

    ElementType* extension=new ElementType[(N+2)*(M+2)];//边缘处理,扩展矩阵
    if(!extension)//记得检查内存是否分配成功
        return;

    for(int i=0;i<M;i++)
    {
        memcpy(extension+(N+2)*(i+1)+1,signal+N*i, sizeof(ElementType)*N);
        extension[(N + 2) * (i + 1)] = signal[N * i];
        extension[(N + 2) * (i + 2) - 1] = signal[N * (i + 1) - 1];
    }

   memcpy(extension, extension + N + 2,(N + 2) * sizeof(ElementType));//填充第一行
   memcpy(extension + (N + 2) * (M + 1),extension + (N + 2) * M,(N + 2) * sizeof(ElementType));//填充最后一行

   MediumFilter2(extension, result ? result : signal, N + 2, M + 2);

   delete[] extension;//释放内存
}

void  MediumFilter2(ElementType* signal,ElementType* result,int N,int M)
{
   for (int m = 1; m < M - 1; ++m)//移动窗口
      for (int n = 1; n < N - 1; ++n)
      {

         int k = 0;
         ElementType window[9];//3*3窗口
         for (int j = m - 1; j < m + 2; ++j)
            for (int i = n - 1; i < n + 2; ++i)
               window[k++] = signal[j * N + i];

         for (int j = 0; j < 5; ++j)//排序
         {
            int min = j;
            for (int l = j + 1; l < 9; ++l)
            if (window[l] < window[min])
               min = l;

            const ElementType temp = window[j];
            window[j] = window[min];
            window[min] = temp;
         }

         result[(m - 1) * (N - 2) + n - 1] = window[4];
      }
}

参考资料:
http://blog.jobbole.com/70549/

没有更多推荐了,返回首页