图像增强 您所在的位置:网站首页 图像的空域处理优缺点 图像增强

图像增强

2024-07-01 22:11| 来源: 网络整理| 查看: 265

目录 一.空域滤波基础1.定义2.卷积理论3.空域滤波及滤波器的定义4.线性滤波器5.非线性滤波器 二.平滑滤波器1.主要用途2.设计3.中值滤波4.均值滤波5.方形滤波6.高斯滤波7.自适应中值滤波器8.双边滤波(bilateral filtering)

一.空域滤波基础 1.定义

空域滤波增强采用模板处理方法对图像进行滤波,去除图像噪声或增强图像的细节。

2.卷积理论

①卷积的离散表达式,基本上可以理解为模板运算的数学表达方式: 在这里插入图片描述 ②由此,卷积的冲击相应函数h(x,y),称为空域卷积模板。

3.空域滤波及滤波器的定义

使用空域模板进行的图像处理,被称为空域滤波。 模板本身被称为空域滤波器。 ①滤波器的分类 · 数学形态分类 在这里插入图片描述 · 处理效果分类

平滑滤波器;锐化滤波器。 4.线性滤波器

①定义 线性滤波器是线性系统和频域滤波概念在空域的自然延伸。其特征是结果像素值的计算由下列公式定义: 在这里插入图片描述 其中:wi i=1,2,…,n是模板的系数; zi i=1,2,…,n是被计算像素及其邻域像素的值。 ②分类 低通滤波器:平滑图像,去除噪音; 高通滤波器:边缘增强,边缘提取; 带通滤波器:删除特定频率,增强中很少用。

5.非线性滤波器

①定义 使用模板进行结果像素值的计算,结果值直接取决于像素邻域的值,而不使用乘积和的计算。 在这里插入图片描述 ②分类 中值滤波:平滑图像,去除噪音; 在这里插入图片描述 最大值滤波:寻找最亮点; 在这里插入图片描述 最小值滤波:寻找最暗点。 在这里插入图片描述

二.平滑滤波器 1.主要用途

①对大图像处理前,删去无用的细小细节; ②连接中断的线段和曲线; ③降低噪音; ④平滑处理,恢复过分锐化的图像; ⑤图像创意(阴影、软边、朦胧效果)。

2.设计

在这里插入图片描述

3.中值滤波

(1)原理 用模板区域内像素的中值,作为结果值: 在这里插入图片描述 (2)效果 强迫突出的亮点(暗点)更像它周围的值,以消除孤立的亮点(暗点)。 (3)算法实现 将模板区域内的像素排列,求出中值。 对于同值像素,连续排列后取中值。 (4)Opencv中的实现

void medianBlur(InputArray src, OutputArray dst, int kszie);

参数说明: ·src:InputArray类型的src,输入图像,Mat类的对象。该函数对通道是独立处理的,且可以处理1、3或4得到的Mat图像,但是待处理的图像深度应该是CV_8U,CV_16U、CV_32F,但对于较大孔径尺寸的图像,只能是CV_8U。 ·dst:OutputArray类型的dst,目标图像,需要和输入图像有相同的尺寸和类型。 ·ksize:int类型参数,孔径的线性尺寸,必须是大于1的奇数。

//中值滤波 Mat dst; medianBlur(noise, dst, 5); //5×5模板 imshow("中值滤波", dst);

在这里插入图片描述 (5)注意点 ①用n*n的中值滤波器去除那些相对于其邻域像素更亮或更暗,并且其区域小于滤波器区域一半的孤立像素集。 ②适合于滤除椒盐噪声和干扰脉冲,尤其适合于目标物体形状是块状的图像滤波。 ③具有丰富尖角几何结构的图像,一般采用十字形滤波窗,且窗口大小最好不要超过图像中最小目标物的尺寸,否则会丢失目标物的细小几何特征。 ④需要保持细线状及尖顶角目标细节时,最好不要采用中值滤波。 (6)Python实现

def middle_filter(img, size): """ 中值滤波器 :param img: :param size: :return: """ rows, cols, channels = img.shape # 扩充图像 pad = int((size - 1) / 2) dst = np.zeros((rows + 2 * pad, cols + 2 * pad, channels), np.uint8) dst[pad:pad + rows, pad:pad + cols] = img.copy() out = dst.copy() for i in range(rows): for j in range(cols): dst[pad + i, pad + j, 0] = np.median(out[i:i + size, j:j + size, 0]) dst[pad + i, pad + j, 1] = np.median(out[i:i + size, j:j + size, 1]) dst[pad + i, pad + j, 2] = np.median(out[i:i + size, j:j + size, 2]) dst = dst[pad:pad + rows, pad:pad + cols] return dst 4.均值滤波

(1)原理 均值滤波也称为线性滤波,其采用的主要方法为邻域平均法。 线性滤波的基本原理是用均值代替原图像中的各个像素值,即对待处理的当前像素点(x,y),选择一个模板,该模板由其近邻的若干像素组成,求模板中所有像素的均值,再把该均值赋予当前像素点(x,y),作为处理后图像在该点上的灰度g(x,y),即g(x,y)=∑f(x,y)/m,m为该模板中包含当前像素在内的像素总个数。 在这里插入图片描述 (2)缺点 存在边缘模糊的问题。 (3)OpenCV中的实现

void blur(InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT )

参数说明: ·src:InputArray类型的src,输入图像,Mat类的对象。该函数对通道是独立处理的,且可以处理1、3或4得到的Mat图像,但是待处理的图像深度应该是CV_8U,CV_16U、CV_32F、CV_16S、CV_64F。 ·dst:OutputArray类型的dst,目标图像,需要和输入图像有相同的尺寸和类型。 ·ksize:Size类型的ksize,内核的大小。一般这样写Size(w,h)来表示内核的大小(其中,w为像素宽度,h为像素高度);Size(3,3)就表示3*3的核大小。 ·anchor:Point类型的anchor,表示锚点(即被平滑的那个点),默认值为Point(-1,-1);如果这个点坐标是负值的话,就表示取核的中心为锚点,所以默认值Point(-1,-1)表示这个锚点在核的中心。 ·borderType:int类型,用于推断图像外部像素的某种边界模式;默认值为BORDER_DEFAULT,一般不去管它。

//均值滤波 Mat dst; blur(src, dst, Size(5, 5)); imshow("均值滤波--blur", dst);

在这里插入图片描述

(4)C++实现

/*邻域平均法平滑*/ void smooth(Mat& src, Mat& dst, Size wsize) { //窗口大小,需为奇数 if (wsize.height % 2 == 0 || wsize.width % 2 == 0) { fprintf(stderr, "Please enter odd size"); exit(-1); } int hh = (wsize.height - 1) / 2; int hw = (wsize.width - 1) / 2; Mat newsrc; //扩充图片的边缘 copyMakeBorder(src, newsrc, hh, hh, hw, hw, BORDER_REFLECT_101); //以边缘为轴,对称 dst.create(src.size(), src.type()); //均值滤波 int sum = 0, sumr = 0, sumg = 0, sumb = 0; int mean = 0, meanr = 0, meang = 0, meanb = 0; for (int i = hh; i if (src.channels() == 1) //灰度图像 { for (int r = i - hh; r sum = newsrc.at(r, c) + sum; } } mean = sum / (wsize.area()); dst.at(i - hh, j - hw) = mean; sum = 0; mean = 0; } else //彩色图像 { for (int r = i - hh; r sumb = newsrc.at(r, c)[0] + sumb; sumg = newsrc.at(r, c)[1] + sumg; sumr = newsrc.at(r, c)[2] + sumr; } } meanb = sumb / (wsize.area()); meang = sumg / (wsize.area()); meanr = sumr / (wsize.area()); dst.at(i - hh, j - hw)[0] = meanb; dst.at(i - hh, j - hw)[1] = meang; dst.at(i - hh, j - hw)[2] = meanr; sumr = 0, sumg = 0, sumb = 0; meanr = 0, meang = 0, meanb = 0; } } } }

在这里插入图片描述 这里发现图像变暗,猜测是因为不同通道选取的中值为不同像素点的,故最后融合后图像的色彩效果不好,整体亮度变暗。 (5)Python实现(以下代码为彩色图像的实现)

def mean_filter(img, size): """ 均值滤波器 :param img:输入图片 :param size:滤波器窗口大小 :return: """ rows, cols, channels = img.shape # 扩充图像 pad = int((size - 1) / 2) dst = np.zeros((rows + 2 * pad, cols + 2 * pad, channels), np.uint8) dst[pad:pad + rows, pad:pad + cols] = img.copy() out = dst.copy() for i in range(rows): for j in range(cols): dst[pad + i, pad + j, 0] = np.sum(out[i:i + size, j:j + size, 0]) / (size * size) dst[pad + i, pad + j, 1] = np.sum(out[i:i + size, j:j + size, 1]) / (size * size) dst[pad + i, pad + j, 2] = np.sum(out[i:i + size, j:j + size, 2]) / (size * size) dst = dst[pad:pad + rows, pad:pad + cols] return dst

在这里插入图片描述

5.方形滤波

(1)原理 方形滤波器是一种矩形的且滤波器中的所有值全部相等。 在这里插入图片描述 (2)OpenCV中的实现

CV_EXPORTS_W void boxFilter( InputArray src, OutputArray dst, int ddepth, Size ksize, Point anchor = Point(-1,-1), bool normalize = true, int borderType = BORDER_DEFAULT );

参数说明: ·src:输入图像,Mat类的对象。 ·dst:目标图像,需要和源图像有一样的尺寸和类型。 ·ddepth:输出图像的深度,-1代表使用源图像深度,即src.depth()。 ·ksize:Size类型,内核的大小。 ·anchor:Point类型的anchor,表示锚点,即被平滑的那个点,默认值Point(-1,-1),表示这个锚点在该核的中心。 ·normalize:bool类型,默认值是true,表示内核是否被其区域归一化了。 ·borderType:int类型,用于推断图像外部像素的某种边界模式,默认值BORDER_DEFAULT,一般不去管它。

//方形滤波 Mat dst6; boxFilter(noise, dst6, -1, Size(5, 5), Point(-1, -1),true);

在这里插入图片描述

6.高斯滤波

(1)原理 ①一维高斯分布函数: 在这里插入图片描述 ②二维高斯分布函数: 在这里插入图片描述 在这里插入图片描述

③高斯滤波和均值滤波一样,都是利用一个掩膜和图像进行卷积求解。 不同之处在于:均值滤波器的模板系数都是相同的,为1; 而高斯滤波器的模板系数,随着距离模板中心距离的增大,系数减小(服从二维高斯分布)。 所以,高斯滤波器相比于均值滤波器而言,对图形模糊程度较小,更能保持图像的整体细节。

④对二维高斯分布函数的说明: ·(x,y):掩膜内任一点的坐标; ·(x0,y0):掩膜内中心点的坐标; ·σ:标准差。 ⑤模板样例: 在这里插入图片描述 ·对于整数形式的模板,需要进行归一化处理,将模板左上角的值归一化为1。 ·使用整数模板时,需要在模板的前面加一个系数,系数为模板中元素和的倒数。 ⑥标准差σ的意义及选取 ·标准差代表着数据的离散程度; ·如果σ较小,那么生成的模板的中心系数较大,而周围的系数较小,这样对图像的平滑效果就不是很明显; ·如果σ较大,则生成的模板的各个系数相差就不是很大,比较类似均值模板,对图像的平滑效果比较明显。 ·高斯分布的概率分布密度图: 在这里插入图片描述 可以看到:σ越小分布越高瘦,σ越大分布越矮胖。 ·由于图像的长宽可能不是滤波器大小的整数倍,因此我们需要在图像的边缘补0,这种方法叫做zero padding。 (2)OpenCv中的实现

void GaussianBlur( InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT )

参数说明: ·src:输入图像; ·dst:输出图像,大小和类型与src相同; ·ksize:高斯核大小,必须为正奇数; ·sigmaX:X方向上的高斯核标准差; ·sigmaY:Y方向上的高斯核标准差,如果sigmaY为零,则将其设置为等于sigmaX,如果sigmaX和sigmaY均为零,则分 别根据ksize.width个ksize.height进行计算; ·borderType:int类型,用于推断图像外部像素的某种边界模式,默认值BORDER_DEFAULT,一般不去管它。 ·

//高斯滤波 Mat dst7; GaussianBlur(noise, dst7, Size(5, 5), 0.8, 0.8);

(3)C++实现

//x,y方向联合实现获取高斯模板 void generateGaussMask(Mat& Mask, Size wsize, double sigma) { Mask.create(wsize, CV_64F); int h = wsize.height; int w = wsize.width; int center_h = (h - 1) / 2; int center_w = (w - 1) / 2; double sum = 0.0; double x, y; for (int i = 0; i x = pow(j - center_w, 2); double g = exp(-(x + y) / (2 * sigma * sigma)); Mask.at(i, j) = g; sum += g; } } Mask = Mask / sum; } void Gauss_Filter(Mat& src, Mat& dst, Mat window) { int hh = (window.rows - 1) / 2; int hw = (window.cols - 1) / 2; dst.create(src.size(), src.type()); //边界填充 Mat Newsrc; copyMakeBorder(src, Newsrc, hh, hh, hw, hw, BORDER_REPLICATE); //边界复制 //高斯滤波 for (int i = hh; i double sum[3] = { 0 }; for (int r = -hh; r if (src.channels() == 1) { sum[0] = sum[0] + Newsrc.at(i + r, j + c) * window.at(r + hh, c + hw); } else { Vec3b rgb = Newsrc.at(i + r, j + c); sum[0] = sum[0] + rgb[0] * window.at(r + hh, c + hw); sum[1] = sum[1] + rgb[1] * window.at(r + hh, c + hw); sum[2] = sum[2] + rgb[2] * window.at(r + hh, c + hw); } } } for (int k = 0; k sum[k] = 0; } else if (sum[k] > 255) { sum[k] = 255; } } if (src.channels() == 1) { dst.at(i - hh, j - hw) = static_cast(sum[0]); } else { Vec3b rgb = { static_cast(sum[0]),static_cast(sum[1]),static_cast(sum[2]) }; dst.at(i - hh, j - hw) = rgb; } } } }

(4)Python实现

def gaussian_filter(img, size, sigma): """ 高斯滤波 :param img: 输入图像 :param size: 窗口大小 :param sigma: 标准差 :return: """ rows, cols, channels = img.shape # zero padding pad = int((size - 1) / 2) dst = np.zeros((rows + pad * 2, cols + pad * 2, channels), np.float32) dst[pad:pad + rows, pad:pad + cols] = img.copy().astype(np.float32) kernel = np.zeros((size, size), np.float32) for i in range(-pad, -pad + size): for j in range(-pad, -pad + size): kernel[j + pad, i + pad] = np.exp(-(i ** 2 + j ** 2) / (2 * (sigma ** 2))) kernel = kernel / (2 * np.pi * sigma * sigma) kernel = kernel / kernel.sum() out = dst.copy() # filter for i in range(rows): for j in range(cols): dst[pad + i, pad + j, 0] = np.sum(kernel * out[i:i + size, j:j + size, 0]) dst[pad + i, pad + j, 1] = np.sum(kernel * out[i:i + size, j:j + size, 1]) dst[pad + i, pad + j, 2] = np.sum(kernel * out[i:i + size, j:j + size, 2]) dst = np.clip(dst, 0, 255) dst = dst[pad:pad + rows, pad:pad + cols].astype(np.uint8) return dst

·椒盐噪声: 在这里插入图片描述 ·高斯噪声: 在这里插入图片描述

7.自适应中值滤波器

(1)原理 ①自适应中值滤波器:根据预先设定好的条件,在滤波过程中,动态地改变滤波器的窗口尺寸大小,还会根据一定条件判断当前像素是不是噪声,如果是则用邻域中值替换掉当前像素,不是则不做改变。 ②相关符号:

· Zmin=Sxy中的最小灰度值; · Zmax=Sxy中的最大灰度值; · Zmed=Sxy中的灰度值的中值; · Zxy表示坐标(x,y)处的灰度值; ·Smax=Sxy允许的最大窗口尺寸。

③两个处理过程,分别记为A和B:

A: A1=Zmed-Zmin A2=Zmed-Zmax 如果A1>0且A20且B2



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有