1. 图像形态
图像形态学是图像处理的一个独立分支
主要用于灰度和二值图像
它是从数学的集合论和数学中的拓扑几何原理发展而来的
二、膨胀操作(dilate)
3×3的卷积核以3×3为卷积核从左往右(从上往下)开始运行,若这卷积核内存在1,则用1替代中心元素。
最大值替换中心像素
多白少黑
扩展的作用:
对象大小增加一个像素(3×3)
平滑对象边缘
减少或填充物体之间的距离
二值图
import cv2 as cv
import numpy as np
def dilate(image):
print(image.shape)
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
cv.imshow("binary", binary)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
dst = cv.dilate(binary, kernel)
cv.imshow("dilate", dst)
src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\number.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
dilate(src)
cv.waitKey(0)
cv.destroyAllWindows()
效果图如下:
·彩图·
import cv2 as cv
import numpy as np
src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\l.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
dst = cv.dilate(src, kernel)
cv.imshow("result", dst)
cv.waitKey(0)
cv.destroyAllWindows()
效果图如下:
三、腐蚀操作(erode)
3×3的卷积核以3×3为卷积核从左往右(从上往下)开始运行,若这卷积核内存在0,则用0替代中心元素。
最小值替换中心像素
多黑少白
二值图
import cv2 as cv
import numpy as np
def erode(image):
print(image.shape)
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)#图像二值化
cv.imshow("binary", binary)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (15, 15))
dst = cv.erode(binary, kernel)
cv.imshow("erode", dst)
src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\number.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
erode_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
效果图如下:
彩色图
import cv2 as cv
import numpy as np
src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\l.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
dst = cv.erode(src, kernel)
cv.imshow("erode", dst)
cv.waitKey(0)
cv.destroyAllWindows()
效果图如下:
彩色和二值图像的腐蚀和膨胀
总结:膨胀---白变多黑变少、腐蚀---黑变多白变少
四、开操作(open)
开放操作 = 腐蚀 + 膨胀
可以去除图像中的小干扰区域cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
,如果反了,可以把参数设置为cv.THRESH_BINARY_INV
import cv2 as cv
import numpy as np
def open(image):
print(image.shape)
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
cv.imshow("binary", binary)
kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (5, 5))
binary = cv.morphologyEx(binary, cv.MORPH_OPEN, kernel)
cv.imshow("open-result", binary)
src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\test.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
open(src)
cv.waitKey(0)
cv.destroyAllWindows()
效果图如下:
五、闭操作(close)
关闭操作 = 膨胀 + 腐蚀
填充小的封闭区域
import cv2 as cv
import numpy as np
def close(image):
print(image.shape)
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
cv.imshow("binary", binary)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
binary = cv.morphologyEx(binary, cv.MORPH_CLOSE, kernel)
cv.imshow("close_demo", binary)
src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\test1.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
close(src)
cv.waitKey(0)
cv.destroyAllWindows()
效果图如下:
打开和关闭操作仅适用于二值图像总结:开操作消除白点,闭操作消除黑点
六、顶帽(tophat)
原图与开运算的差图
彩色图像
import cv2 as cv
import numpy as np
def tophat(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (15, 15))
dst = cv.morphologyEx(gray, cv.MORPH_TOPHAT, kernel)
"""
若图片不够亮可以对图像进行整体增加亮度
cimage = np.array(gray.shape, np.uint8)
cimage = 120;
dst = cv.add(dst, cimage)
"""
cv.imshow("tophat", dst)
src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\l.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
tophat(src)
cv.waitKey(0)
cv.destroyAllWindows()
效果图如下:二值图像
import cv2 as cv
import numpy as np
def tophat_binary(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
dst = cv.morphologyEx(binary, cv.MORPH_TOPHAT, kernel)
cv.imshow("tophat_binary", dst)
src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\test.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
tophat_binary(src)
cv.waitKey(0)
cv.destroyAllWindows()
效果图如下:
七、黑帽(blackhat)
关闭操作与原始图像的差异图像彩色图像
import cv2 as cv
import numpy as np
def blackhat(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (15, 15))
dst = cv.morphologyEx(gray, cv.MORPH_BLACKHAT, kernel)
"""
若图片不够亮可以对图像进行整体增加亮度
cimage = np.array(gray.shape, np.uint8)
cimage = 120;
dst = cv.add(dst, cimage)
"""
cv.imshow("blackhat", dst)
src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\l.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
blackhat(src)
cv.waitKey(0)
cv.destroyAllWindows()
效果图如下:二值图像
import cv2 as cv
import numpy as np
def blackhat_binary(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
dst = cv.morphologyEx(binary, cv.MORPH_BLACKHAT, kernel)
cv.imshow("blackhat_binary", dst)
src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\test.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
blackhat_binary(src)
cv.waitKey(0)
cv.destroyAllWindows()
效果图如下:
八、形态学梯度(Gradient)
基本梯度:从膨胀图像中减去侵蚀图像得到的差值图像
内部梯度:原始图像减去侵蚀图像得到的差值图像
外梯度:图像扩展后减去原始图像得到的差值图像
基本梯度
import cv2 as cv
import numpy as np
def base_gradient(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
dst = cv.morphologyEx(binary, cv.MORPH_GRADIENT, kernel)
cv.imshow("base_gradient", dst)
src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\test.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
base_gradient(src)
cv.waitKey(0)
cv.destroyAllWindows()
效果图如下:内梯度和外梯度
import cv2 as cv
import numpy as np
def ex_in_gradient(image):
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
dm = cv.dilate(image, kernel)
em = cv.erode(image, kernel)
dst1 = cv.subtract(image, em) # internal gradient
dst2 = cv.subtract(dm, image) # external gradient
cv.imshow("internal", dst1)
cv.imshow("external", dst2)
src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\test.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
ex_in_gradient(src)
cv.waitKey(0)
cv.destroyAllWindows()
效果图如下:
以上代码中,想要获取不同的需求只需要修改这个获取结构元素的方法中的参数即可cv.getStructuringElement(cv.MORPH_RECT, (15, 15))
文章出处登录后可见!
已经登录?立即刷新