第十天图像综合案例

案例一 纸张变正

#练习改进
fig, axes = plt.subplots(1, 5, figsize=(15, 15))
img = cv2.imread('../data/paper.jpg', 1)[..., ::-1]
axes[0].imshow(img)

gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
axes[1].imshow(gray, cmap=plt.get_cmap('gray'))

#模糊降噪
bluerd = cv2.GaussianBlur(gray, (5, 5), 0)

# 执行开运算,去掉边角的阴影
k = np.ones((3, 3), np.uint8)
r1 = cv2.morphologyEx(bluerd, cv2.MORPH_CLOSE, k, iterations=3)

#提高边沿分辨度
canny = cv2.Canny(r1,
                  30,  #滞后域值
                  120)  #模糊度

#二值化效果不理想,所以放弃二值化
t, binary = cv2.threshold(canny, 200, 255, cv2.THRESH_BINARY)
axes[2].imshow(binary, cmap=plt.get_cmap('gray'))

#寻找轮廓
cnts, hie = cv2.findContours(binary,
                             mode=cv2.RETR_EXTERNAL,  #只检测外轮廓
                             method=cv2.CHAIN_APPROX_SIMPLE)  #存储重点坐标

#print(len(cnts))
#for i in range(len(cnts)):
#    print(cnts[i].shape)

#找到最大的矩形轮廓,并获得矩形坐标
doccnt = None
if len(cnts) > 0:
    sorted(cnts,
           key=cv2.contourArea,  #key只能是排序依据,所以不用(),有了()就是函数调用了
           reverse=True)  #降序排序
    for cnt in cnts:
        eps = 0.02 * cv2.arcLength(cnt, True)
        approx = cv2.approxPolyDP(cnt, eps, True)
        if len(approx) == 4:
            doccnt = approx
            break

print(doccnt)

#将四个角上花圈
points = []
for peak in doccnt:
    peak = peak[0]
    cv2.circle(gray, tuple(peak), 30, (0, 0, 0), 4)
    points.append(peak)
#变换之前的坐标点
src = np.array(points, dtype='float32')

#求宽度和高度
h = int(math.sqrt((src[0][0] - src[1][0]) ** 2 + (src[0][1] - src[1][1]) ** 2))
w = int(math.sqrt((src[0][0] - src[3][0]) ** 2 + (src[0][1] - src[3][1]) ** 2))

dst = np.float32([[0, 0],
                  [0, h],
                  [w, h],
                  [w, 0]])

#仿射变换
M = cv2.getPerspectiveTransform(src, dst)
res = cv2.warpPerspective(img, M, (w, h))
axes[4].imshow(res)

#绘制轮廓
img_cnt = cv2.drawContours(gray,
                           cnts[0],
                           -1,  # 绘制cnts内全部轮廓
                           (0, 0, 0),  # 轮廓颜色:黑色
                           6)  # 轮廓粗细 -1表示实心化填充

axes[3].imshow(img_cnt, cmap=plt.get_cmap('gray'))
plt.show()

在这里插入图片描述

案例二 芯片找瑕疵

#练习
fig, axes = plt.subplots(2, 4, figsize=(15, 15))
img = cv2.imread('../data/CPU3.png', 1)[..., ::-1]
axes[0][0].imshow(img)

gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
axes[0][1].imshow(gray, cmap=plt.get_cmap('gray'))

t, binary = cv2.threshold(gray, 169, 255, cv2.THRESH_BINARY)
axes[0][2].imshow(binary, cmap=plt.get_cmap('gray'))

cnts, hie = cv2.findContours(binary,
                             mode=cv2.RETR_EXTERNAL,  #只检测外轮廓
                             method=cv2.CHAIN_APPROX_NONE)  #存储所有的轮廓点

mask = np.zeros_like(binary)
#绘制轮廓
img_fill = cv2.drawContours(mask, cnts,
                            -1,  # 绘制全部轮廓
                            (255, 0, 0),  # 轮廓颜色:红色
                            -1)  # 轮廓粗细
axes[0][3].imshow(img_cnt, cmap=plt.get_cmap('gray'))

img_sub = cv2.subtract(img_fill, binary)  # 两幅图像相减,是求出图像的差异
axes[1][0].imshow(img_sub, cmap=plt.get_cmap('gray'))

# 执行闭运算, 让瑕疵点内部收敛
k = np.ones((3, 3), np.uint8)
close = cv2.morphologyEx(img_sub, cv2.MORPH_CLOSE, k, iterations=2)
axes[1][1].imshow(close, cmap=plt.get_cmap('gray'))

#查找轮廓
cnts, hie = cv2.findContours(close,
                             mode=cv2.RETR_EXTERNAL,  #只检测外轮廓
                             method=cv2.CHAIN_APPROX_NONE)  #存储所有的轮廓点

#找到最大的矩形轮廓
doccnt = None
if len(cnts) > 0:
    sorted(cnts,
           key=cv2.contourArea,  #key只能是排序依据,所以不用(),有了()就是函数调用了
           reverse=True)  #降序排序

center, radius = cv2.minEnclosingCircle(cnts[0])
print('圆心和半径:({},{})'.format(center, radius))
#圆心和半径必须是整数
center = (int(center[0]), int(center[1]))
radius = int(radius)

img_close = cv2.circle(close, center, radius, (255, 255, 255), 30)  # 绘制圆
axes[1][2].imshow(img_close, cmap=plt.get_cmap('gray'))

img_close2 = cv2.circle(gray, center, radius, (255, 255, 255), 30)  # 绘制圆
axes[1][3].imshow(img_close2, cmap=plt.get_cmap('gray'))

plt.show()

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值