Python cv2(OpenCV) 图像处理

OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效,由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。OpenCV用C++语言编写,它具有C ++,Python,Java和MATLAB接口,并支持Windows,Linux,Android和Mac OS,OpenCV主要倾向于实时视觉应用,并在可用时利用MMX和SSE指令, 如今也提供对于C#、Ch、Ruby,GO的支持。本文主要介绍Python 中使用cv2(Opencv) 进行图像处理的方法及示例代码。

1、使用cv2(Opencv)图像基本操作

参考文档Python cv2(Opencv) 图像基本操作

2、灰度图

灰度图,Gray Scale Image 或是Grey Scale Image,又称灰阶图。把白色与黑色之间按对数关系分为若干等级,称为灰度。灰度分为256阶。灰度是指黑白图像中的颜色深度,范围一般0-255,白色为255,黑色为0,故黑白图片也称为灰度图像。

HSV包括:

H:色调(主波长)。
S:饱和度(纯度/颜色的阴影)。
V:强度

代码如下,

import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB

img=cv2.imread('cjavapy.jpg')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
print(img_gray.shape)
cv2.imshow("img_gray", img_gray)
cv2.waitKey(0)    
cv2.destroyAllWindows() 

hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
cv2.imshow("hsv", hsv)
cv2.waitKey(0)    
cv2.destroyAllWindows()

3、图像阈值

ret, dst = cv2.threshold(src, thresh, maxval, type):

src: 输入图,只能输入单通道图像,通常来说为灰度图

dst: 输出图

thresh: 阈值

maxval: 当像素值超过阈值(或者小于阈值,根据type来决定),所赋的值

type:二值化操作的类型,

包含以下5种类型: cv2.THRESH_BINARY, cv2.THRESH_BINARY_INVcv2.THRESH_TRUNCcv2.THRESH_TOZEROcv2.THRESH_TOZERO_INV

类型

说明

cv2.THRESH_BINARY

超过阈值部分取maxval(最大值),否则取0

cv2.THRESH_BINARY_INV

THRESH_BINARY的反转

cv2.THRESH_TRUNC

大于阈值部分设为阈值,否则不变

cv2.THRESH_TOZERO

大于阈值部分不改变,否则设为0

cv2.THRESH_TOZERO_INV

THRESH_TOZERO的反转

代码如下,

import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB

img=cv2.imread('cjavapy.jpg')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)
ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)
ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)

titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]

for i in range(6):
    plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()

4、图像平滑

图像平滑是改善图像质量的方法,图像平滑是指用于突出图像的宽大区域、低频成分、主干部分或抑制图像噪声和干扰高频成分的图像处理方法,目的是使图像亮度平缓渐变,减小突变梯度,改善图像质量。代码如下,

import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
img = cv2.imread('cjavapy.png')

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 均值滤波
# 简单的平均卷积操作
blur = cv2.blur(img, (3, 3))

cv2.imshow('blur', blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 方框滤波
# 基本和均值一样,可以选择归一化
box = cv2.boxFilter(img,-1,(3,3), normalize=True)  

cv2.imshow('box', box)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 方框滤波
# 基本和均值一样,可以选择归一化,容易越界
box = cv2.boxFilter(img,-1,(3,3), normalize=False)  

cv2.imshow('box', box)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 高斯滤波
# 高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的
aussian = cv2.GaussianBlur(img, (5, 5), 1)  

cv2.imshow('aussian', aussian)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 中值滤波
# 相当于用中值代替
median = cv2.medianBlur(img, 5)  # 中值滤波

cv2.imshow('median', median)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 展示所有的
res = np.hstack((blur,aussian,median))
#print (res)
cv2.imshow('median vs average', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

5、形态学操作

形态学,morphology, 形态学最初是生物学中研究动物和植物结构的一个分支,被引入图像处理领域后,图像形态学就指以形态为基础对图像进行分析的一种方法或技术。

图像形态学操作的核心思想是:从图像中提取 用于表达或描绘图像形状 的信息。

图像形态学操作的目的是:使计算机更够更好的对图像进行识别和理解。因为图像形态学处理后可以简化图像数据,同时保存了它们基本的形状特性,去除了不相干的结构。

关键点:图像形态学操作主要是对二值图像进行操作的,来连接相邻的元素或分离成独立的元素。其次是灰度图像,但处理彩色图像几乎没有意义!

图像形态学操作主要有:膨胀、腐蚀、开运算、闭运算、梯度运算、礼帽运算、黑帽运算,击中与击不中变换 等等。其中膨胀和腐蚀是基本操作,后面的操作都是在膨胀和腐蚀的基础上延申而来的。

图像形态学操作有哪些应用领域?由于对图像进行形态学操作后,可以实现比如消除噪声、提取边界、填充区域、提取连通分量、凸壳、细化、粗化等; 还可以分割出独立的图像元素,或者图像中相邻的元素;求取图像中明显的极大值区域和极小值区域;求取图像梯度等等, 所以在视觉检测、图像理解、文字识别、医学图像处理、图像压缩编码等领域有非常重要的应用。

1)腐蚀操作

将物体的边缘加以腐蚀。具体的操作是拿一个宽m高n的矩形作为kernel,对图像中的每一个像素进行扫描,扫描后的图像的每个像素点和原图的位置对应,同时和扫描时kernel的中心点对应。用kernel遍历原图的所有像素,每遍历一次就将对应位置的像素点更改为kernel中的最小值。这样原图所有像素遍历一轮后,原图中突出的像素点就会被置为最小值,人类视觉看起来就是图像被腐蚀了。代码如下,

import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
img = cv2.imread('cjavapy.png')

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
#腐蚀操作,比较不同的kernel最终的腐蚀效果
#(3,3)表示3行3列, np.uint8表示行列的类型
kernel = np.ones((3,3),np.uint8) 
# cv2.erode(img, kenel, iterations)函数需要指定核以及迭代次数。
#iterations迭代次数表示腐蚀的次数
erosion = cv2.erode(img,kernel,iterations = 1)

cv2.imshow('erosion', erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()

pie = cv2.imread('pie.png')

cv2.imshow('pie', pie)
cv2.waitKey(0)
cv2.destroyAllWindows()
kernel = np.ones((30,30),np.uint8) 
erosion_1 = cv2.erode(pie,kernel,iterations = 1)
erosion_2 = cv2.erode(pie,kernel,iterations = 2)
erosion_3 = cv2.erode(pie,kernel,iterations = 3)
res = np.hstack((erosion_1,erosion_2,erosion_3))
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

2)膨胀操作

膨胀和腐蚀是相反的操作,膨胀能对图像的边界进行扩展,就是将图像的轮廓加以膨胀。操作方法与腐蚀操作一样,也是拿一个kernel,对图像的每个像素做遍历处理。不同之处在于生成的像素值不是所有像素中最小的值,而是最大的值。操作的结果会将图像外围的突出点连接并向外延伸。代码如下,

import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
img = cv2.imread('cjavapy.png')

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
#膨胀操作,比较不同的kernel最终的膨胀效果
#(3,3)表示3行3列, np.uint8表示行列的类型
kernel = np.ones((3,3),np.uint8) 
# cv2.dilate(img, kenel, iterations)函数需要指定kenel以及迭代次数。
#iterations迭代次数表示膨胀的次数
dige_dilate = cv2.dilate(dige_erosion,kernel,iterations = 1)

cv2.imshow('dilate', dige_dilate)
cv2.waitKey(0)
cv2.destroyAllWindows()
pie = cv2.imread('pie.png')

kernel = np.ones((30,30),np.uint8) 
dilate_1 = cv2.dilate(pie,kernel,iterations = 1)
dilate_2 = cv2.dilate(pie,kernel,iterations = 2)
dilate_3 = cv2.dilate(pie,kernel,iterations = 3)
res = np.hstack((dilate_1,dilate_2,dilate_3))
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()
推荐阅读
cjavapy编程之路首页