图形数字处理作业
使用Python+OpenCV实现对图像的处理。
作业说明:
1.直方图均衡化
2.平滑滤波器(中值和均值)
3.锐化滤波器(一阶和二阶的差异)
一.直方图均衡化
1.简单说明:
通过改变图像的直方图来改变图像中各像素的灰度,主要用于增强动态范围偏小的图像的对比度.把原始图像的直方图变换为均匀分布(均衡)的形式,直方图均衡化是一种全局处理方式,它对处理的数据不加选择。
2.代码:
import cv2
import numpy as np
img = cv2.imread('caise2.jpg',1) #此图片是彩色图,名为caise2.jpg
(b,g,r) = cv2.split(img) #通道分解
bH = cv2.equalizeHist(b) #函数equalizeHist用来做直方图均衡化
gH = cv2.equalizeHist(g) #函数equalizeHist只支持单通道的灰度图
rH = cv2.equalizeHist(r) #彩色图要多通道分离成单通道,然后再合并成多通道
result = cv2.merge((bH,gH,rH),)#通道合成
res = np.hstack((img,result))
#cv2.imshow('dst',res)
cv2.imshow('caise1',res)
cv2.waitKey(0)
3.效果图对比
4.自我理解
通过上图可以看出,直方图均衡化让原本亮的图片变的更亮,所以直方图均衡化应该适用于图片整体偏亮或者偏暗的图像,因为它属于一种全局处理方式,对图片上的所有数据都不加选择的处理。
二.平滑滤波器(中值和均值)
1.简单说明:
两者都是一种降低噪声的平滑滤波器;中值滤波器:如果一个信号是平缓变化的,那么某一点的输出值可以用这点的某个大小的邻域内的所有值的统计中值来代替;均值滤波器:均值滤波器的主要应用是去除图像中的不相关细节,是指与滤波器的模板相比较小的像素区域,把邻域内的平均值赋给中心元素。
2.代码:
#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取图片
img = cv2.imread('huidu4.png')
#source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB),本身就是灰度,不需要变灰了。
#均值滤波
result = cv2.blur(img, (5,5))
#中值滤波
median = cv2.medianBlur(img,5)
#显示图形
titles = ['Source Image', 'Blur Image','medianBlur Image']
images = [img, result,median]
for i in range(3):
plt.subplot(1,3,i+1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
# 函数表示plt.subplot(1,3,i+1),1行3列,当前位置。
3.效果图对比
4.自我理解
通过上图的对比,可以看出均值滤波器的缺点是存在着边缘模糊的问题。而中值滤波做到既去除噪声又保护图像的边缘。
锐化滤波器(一阶梯度算子和二阶拉普拉斯算子)
1.简单说明:
梯度算子:首先通过一阶导数计算边缘强度,然后采用梯度的方向来对边缘的局部方向进行寻找。这里主要描述Sobel算子:图像中的边缘区域,像素值会发生“跳跃”,对这些像素求导,在其一阶导数在边缘位置为极值,这就是Sobel算子使用的原理——极值处就是边缘。拉普拉斯算子:基于二阶微分的算子,也称基于零交叉的算子,如果对像素值求二阶导数,会发现边缘处的导数值为0。
2.代码:
A:Sobel算子
#coding=utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("huidu10.jpg", 0)
x = cv2.Sobel(img,cv2.CV_16S,1,0)
y = cv2.Sobel(img,cv2.CV_16S,0,1) #求梯度Sobel()
absX = cv2.convertScaleAbs(x) # 转回uint8
absY = cv2.convertScaleAbs(y) #convertScaleAbs()用于实现对整个图像数组中的每一个元素实现虹膜增强效果
Result = cv2.addWeighted(absX,0.5,absY,0.5,0)#简单的图像融合addWeighted
##cv2.imshow("absX", absX)
##cv2.imshow("absY", absY)
titles = ['Source Image', 'Sobel Image']
images = [img, Result]
for i in range(2):
plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
##cv2.imshow("img", img)
##cv2.imshow("Result", dst) 这里选择同时显示图片。
cv2.waitKey(0)
cv2.destroyAllWindows()
B:Laplacian算子
#coding=utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("huidu10.jpg", 0)
gray_lap = cv2.Laplacian(img,cv2.CV_16S,ksize = 3)#Laplacian变换
Result = cv2.convertScaleAbs(gray_lap) #convertScaleAbs增强效果
titles = ['Source Image', 'laplacian Image']
images = [img, Result]
for i in range(2):
plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
##cv2.imshow('laplacian',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
3.效果图对比
4.自我理解
通过上图的对比,我感觉拉普拉斯算子的图片边缘更为明显一些,噪声较为明显。