OpenCV中的形态学

图像二值化

二值化就是将图像的每个像素变成两种值,比如0或255,一般是对灰度图像进行处理
**全局二值化api:设定一个阈值,低于这个值的把像素值为0,高于的归为255或其他值(自己设定)

threshold(img, thresh, maxVal, type)
img :图像,最好是灰度图像
thresh :阈值
maxVal :自己设定的像素点最大值
type :THRESH_BINARY(低于阈值的设为0,高于的设为最大值),
THRESH_BINARY_INV(低于阈值的设为最大值,高于的设为0)
THRESH_TRUNC(低于阈值时不做改变,高于阈值的像素点设为阈值)
THRESH_TOZERO(高于阈值时不变,低于阈值时设为0)
THRESH_TOZERO_INV(低于阈值时不变,高于阈值时设为0)
【type 的后三种类型生成的图像不是二值化图像,图像中还是有梯度的】
下面图是type 的5个类型表达
OpenCV中的形态学_第1张图片

import cv2
import numpy as np

img = cv2.imread('d:\\STUDY_OPENCV\\img\\cdog.jpg')
#把彩色图像变为灰度图像
img1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret,dst = cv2.threshold(img1, 100, 255, cv2.THRESH_BINARY)
cv2.imshow('img', img)
cv2.imshow('gray',img1)
cv2.imshow('bin',dst)
cv2.waitKey(0)

自适应阈值二值化

由于光照不均匀以及阴影的存在,只有一个阈值会使得一张图识别不准确。
自适应阈值二值化api

adaptiveThreshold(img, maxVal, adaptiveMethod,type, blockSize, C)
img :要处理的图片
maxVal :转换的最大值是多少
adaptiveMethod :计算阈值方法,对某个区域自己计算这个阈值
type : THRESH_BINARY,THRESH_BINARY_INV
blockSize :区域的大小,想要计算精准点就把区域设置小点,但是计算量会增加
C :又自适应计算得到的平均值或加权平均值减去,一般设为0即可

计算阈值方法有:
ADAPTIVE_THRESH_MEAN_C :计算邻近区域的平均值作为阈值(就是把blockSize 区域的所有像素值计算的平均值作为阈值)
ADAPTIVE_THRESH_GAUSSIAN_C :高斯窗口加权平均值(越靠近中心点权值越重)

把以上代码ret,dst = cv2.threshold(img1, 100, 255, cv2.THRESH_BINARY)换成自适应
dst = cv2.adaptiveThreshold(img1, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 3, 0)即可得到以下效果,可以看出处理后的图片背景噪点比较多

图像的腐蚀

用卷积核对图像进行处理,其中卷积核元素只有在所有像素都为1的情况下或者说所有像素都大于1才为1,其他时候都为0,所以在完全黑色或者完全白色区域处理之后不变,在卷积的这块区域中又有黑色又有白色那么处理后就会变成黑色,即原来图像会缩小
以下是进行腐蚀之后的效果
OpenCV中的形态学_第2张图片
腐蚀api
erode(img, kernel, iteration = 1)
img :需要处理的图像,二值化图像
kernel :卷积核,卷积核越大腐蚀的效果越明显。
手动设置可以这样kernel = np.ones((3,3),np.uint8),或调用获取形态学卷积核api
iteration :腐蚀执行的次数

获取形态学卷积核api :
getStructuringElement( type, size)
size :卷积核大小,书写形式为(3,3)
type :(可以在程序中通过print打印出来就可以看出区别)
MORPH_RECT : 方形卷积核
MORPH_ELLIPSE :椭圆形卷积核
MORPH_CROSS : 十字架型卷积核,中间一横和竖为1,其余元素为0

图像的膨胀

图像进行卷积的时候只要卷积核的中心锚点是非零的,经过卷积之后的周边无论是非零还是零都变成了非零值,这就是膨胀。通俗来讲腐蚀就是把图像变瘦了,膨胀就是把图像扩大了。膨胀的快与慢就是与卷积核的大小有关。
膨胀之后的效果
OpenCV中的形态学_第3张图片
膨胀api
dilate(img, kernel, iteration = 1) : 与上面腐蚀api参数含义是一样的

开运算

开运算 = 腐蚀+膨胀 【顺序一定不能颠倒】,能够消除背景中的噪点,可以手动调两个api也可以调用开运算api
开运算api
morphologyEx(img, MORPH_OPEN, kernel)
MORPH_OPEN :一个宏定义,代表形态学的开运算
kernel :卷积核,一般噪点比较大的时候会使用比较大的卷积核
OpenCV中的形态学_第4张图片

闭运算

闭运算 = 膨胀 + 腐蚀 【顺序一定不能颠倒】:能够将图片里面的黑色噪点消除
闭运算api
morphologyEx(img,MORPH_CLOSE , kernel),与开运算api一样,只是调用的宏不一样
OpenCV中的形态学_第5张图片

形态学梯度

梯度 = 原图 - 腐蚀, 最后结果就是检测边缘
morphologyEx(img,MORPH_GRADIENT , kernel),边缘的好坏与kernel大小密切相关,kernel越大,腐蚀的越多,得出来的边缘就越粗
OpenCV中的形态学_第6张图片

顶帽运算

顶帽运算 = 原图 - 开运算 ,开运算是去除背景图的噪点,则顶帽运算就是得到背景图的噪点(也可能是有用信息)
顶帽api :morphologyEx(img,MORPH_TOPHAT , kernel)
OpenCV中的形态学_第7张图片

黑帽运算

黑帽运算 = 原图 - 闭运算,闭运算是去除白色图像中的噪点,则黑帽运算就是得到白色图形中的噪点(可能是有效信息)
黑帽api :morphologyEx(img,MORPH_BLACKHAT , kernel)
OpenCV中的形态学_第8张图片
以下是上面api的实例操作

import cv2
import numpy as np

#kernel = np.ones((3,3), np.uint8)
#获取形态学卷积核
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7,7))

img = cv2.imread('d:\\STUDY_OPENCV\\img\\pos.png')
img_er = cv2.imread('d:\\STUDY_OPENCV\\img\\zf.jpg')
#腐蚀
ero = cv2.erode(img_er, kernel, iterations=1)
#膨胀操作
dil = cv2.dilate(img_er, kernel, iterations=1)

#开运算 = 腐蚀 + 膨胀
mor = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
#闭运算 = 膨胀 +腐蚀
mor2 = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
#梯度运算,即检测边缘
mor3 = cv2.morphologyEx(img_er, cv2.MORPH_GRADIENT, kernel)
#顶帽运算 = 原图-开运算
mor4 = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
#黑帽运算 = 原图-闭运算
mor5 = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

cv2.imshow('img',img)
cv2.imshow('mor2',mor2)
cv2.imshow('mor', mor)
cv2.imshow('mor4', mor4)
cv2.imshow('mor5', mor5)
cv2.waitKey(0)

你可能感兴趣的:(opencv,计算机视觉,人工智能)