想学习机器视觉和图像处理的朋友看过来!
数学形态学提供了一组有用的方法,能够用来调整分割区域的形状以获得比较理想的结果,它最初是从数学中的集合论发展而来并用于处理二值图的,虽然运算很简单,但是往往可以产生很好的效果,后来这些方法推广到普通的灰度级图像处理中。常用的形态学处理方法包括:腐蚀、膨胀、开运算、闭运算、礼帽运算、黑帽运算,其中膨胀与腐蚀是图像处理中最常用的形态学操作手段,其他方法是两者相互组合而产生的。
膨胀:
取每个位置领域内最大值,所以膨胀后输出图像的总体亮度的平均值比起原图会有所升高,图像中比较亮的区域的面积会变大,而较暗物体的尺寸会减小甚至消失。
# encoding = 'utf8'
import cv2
import numpy as np
img = cv2.imread('8-3.jpg',0)
kernel = np.ones((10,10),np.uint8)
t,rst = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
dilation = cv2.dilate(rst,kernel)
cv2.imshow('image',rst)
cv2.imshow('dilation',dilation)
cv2.waitKey(0)
cv2.destroyAllWindows()
腐蚀:
腐蚀操作与膨胀操作类似,只是它取每个位置领域内最小值,所以腐蚀后输出图像的总体亮度的平均值比起原图会有所降低,图像中比较亮的区域的面积会变小甚至消失,而较暗物体的尺寸会扩大。
# encoding = 'utf8'
import cv2
import numpy as np
img = cv2.imread('8-2.jpg',0)
kernel = np.ones((10,10),np.uint8)
t,rst = cv2.threshold(img,127,255,cv2.THRESH_BINARY) # 二值化
erosion = cv2.erode(rst,kernel) # 腐蚀
cv2.imshow('image',img)
cv2.imshow('imagel',rst)
cv2.imshow('erosion',erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()
开运算:
先腐蚀后膨胀的操作
可以去除噪声,消除小物体
在纤细点处分离物体
平滑较大物体的边界的同时并不明显改变其面积
# encoding = 'utf8'
import cv2
import numpy as np
img = cv2.imread('8-4.jpg',0)
kernel = np.ones((10,10),np.uint8)
t,rst = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
r1 = cv2.morphologyEx(rst,cv2.MORPH_OPEN,kernel)
cv2.imshow('image',rst)
cv2.imshow('r1',r1)
cv2.waitKey(0)
cv2.destroyAllWindows()
闭运算:
先膨胀后腐蚀
可排除小型空洞(指黑色区域)
平滑物体轮廓
弥合(连接)窄的间断点,沟壑
填补轮廓线断裂
# encoding = 'utf8'
import cv2
import numpy as np
img1 = cv2.imread('8-5.jpg',0)
img2 = cv2.imread('8-6.jpg',0)
kernel = np.ones((10,10),np.uint8)
t1,rst1 = cv2.threshold(img1,127,255,cv2.THRESH_BINARY)
t2,rst2 = cv2.threshold(img2,127,255,cv2.THRESH_BINARY)
r1 = cv2.morphologyEx(rst1,cv2.MORPH_CLOSE,kernel)
r2 = cv2.morphologyEx(rst2,cv2.MORPH_CLOSE,kernel)
cv2.imshow('image1',rst1)
cv2.imshow('image2',rst2)
cv2.imshow('r1',r1)
cv2.imshow('r2',r2)
cv2.waitKey(0)
cv2.destroyAllWindows()
形态梯度学运算:
对二值图进行这一操作可以将边缘突出出来,我们可以用形态学梯度来保留物体的边缘轮廓
# encoding = 'utf8'
import cv2
import numpy as np
img = cv2.imread('8-7.jpg',0)
kernel = np.ones((10,10),np.uint8)
t,rst = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
r1 = cv2.morphologyEx(rst,cv2.MORPH_GRADIENT,kernel)
cv2.imshow('image',rst)
cv2.imshow('r1',r1)
cv2.waitKey(0)
cv2.destroyAllWindows()
形态学练习:
import cv2
import numpy as np
img1 = cv2.imread('11.jpg')
img2 = cv2.imread('12.jpg')
img3 = cv2.imread('13.jpg')
img4 = cv2.imread('14.jpg')
img5 = cv2.imread('22.jpg')
img6 = cv2.imread('22.jpg',0)
a,b = img6.shape
print("22文件的面积是",a*b)
print("22文件的周长是",(a+b)*2)
kernel = np.ones((10,10),np.uint8)
t1,rst1 = cv2.threshold(img1,127,255,cv2.THRESH_BINARY)
t2,rst2 = cv2.threshold(img2,127,255,cv2.THRESH_BINARY)
t3,rst3 = cv2.threshold(img3,127,255,cv2.THRESH_BINARY)
t4,rst4 = cv2.threshold(img4,127,255,cv2.THRESH_BINARY)
t5,rst5 = cv2.threshold(img5,127,255,cv2.THRESH_BINARY) #二值化,大于127阈值的被置为255,小于127的被置为0
r1 = cv2.morphologyEx(rst1,cv2.MORPH_CLOSE,kernel)
r2 = cv2.morphologyEx(rst2,cv2.MORPH_OPEN,kernel)
r3 = cv2.morphologyEx(rst3,cv2.MORPH_OPEN,kernel)
r4 = cv2.morphologyEx(rst4,cv2.MORPH_OPEN,kernel)
r5 = cv2.morphologyEx(rst5,cv2.MORPH_GRADIENT,kernel)
def dHash(img):
# 差值哈希算法
# 缩放8*8
img = cv2.resize(img,(9,8))
# 转换灰度图
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
hash_str = ''
# 每行前一个像素大于后一个像素为1,相反为0,生成哈希
for i in range(8):
for j in range(8):
if gray[i,j] > gray[i,j+1]:
hash_str = hash_str+'1'
else:
hash_str = hash_str+'0'
return hash_str
def cmpHash(hash1, hash2):
# Hash值对比
# 算法中1和0顺序组合起来的即是图片的指纹hash。顺序不固定,但是比较的时候必须是相同的顺序。
# 对比两幅图的指纹,计算汉明距离,即两个64位的hash值有多少是不一样的,不同的位数越小,图片越相似
# 汉明距离:一组二进制数据变成另一组数据所需要的步骤,可以衡量两图的差异,汉明距离越小,则相似度越高。汉明距离为0,即两张图片完全一样
n = 0
# hash长度不同则返回-1代表传参出错
if len(hash1) != len(hash2):
return -1
# 遍历判断
for i in range(len(hash1)):
# 不相等则n计数+1,n最终为相似度
if hash1[i] != hash2[i]:
n = n + 1
return n
li1 = [img1,img2,img3,img4]
li2=[]
max_n = 0
for i in range(len(li1)):
hash1 = dHash(li1[i])
hash2 = dHash(img5)
n = cmpHash(hash1, hash2)
print(n)
li2.append(n)
for j in li2:
if j > max_n:
max_n = j
else:
max_n = max_n
for i in range(len(li1)):
if max_n==li2[i]:
t1, rst6 = cv2.threshold(li1[i], 127, 255, cv2.THRESH_BINARY)
r6 = cv2.morphologyEx(rst6, cv2.MORPH_CLOSE, kernel)
cv2.imshow('r6', r6)
cv2.imshow('r1',r1)
cv2.imshow('r2',r2)
cv2.imshow('r3',r3)
cv2.imshow('r4',r4)
cv2.imshow('r5',r5)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
文章到这里就结束了!希望大家能多多支持机器视觉(系列)!私聊我,可以问关于本文章的问题!以后每天都会发布新的文章,喜欢的点点关注!一个陪伴你学习的新青年!不管多忙都会更新下去,一起加油!
网友评论