数字图像处理--图像增强
图像锐化
学习地址
图像增强就是通过对图像的某些特征,如边缘、轮廓、对比度等,进行强调或尖锐化,使之更适合于人眼的观察或机器的处理的一种技术。
图像增强技术分为:
空间域增强方法,也即在图像平面中对图像的像素灰度值直接进行运算处理的方法。
频率域增强方法,是指在图像的频率域中对图像进行增强处理的方法。
空间域图像增强方法
逐像素点对图像进行增强的灰度变换方法;
通过全部或局部地改变图像的对比度进行图像增强的直方图增强处理方法;
利用模板或掩模对图像的邻域像素进行处理的空间运算方法。
窗切片也称为灰度切片,是一种提高图像中某个灰度级范围的亮度,使其变得比较突出的增强对比度的方法。
基本的实现方法包括两种:
◆ 一种是给所关心的灰度范围指定一个较高的灰度值,而给其它部分指定一个较低的灰度值或0值。
◆ 另一种是给所关心的灰度范围指定一个较高的灰度值,而其它部分的灰度值保持不变。
图像的直方图增强处理方法,就是一种通过改变图像的全部或局部对比度来进行图像增强的技术。
总结:
各种锐化算子的比较
可戳这里
several instances:
program1
imread函数有两个参数,第一个参数是图片路径,第二个参数表示读取图片的形式,有三种:
cv2.IMREAD_COLOR:加载彩色图片,这个是默认参数,可以直接写1。
cv2.IMREAD_GRAYSCALE:以灰度模式加载图片,可以直接写0。灰度模式加载的图片是单通道的。
cv2.IMREAD_UNCHANGED:包括alpha,可以直接写-1。
# -*- coding:utf-8
import cv2 as cv
import numpy as np
from matplotlib import pyplot as pltdef display(files):cv.namedWindow("imgs", 0)cv.resizeWindow("imgs",3*W,H)cv.imshow('imgs', np.hstack(files))if __name__ == '__main__':path = "/home/image/Pictures/lena256.jpg"img = cv.imread(path, 0)print(img.shape)#(256,256)灰度图就一个通道(H, W) = img.shapeimg1_1 = np.zeros((H,W),np.uint8)#无符号8位'''#所有像素值*1.2,有些*1.2之后就超过255了,因为类型是无符号8位,所以又相当于取模了,变成了低灰度值也就出现了图像的某些部分变成了黑色'''img1_1[:] = img[:] * 1.2img0_8 = np.zeros((H,W),np.uint8)img0_8[:] = img[:] * 0.8files =[img,img1_1,img0_8]display(files)cv.waitKey(0)cv.destroyAllWindows()# Local enhancementimg2_1 =np.zeros((H,W),np.uint8)for i in range(H):for j in range(W):if img[i,j] < 50:img2_1[i,j] = img[i,j]* 0.8elif img[i,j]> 180:x= img[i,j]*1.2if (x>256):img2_1[i, j] =255else:img2_1[i, j] =ximg2_2 =np.zeros((H,W),np.uint8)for i in range(H):for j in range(W):if img[i, j] < 80:img2_2[i, j] = img[i, j] *1.2elif (img[i, j] > 160):img2_2[i,j] =img[i,j]* 0.8files =[img,img2_1,img2_2]display(files)cv.waitKey(0)cv.destroyAllWindows()
运行结果:
(解释在注释中)
program2
窗切片操作
没啥好说的,看运行结果
# -*- coding:utf-8
import cv2 as cv
import numpy as npnames = "/home/image/Pictures/lena256.jpg"
img = cv.imread(names,0)
(H,W)=img.shape
Mida = 80
Midb = 160
weighta = 180
weightb = 55def display(files):cv.namedWindow("imgs", 0)cv.resizeWindow("imgs",4*H,W)cv.imshow('imgs', np.hstack(files))if __name__ == '__main__':img1 = np.zeros((H, W), np.uint8)img2 = np.zeros((H, W), np.uint8)img3 = np.zeros((H, W), np.uint8)for i in range(H):for j in range(W):if (img[i,j]>=Mida and img[i,j] <= Midb):img1[i,j] = weighta#180else:img1[i,j] = weightb#55for i in range(H):for j in range(W):if (img[i, j] >= Mida and img[i, j] <= Midb):img2[i, j] = weightaelse:img2[i, j] = 0for i in range(H):for j in range(W):if (img[i, j] >= Mida and img[i, j] <=Midb):img3[i, j] = weighta#180files = [img, img1, img2,img3]display(files)cv.waitKey(0)cv.destroyAllWindows()
运行结果:
program3
(1)cv.Laplacian()函数说明
cv.Laplacian是用来判断图像模糊度的。
dst = cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])
前两个是必须的参数:
第一个参数是需要处理的图像;
第二个参数是图像的深度,-1表示采用的是与原图像相同的深度。目标图像的深度必须大于等于原图像的深度;
其后是可选的参数:
dst不用解释了;
ksize是算子的大小,必须为1、3、5、7。默认为1。
scale是缩放导数的比例常数,默认情况下没有伸缩系数;
delta是一个可选的增量,将会加到最终的dst中,同样,默认情况下没有额外的值加到dst中;
borderType是判断图像边界的模式。这个参数默认值为cv2.BORDER_DEFAULT。
(2)cv.Sobel函数说明
Sobel算子依然是一种过滤器,只是其是带有方向的。
dst = cv2.Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]])
函数返回其处理结果。
前四个是必须的参数:
- 第一个参数是需要处理的图像;
- 第二个参数是图像的深度,-1表示采用的是与原图像相同的深度。目标图像的深度必须大于等于原图像的深度;
- dx和dy表示的是求导的阶数,0表示这个方向上没有求导,一般为0、1、2。
其后是可选的参数:
- dst不用解释了;
- ksize是Sobel算子的大小,必须为1、3、5、7。
- scale是缩放导数的比例常数,默认情况下没有伸缩系数;
- delta是一个可选的增量,将会加到最终的dst中,同样,默认情况下没有额外的值加到dst中;
- borderType是判断图像边界的模式。这个参数默认值为cv2.BORDER_DEFAULT。
(3)np.absolute: 计算绝对值,np.absolute(a) 或者 np.abs(a),对于非复数的数组,np.fabs 速度更快
(4)四个按位操作函数
bitwise_and是对二进制数据进行“与”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“与”操作,1&1=1,1&0=0,0&1=0,0&0=0
bitwise_or是对二进制数据进行“或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“或”操作,1|1=1,1|0=1,0|1=1,0|0=0
bitwise_xor是对二进制数据进行“异或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“异或”操作,1^1=0,1^0=1,0^1=1,0^0=0
bitwise_not是对二进制数据进行“非”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“非”操作,~1=0,~0=1
(5)cv.Canny函数说明
edges=cv.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]])
必要参数:
第一个参数是需要处理的原图像,该图像必须为单通道的灰度图;
第二个参数是阈值1;
第三个参数是阈值2。
关于2个阈值参数:
- 低于阈值1的像素点会被认为不是边缘;
- 高于阈值2的像素点会被认为是边缘;
- 在阈值1和阈值2之间的像素点,若与第2步得到的边缘像素点相邻,则被认为是边缘,否则被认为不是边缘。
其中较大的阈值2用于检测图像中明显的边缘,但一般情况下检测的效果不会那么完美,边缘检测出来是断断续续的。所以这时候用较小的第一个阈值用于将这些间断的边缘连接起来。
可选参数中apertureSize就是Sobel算子的大小。而L2gradient参数是一个布尔值,如果为真,则使用更精确的L2范数进行计算(即两个方向的倒数的平方和再开放),否则使用L1范数(直接将两个方向导数的绝对值相加)。
函数返回一副二值图,其中包含检测出的边缘。
# -*- coding:utf-8import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
path ="/home/image/Pictures/lena300.jpg"
img = cv.imread(path,0)
(H,W) = img.shape
print (H,W)def dis(files,titles):lens = files.__len__()rows = lens /2for i in range(lens):plt.subplot(2, rows, i + 1)plt.imshow(files[i],cmap='gray')plt.xticks([]), plt.yticks([])plt.title(titles[i])plt.show()def laplacian(img):#拉普拉斯算子lap = cv.Laplacian(img,cv.CV_8U)return lapdef soble(img):sx = cv.Sobel(img,cv.CV_8U,1,0)#参数1,0为只在x方向上求一阶导数,最大可以求二阶导数sy = cv.Sobel(img,cv.CV_8U,0,1)#参数0,1为只在y方向上求一阶导数,最大可以求二阶导数sx = np.uint8(np.absolute(sx))sy = np.uint8(np.absolute(sy))sc = cv.bitwise_or(sx,sy)return sx,sy,scdef canny(img):cannyimg = cv.Canny(img,60,110)cannyimg = np.uint8(np.absolute(cannyimg))return cannyimgif __name__ == '__main__':lap = laplacian(img)sx,sy,sc = soble(img)cannimg = canny(img)files = [img,lap,sx,sy,sc,cannimg]titles=['Original','Laplacian','Sobel-x','Sobel-y','Sobel','Canny']dis(files,titles)
running consequence
homework
手动实现Sobel和Prewitt算子
注意Sobel和Prewitt算子需要最后进行叠加的模运算。
import cv2 as cv
import numpy as np
from matplotlib import pyplot as pltpath='/home/image/Pictures/lena300.jpg'
src=cv.imread(path,0)
(H,W)=src.shape'''
Gx Gy
-1 0 1 1 1 1
-1 0 1 0 0 0
-1 0 1 -1 -1 -1
'''
def Prewitt(src):tmp=np.zeros((src.shape),np.uint8)for i in range(1,H-1):for j in range(1,W-1):a11=src[i-1,j-1]a12=src[i,j-1]a13=src[i+1,j-1]a21 = src[i - 1, j ]a22 = src[i , j ]a23 = src[i + 1, j ]a31 = src[i - 1, j + 1]a32 = src[i , j + 1]a33 = src[i + 1, j + 1]x=(-1*a11+0*a12+1*a13-1*a21+0*a22+1*a23-1*a31+0*a32+1*a33)y=(1*a11+1*a12+1*a13+0*a21+0*a22+0*a23-1*a31-1*a32-1*a33)#tmp[i][j]=np.sqrt(x*x+y*y)tmp[i,j]=np.abs(x)+np.abs(y)return tmp'''
Gx Gy
-1 0 1 1 2 1
-2 0 2 0 0 0
-1 0 1 -1 -2 -1
'''
def Sobel(src):tmp=np.zeros((H,W),np.uint8)for i in range(1,H-1):for j in range(1,W-1):a11=src[i-1,j-1]a12=src[i,j-1]a13=src[i+1,j-1]a21 = src[i - 1, j ]a22 = src[i , j ]a23 = src[i + 1, j ]a31 = src[i - 1, j + 1]a32 = src[i , j + 1]a33 = src[i + 1, j + 1]x=(-1*a11+0*a12+1*a13-2*a21+0*a22+2*a23-1*a31+0*a32+1*a33)y=(1*a11+2*a12+1*a13+0*a21+0*a22+0*a23-1*a31-2*a32-1*a33)#tmp[i][j] = np.sqrt(x * x + y * y)tmp[i,j]=np.abs(x)+np.abs(y)return tmpdef display(files,names):'''plt.figure(figsize=(10, 10))for i in range(files.__len__()):plt.subplot(1,3,i+1)plt.title(names[i])plt.imshow(files[i],cmap='gray')plt.xticks([]),plt.yticks([])plt.show()'''cv.namedWindow('original_____Sobel_____Prewitt',cv.WINDOW_AUTOSIZE)#cv.resizeWindow('original_____Sobel_____Prewitt',3*W,H)cv.imshow('original_____Sobel_____Prewitt',np.hstack(files))cv.waitKey(0)cv.destroyAllWindows()if __name__=='__main__':sobel=Sobel(src)prewitt=Prewitt(src)files=[src,sobel,prewitt]names=['original','Sobel','Prewitt']display(files,names)
consequences
拉普拉斯算子
数学原理就不复制黏贴PPT了,没意思
直接利用拉普拉斯锐化模板锐化后的图像虽然边缘增强了,但图像中的背景信息却消失了。
为了既体现拉普拉斯锐化的处理结果,同时又能保持原图像的背景信息,通常利用拉普拉斯算子对图像进行增强的结果图像应是将原始图像和拉普拉斯图像(式4.46的结果)叠加在一起的结果。
边缘检测:
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
path ="/home/image/Pictures/lena300.jpg"
img = cv.imread(path,0)
(H,W) = img.shape
print (H,W)test=np.array([[1,2,3],[4,5,6],[7,8,9]])
print(test[0,1],test[2,0],test[2,1],test[2,2])def show(files,titles):lens = files.__len__()for i in range(lens):plt.subplot(1,3, i + 1)plt.imshow(files[i],cmap='gray')plt.xticks([]), plt.yticks([])plt.title(titles[i])plt.show()
def Laplace(H,W,img):#边缘识别算子#H1=np.mat([[0,1,0], H2 =[[1,1,1]# [1,-4,1], [1,-8,1]# [0,1,0]]) [1,1,1]]imgXYH1 = np.zeros((H,W),np.uint8)imgXYH2 = np.zeros((H,W),np.uint8)for i in range(1,H-2) :for j in range (1,W-2):a00 = np.int16(img[i - 1, j - 1])a01 = np.int16(img[i - 1, j])a02 = np.int16(img[i - 1, j + 1])a10 = np.int16(img[i, j - 1])a11 = np.int16(img[i, j])a12 = np.int16(img[i, j + 1])a20 = np.int16(img[i + 1, j - 1])a21 = np.int16(img[i + 1, j])a22 = np.int16(img[i + 1, j + 1])h1 = a10+a12+a01+a21-4*a11h2 = a10+a12+a01+a02+a00+a22+a21+a20 -8*a11if h1>255:h1=255elif h1<0:h1=0imgXYH1[i,j] = h1if h2 > 255:h2 = 255elif h2 < 0:h2 = 0imgXYH2[i,j] = h2files = [img, imgXYH1,imgXYH2]tiles = ['Original','H1 Template','H2 Template']show(files,tiles)
if __name__ == '__main__':Laplace(H,W,img)
锐化算子:
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
path ="/home/image/Pictures/lena300.jpg"
img = cv.imread(path,0)
(H,W) = img.shape
print (H,W)
def dis(files,titles):lens = files.__len__()for i in range(lens):plt.subplot(1,3, i + 1)plt.imshow(files[i],cmap='gray')plt.xticks([]), plt.yticks([])plt.title(titles[i])plt.show()
def Synthetic(H,W,img):#锐化算子# H6=np.mat([[0,-1,0], H9 =[[-1,-1,-1]# [-1,5,-1], [-1, 9 ,-1]# [0,-1,0]]) [-1,-1,-1]]imgXYH1 = np.zeros((H, W), np.uint8)imgXYH2 = np.zeros((H, W), np.uint8)for i in range(1, H - 2):for j in range(1, W - 2):a00 = np.int16(img[i - 1, j - 1])a01 = np.int16(img[i - 1, j])a02 = np.int16(img[i - 1, j + 1])a10 = np.int16(img[i, j - 1])a11 = np.int16(img[i, j])a12 = np.int16(img[i, j + 1])a20 = np.int16(img[i + 1, j - 1])a21 = np.int16(img[i + 1, j])a22 = np.int16(img[i + 1, j + 1])h1 = -a10 - a12 - a01 - a21 +5* a11h2 = -a10 - a12 - a01 - a02 - a00 - a22 - a21 - a20 + 9 * a11if h1 > 255:h1 = 255elif h1 < 0:h1 = 0imgXYH1[i, j] = h1if h2 > 255:h2 = 255elif h2 < 0:h2 = 0imgXYH2[i, j] = h2files = [img, imgXYH1, imgXYH2]tiles = ['Original', 'H6 Template', 'H9 Template']dis(files, tiles)
if __name__ == '__main__':Synthetic(H,W,img)
高斯拉普拉斯边缘检测(LOG)算子
Marr和Hildreth提出将Laplace算子与高斯低通滤波相结合,提出了LOG(Laplace and Guassian)算子。
Canny算子
Canny算子边缘检测的具体步骤如下:
1、用高斯滤波器平滑图像
2、用Sobel等梯度算子计算梯度幅值和方向
3、对梯度幅值进行非极大值抑制
4、用双阈值算法检测和连接边缘
作业:结合Laplacian算子和LOG算子计算方法,完成图像的增强和边缘提取。
运行结果:
Log float Template[[ 0.01203505 0.02356547 0.036579 0.036579 0.02356547][ 0.02356547 0.05074604 0.03160835 0.03160835 0.05074604][ 0.036579 0.03160835 -0.17711597 -0.17711597 0.03160835][ 0.036579 0.03160835 -0.17711597 -0.17711597 0.03160835][ 0.02356547 0.05074604 0.03160835 0.03160835 0.05074604]]
数字图像处理--图像增强相关推荐
- 数字图像处理--图像增强之对比度拉伸
我们前面提到过图像二值化,图像反转,本质上是对图像的所有像素点的灰度进行操作,属于灰度变换的内容.灰度变换的主要目的是用于图像增强. 而对比度拉伸是图像增强的一种方法,也属于灰度变换操作.我们看如下图 ...
- 【笔记】数字图像处理--图像增强(空间域+频率域)
前言 本篇文章仅作为博主学习笔记使用,各位小伙伴可以简单浏览大概了解一下图像增强方面的知识呀
- Matlab数字图像处理——图像处理工具箱Image Processing Toolbox
Image Processing Toolbox 图像处理工具箱包含的功能: 图像的读取和保存 图像的显示 创建GUI 图像的几何变换 图像滤波器设计及线性滤波 形态学图像处理 图像域变换 图像增强 ...
- Matlab数字图像处理——图像文件的读取
文章目录 一.Matlab中获取图像信息的函数 imfinfo 二.Matlab读取图像文件的函数 imread 三.Matlab保存图像文件的函数 imwrite 完整目录 一.Matlab中获取图 ...
- Matlab数字图像处理——图像的空间变换
Matlab空间变换函数 imtransform Matlab空间变换函数 imtransform 可以实现图像仿射变换(如 平移.旋转.剪切.缩放).投影变换, 该函数可与 maketform 配合 ...
- 数字图像处理——第三章 空间域图像增强(空间滤波)
文章目录 1. 空间滤波基础 2. 线性滤波器 2.1 平滑空间滤波器 2.2 锐化空间滤波器 2.2.1 基于一阶微分的图像增强--梯度法 2.2.2 基于二阶微分的图像增强--拉普拉斯算子 3. ...
- 数字图像处理——第三章 空间域图像增强(灰度变换和直方图处理)
文章目录 空间域图像增强 1. 背景知识 2. 基本灰度变换 2.1 图像反转 2.2 对数变换 2.3 幂次变换 2.4 分段线性变换函数 2.4.1 对比拉伸 2.4.2 灰度切割 2.4.3 位 ...
- 【数字图像处理】七.MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化详解
本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行讲解,主要通过MFC单文档视图实现显示BMP图像增强处理,包括图像普通平滑.高斯 ...
- 数字图像处理实验三图像增强
一.实验目的 (1)了解图像增强的目的及意义,加深对图像增强的 感性认识,巩固所学的图像增强的理论知识和相 关算法. (2)熟练掌握直方图均衡化和直方图规定化的计算过 程. (3)熟练掌握空域滤波中常 ...
最新文章
- AlexeyAB DarkNet YOLOv3框架解析与应用实践(一)
- 查看Linux的磁盘使用情况
- android 网络时区 错误,React native 安卓机器上调试代码报错:网络请求出错TypeError: Network request failed...
- Flume案例:模拟两个agent之间传递消息的场景
- centos7配置haproxy
- pause容器作用_Kubernetes学习之pause容器
- 对于华为,英特尔与微软表示继续提供支持;亚马逊亲证云计算服务出现宕机;中国移动5G套餐曝光,每月都含200G流量……...
- Laravel测试驱动开发--反向单元测试
- Spring核心技术原理-(2)-通过Web开发演进过程了解一下为什么要有Spring AOP?
- linux创建django项目,Ubuntu 16.04下配置Django项目
- Total Defense Anti-Virus – 免费6个月
- POJ 2777 Count Color (线段树区间修改 + 状态压缩)
- 神剧《切尔诺贝利》引发的技术思考:如何避免下一次核灾难?
- Linux版Silverlight - Moonlight宣布停止更新
- SpringMVC的乱码问题解决
- C++游戏编程教程(一)
- 学习Spring,这篇就够了
- 华为python673集_实现Redis Cluster并实现Python链接集群
- avahi服务的使用
- 智慧景区“数字孪生“三维可视化运营管理平台-景区“元宇宙”的数字
热门文章
- 统信UOS安装chromium
- JS中将 JSON 数据转换为 Excel 表格的详细步骤如下:
- 最新android 8手机,8月Android手机性能榜:堆料极限、各显身手
- 【词云】iOS如何实现词云
- java中switch的使用_Java中Switch用法示例
- 格式化字符串 - Formatter
- 雅达利linux模拟器,雅达利VCS主机将发售 用户可以自己制作游戏与应用!
- 如何理解count=count++,count的值不变
- 大厂面试官:关于校招,你必须知道的那些事和建议
- 图书-管理:《80/20定律》