资讯专栏INFORMATION COLUMN

图像处理?没有Python可不行

JaysonWang / 1443人阅读

摘要:如果为灰度图像则没有通道。也可以使用的形式,表示第二行,第三列,红色通道。对数调整用一行两列来展示图像另一个很有用的图像增强算法是直方图均衡化,能有效的改善图像。膨胀处理可以扩充边缘和填充空洞。

python作为简单高效又很强大的一门编程语言,对于图像的处理自然也是轻松拿下,scikit-image是python中处理图像的一个库,对大多数的图像处理算法进行了封装,用户只需调用相关的接口即可。

入门示例

首先使用pip安装skimage

pip install skimage

我们都知道,图像是由像素构成的,其中彩色图像还包括不同的通道,视频则是在图像的基础上加入时间变量而已。一张图就像是由像素点构成的表格一样,skimage正是基于此来进行图像的处理操作。具体来说,skimage使用numpy作为图像的数据类型,numpy不用多说,它可以让你在 Python 中使用向量和数学矩阵(有不了解的可以网上找找教程)。

我们首先来打开一张图片看看。

为了方便,我们使用skimage自带的一些图片,这些图片放在data模块下,使用data.导入即可。如果要打开本地文件夹下的图片,可以使用io模块下的imread方法,保存图片可以使用io.imsave。

from skimage import data, io
img = data.chelsea()
# 查看图片,使用io模块中的imshow方法
io.imshow(img)
# 保存图片
io.imsave("F:cat.jpg", img)

接下来进行一些简单的图像处理。

一张图片在skimage中表示为多维数组的形式,比如img[2:16, 1:10, 0]表示宽度上从第2个像素点到第16个像素点,高度上从1到10的像素点,红色通道。如果为灰度图像则没有通道。也可以使用img[2, 3, 0]的形式,表示第二行,第三列,红色通道。

使用.shape显示图片的信息。如果图片为彩色图片,显示为宽度像素值,高度像素值,通道。

print(img.shape)
(300, 451, 3)

我们可以只显示图片的某一个通道,其中红绿蓝三个通道分别用数字0,1,2表示。比如只显示红色通道:

R = img[:, :, 0]
io.imshow(R)

我们也可以通过只显示某部分像素区间来剪裁图像,比如:

img_c = img[80:180, 100:200, :]
io.imshow(img_c)

还可以通过控制像素把图像二值化,也就是把像素值转换为0,1的形式。

from skimage import color
img4 = data.chelsea()
# 将彩色图像转为灰度图像,用到color模块
img_gray = color.rgb2gray(img4)

# 拆包获得行列数
rows, cols = img_gray.shape

# 循环,如果像素值小于0.5为0,反之则为1。
for i in range(rows):
    for j in range(cols):
        if img_gray[i, j]<=0.5:
            img_gray[i, j] = 0
        else:
            img_gray[i, j] = 1
io.imshow(img_gray)

图像增强

作为图像处理的一个部分,图像增强用来改善图像的图像的质量,也就是让图片更好看。skimage提供了强大的函数支持。

比如通过灰度变换改变图片的对比度和亮度。常见的算法有伽马调整和和log对数调整,在此不深究具体的算法细节,会用即可。

这里使用到matplotlib包,这是python中的一个绘图工具,用来展示图像,绘制统计图等。

from skimage import exposure, img_as_float
import matplotlib.pyplot as plt

# 把图像的像素值转换为浮点数
imge5 = img_as_float(data.moon())

# 使用伽马调整
# 第二个参数控制亮度,大于1增强亮度,小于1降低。
gam1 = exposure.adjust_gamma(imge5, 2)


# 对数调整
log1 = exposure.adjust_log(imge5, 0.7)


# 用一行两列来展示图像
plt.subplot(1, 3, 1)
plt.imshow(imge5, plt.cm.gray)

plt.subplot(1, 3, 2)
plt.imshow(gam1, plt.cm.gray)

plt.subplot(1, 3, 3)
plt.imshow(log1, plt.cm.gray)

另一个很有用的图像增强算法是直方图均衡化,能有效的改善图像。直方图均衡化简单来说就是通过将直方图变为均匀分布的来改善对比度。直方图的横坐标代表某个像素,纵坐标代表该像素有多少个。

# 直方图均衡化
import matplotlib.pyplot as plt

img6 = data.moon()
# 指定绘制的大小
plt.figure("hist", figsize=(8, 8))

# 把图像的二维数组按行转为一维数组,这样才能绘制直方图
arr = img6.flatten()

plt.subplot(2,2,1)
plt.imshow(img6, plt.cm.gray)
plt.subplot(2,2,2)
# 绘制直方图
plt.hist(arr, bins=256, normed=1, edgecolor="None",facecolor="red")

# 对直方图进行均衡化
img_c = exposure.equalize_hist(img6)
arr_c = img_c.flatten()
plt.subplot(2,2,3)
plt.imshow(img_c, plt.cm.gray)
plt.subplot(2,2,4)
plt.hist(arr_c, bins=256, normed=1, edgecolor="None", facecolor="red")

plt.show()

可以明显的看出,经过直方图均衡化之后,图像质量改善了许多。

再一个图像增强中常用的算法就是各种滤波器,像平滑化滤波器,锐化滤波器等。这其中,平滑滤波器可以用来去除噪声和平滑化处理图像,具体使用到的滤波器为低通滤波和中值滤波。不过低通噪声去除噪声的同时也平滑化了边和尖锐的细节,中值滤波则不会。

除了低通还有高通,除了中值还有最大值,最小值,均值等滤波器,在此不多赘述,查官方手册即可。

滤波器相关的算法放在filter模块下,记得导入。

from skimage import filters
import skimage.morphology as sm
image6 = data.camera()
# 中值滤波
# 第二个参数代表滤波器的形状,disk代表平面圆形,当然还有什么正方形,矩形啥的
edges = filters.median(image6, sm.disk(5))

plt.subplot(1, 2, 1)
plt.imshow(image6, plt.cm.gray)

plt.subplot(1, 2, 2)
plt.imshow(edges, plt.cm.gray)

与平滑滤波器正好相反,锐化滤波器可以用来提取边缘,凸显某些标志,突出细节等。其中的算法包括各种算子,roberts算子,prewitt梯度算子等等,还有微分滤波器等。

比如使用sobel描述图像中物体的边缘。

img = color.rgb2gray(data.chelsea())
# 使用sobel算子
edges = filters.sobel(img)

plt.figure("img", figsize=(8,8))
plt.subplot(1,2,1)
plt.imshow(img, plt.cm.gray)
plt.subplot(1,2,2)
plt.title("sobel")
plt.imshow(edges, plt.cm.gray)
plt.show()

图像分割

图像分割主要就是进行特征提取,从而使别图像中的物体,比如给你一张满是苹果的照片,让你统计照片中一共有多少个苹果。数出来的可不算。这时候就要用到图像分割中的一些算法了。

介绍下阈值分割。阈值是什么意思,比如你有一堆苹果,为了区分出哪些是好苹果哪些是不好的,规定尺寸大于75的就是好的,这里的75就是阈值。简单来说,阈值分割就是利用图像中要提取的目标区域与其背景在灰度特性上的差异,把图像看作具有不同灰度级的两类区域(目标区域和背景区域)的组合,选取一个比较合理的阈值,产生二值图像。

看个例子。

img = color.rgb2gray(data.chelsea())
# 基于otsu阀值分割方法
thresh = filters.threshold_otsu(img)
dst = (img<=thresh)*1.0

plt.figure("img", figsize=(8,8))
plt.subplot(1,2,1)
plt.imshow(img, plt.cm.gray)
plt.subplot(1,2,2)
plt.title("otsu")
plt.imshow(dst, plt.cm.gray)
plt.show()

再说下形态学变换,形态学变换包括膨胀处理,腐蚀处理,开闭运算,白黑帽等。膨胀处理的意思是说检测图像中像素值为1的点,然后将它周围某个区域的像素都变为1。膨胀处理可以扩充边缘和填充空洞。

看个例子。

img = data.checkerboard()
# 设置结构元素为边长5的正方形
dst = sm.dilation(img, sm.square(5))
plt.figure("dilation", figsize=(8,8))
plt.subplot(1,2,1)
plt.imshow(img, plt.cm.gray)
plt.subplot(1,2,2)
plt.imshow(dst, plt.cm.gray)

腐蚀处理正好相反,检测图像中像素值为0的点,然后将它周围某个区域的像素都变为0。

img = data.checkerboard()
# 设置结构元素为边长5的正方形
dst = sm.erosion(img, sm.square(5))
plt.figure("dilation", figsize=(8,8))
plt.subplot(1,2,1)
plt.imshow(img, plt.cm.gray)
plt.subplot(1,2,2)
plt.imshow(dst, plt.cm.gray)

图像识别

在机器学习和深度学习的推动下,图像识别获得了很大的发展,识别率节节攀升。如今的图像识别都在用深度学习算法来进行,所以这部分就不细讲了。

skimage中有一些很有用的算法用来检测轮廓。比如使用霍夫圆来检测圆形,椭圆变换来检测椭圆等等。

import numpy as np
import matplotlib.pyplot as plt
from skimage import data, color,draw,transform,feature,util

image = util.img_as_ubyte(data.coins()[0:95, 70:370]) #裁剪原图片
edges =feature.canny(image, sigma=3, low_threshold=10, high_threshold=50) #检测canny边缘

fig, (ax0,ax1) = plt.subplots(1,2, figsize=(8, 5))

ax0.imshow(edges, cmap=plt.cm.gray)  #显示canny边缘
ax0.set_title("original iamge")

hough_radii = np.arange(15, 30, 2)  #半径范围
hough_res =transform.hough_circle(edges, hough_radii)  #圆变换 

centers = []  #保存中心点坐标
accums = []   #累积值
radii = []    #半径

for radius, h in zip(hough_radii, hough_res):
    #每一个半径值,取出其中两个圆
    num_peaks = 2
    peaks =feature.peak_local_max(h, num_peaks=num_peaks) #取出峰值
    centers.extend(peaks)
    accums.extend(h[peaks[:, 0], peaks[:, 1]])
    radii.extend([radius] * num_peaks)

#画出最接近的5个圆
image = color.gray2rgb(image)
for idx in np.argsort(accums)[::-1][:5]:
    center_x, center_y = centers[idx]
    radius = radii[idx]
    cx, cy =draw.circle_perimeter(center_y, center_x, radius)
    image[cy, cx] = (255,0,0)

ax1.imshow(image)
ax1.set_title("detected image")

这篇文章大致介绍了使用skimage库来进行图像处理的一些过程,各种算法的具体使用还是查看官方手册最为妥当。

本人才疏学浅,上文中难免有些错误,还请各位品评指正。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/44500.html

相关文章

  • ❤️爆肝十二万字《python从零到精通教程》,从零教你变大佬❤️(建议收藏)

    文章目录 强烈推荐系列教程,建议学起来!! 一.pycharm下载安装二.python下载安装三.pycharm上配置python四.配置镜像源让你下载嗖嗖的快4.1pycharm内部配置 4.2手动添加镜像源4.3永久配置镜像源 五.插件安装(比如汉化?)5.1自动补码神器第一款5.2汉化pycharm5.3其它插件 六.美女背景七.自定义脚本开头八、这个前言一定要看九、pyt...

    booster 评论0 收藏0
  • Python将被加入高考科目?你怎么看?

    摘要:浙江省教育厅基教处相关负责人也表示,目前为止,还没有接到下半年开始使用新教材的通知。人生苦短,赶紧用起吧,大潮来袭,还在等什么原文链接将被加入高考科目你怎么看原文链接开发者交流平台,没有办法放链接为了不侵权,把作者的公众号联系方式放在这里。 今天看到这样的一则新闻:不禁感叹,人工智能这股风来的太快,已经掀起全民学习Python的浪潮。 2017年中观察:看上去这个大纲内容基本是这样了,...

    Yujiaao 评论0 收藏0
  • Python-数据类型总结

    摘要:如果有一个值为真,立刻返回该值如果所有的值都为假,返回最后一个假值注意在布尔上下文中会一直进行表达式演算直到找到第一个真值,然后就会忽略剩余的比较值结合使用结合了前面的两种语法,推理即可。 一、介绍 按存储空间的占用分(从低到高):数字字符串集合:无序,即无序存索引相关信息元组:有序,需要存索引相关信息,不可变列表:有序,需要存索引相关信息,可变,需要处理数据的增删改字典:无序,需要存...

    Miracle 评论0 收藏0
  • Python指令库click的实际应用

      一、序言  接下来要详细介绍的click乃是以一种你也很熟识的方式去轻松玩cmd。cmd程序流程实质上是界定主要参数与处理主要参数,而解决参数逻辑性肯定是和所界定的主要参数相关联的。那可不可以用函数公式和装饰器来达到解决主要参数逻辑界定主要参数的联系呢?而click正好便是以这样的方式来所使用的。  本系列产品文章内容默认设置应用Python3做为编译器进行介绍。  若是你依然在应用Pytho...

    89542767 评论0 收藏0
  • Java Lambda 表达式(又名闭包 (Closure)/ 匿名函数 ) 笔记

    摘要:表达式又名闭包匿名函数笔记根据终于在中引入了表达式。函数式接口要介绍中表达式的实现,需要知道什么是函数式接口。但同样需要保证外部的自由变量不能在表达式中被改变。 Java Lambda 表达式(又名闭包 (Closure)/ 匿名函数 ) 笔记 根据 JSR 335, Java 终于在 Java 8 中引入了 Lambda 表达式。也称之为闭包或者匿名函数。 showImg(https...

    fou7 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<