使用Python,OpenCV构建移动文档扫描仪

使用Python,OpenCV构建移动文档扫描仪

1. 效果图

图1,鸟瞰图
在这里插入图片描述
图2,角度不太一样,鸟瞰图的效果也不一致;
在这里插入图片描述

2. 步骤

使用OpenCV构建文档扫描仪仅需三个简单步骤即可完成:

  1. 检测边缘;
  2. 使用图像中的边缘找到代表要扫描的纸张的轮廓(轮廓);
  3. 应用透视变换以获得图像文档的自顶向下视图;

3. 源码

  • 为了加快图像处理速度,对图像进行保留宽高比的缩放(imutils.resize);
  • 执行高斯模糊(cv2.GaussianBlur)以消除高频噪声,有助于后续的轮廓检测;
  • 应用阈值处理(threshold_local)可以获得漂亮,干净的黑白感觉的图像;
# USAGE
# python scan.py --image images/01.jpg

# 导入必要的包
import argparse  # 命令行参数构建及解析

import cv2
import imutils
from imutils.perspective import four_point_transform  # 透视变换方法
from skimage.filters import threshold_local  # 此功能将帮助我们获得扫描图像的“黑白”感觉。

# 构建命令行参数及解析
# --image 图像路径
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
                help="Path to the image to be scanned")
args = vars(ap.parse_args())

# 加载图像,计算图像高度/新高度的比值,复制图像,保留宽高比的缩放图像
# 为了加快图像处理速度,对图像进行了缩放
image = cv2.imread(args["image"])
ratio = image.shape[0] / 500.0
orig = image.copy()
image = imutils.resize(image, height=500)

# 转换图像为灰度图,执行高斯模糊以消除高频噪声(有助于步骤2中的轮廓检测),执行canny边缘检测算法
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(gray, 75, 200)

# 展示原始图像和边缘检测的图像
print("STEP 1: Edge Detection")
cv2.imshow("Image", image)
cv2.imshow("Edged", edged)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 假设图像中具有正好四个点的最大轮廓是要扫描的纸。这是一个相当安全的假设-扫描仪应用程序仅假设您要扫描的文档是图像的主要焦点。并且可以安全地假设这张纸有四个边缘。

# 从边缘检测的图像中寻找轮廓,保持最大的一个,并且初始化文档轮廓
cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:5]
print(cnts)

# 遍历轮廓
for c in cnts:
    # 近似轮廓
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.02 * peri, True)

    # 如果近似轮廓刚好有4个点,则假设我们已经找到了文档页
    if len(approx) == 4:
        screenCnt = approx
        break

# 展示纸的轮廓
print("STEP 2: Find contours of paper")
cv2.drawContours(image, [screenCnt], -1, (0, 255, 0), 2)
cv2.imshow("Outline", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 构建移动文档扫描仪的最后一步是获取代表文档轮廓的四个点,并应用透视变换以获得图像的自顶向下的“鸟瞰图”。
# 应用四点透视变换以获得原始图像的自顶向下的“鸟瞰图”
warped = four_point_transform(orig, screenCnt.reshape(4, 2) * ratio)

# 转换透视变换后的结果为灰度图,并应用阈值化方法以构建“黑白”背景的感觉
warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
T = threshold_local(warped, 11, offset=10, method="gaussian")
warped = (warped > T).astype("uint8") * 255

# 展示原始图像和扫描得到的图像
print("STEP 3: Apply perspective transform")
cv2.imshow("Original", imutils.resize(orig, height=500))
cv2.imshow("Scanned", imutils.resize(warped, height=500))
cv2.waitKey(0)

参考

猜你喜欢

转载自blog.csdn.net/qq_40985985/article/details/110094436