python - openCV:各种尺寸图像的翘曲透视图

标签 python opencv cv2

我正在学习计算机视觉,并尝试为 OCR 扭曲单张纸图片的透视图。样本图片为enter image description
我成功地将图像二值化并检测轮廓。然而,我很难根据轮廓包裹透视图。

def display_cv_image(image,  format='.png'):
    """
    Display image from 2d array
    """

    decoded_bytes = cv2.imencode(format, image)[1].tobytes()
    display(Image(data=decoded_bytes))
    
def get_contour(img,original, thresh):
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    areas = []
    for cnt in contours:
        area = cv2.contourArea(cnt)
        if area > 10000:
            epsilon = 0.1*cv2.arcLength(cnt,True)
            approx = cv2.approxPolyDP(cnt,epsilon,True)
            areas.append(approx)

    cv2.drawContours(original,areas,-1,(0,255,0),3)
    display_cv_image(original)

    return areas[0]

def perspective(original, target):
    dst = []

    pts1 = np.float32(target)
    pts2 = np.float32([[1000,2000],[1000,0],[0,0],[0,2000]])

    M = cv2.getPerspectiveTransform(pts1,pts2)
    dst = cv2.warpPerspective(original,M,(1000,2000))

    display_cv_image(dst)

# Driver codes
original = cv2.imread('image.jpg')
thresh, grey = binarize(original)
target = get_contour(grey,original, thresh)
perspective(original, target)

问题是pts2perspective功能。我正在尝试变量的多个值,但它们都不起作用。我想回算 map 矩阵,并可能使函数适应各种大小的图像。

最佳答案

可以从 Adrian 的教程中获得对四点透视变换的一个很好的描述:https://www.pyimagesearch.com/2014/08/25/4-point-opencv-getperspective-transform-example/
有一个功能four_point_transformimutils模块。
就上图而言,以下是可用于 OCR 输入的扭曲和二值化的代码片段。

import cv2
import numpy as np
from imutils.perspective import four_point_transform
import imutils

original = cv2.imread('image.jpg')

blurred = cv2.GaussianBlur(original, (3, 3), 0)
blurred_float = blurred.astype(np.float32) / 255.0
edgeDetector = cv2.ximgproc.createStructuredEdgeDetection('model.yml')
edged = edgeDetector.detectEdges(blurred_float)
edged = (255 * edged).astype("uint8")
edged = cv2.threshold(edged, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

cnts = cv2.findContours(edged, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:5]

for c in cnts:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.02 * peri, True)
    if len(approx) == 4:
        screenCnt = approx
        break

if len(screenCnt) == 4:
    warped = four_point_transform(original, screenCnt.reshape(4, 2))

warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
T = cv2.ximgproc.niBlackThreshold(warped, maxValue=255, type=cv2.THRESH_BINARY_INV, blockSize=81, k=0.1, binarizationMethod=cv2.ximgproc.BINARIZATION_WOLF)
warped = (warped > T).astype("uint8") * 255

cv2.imshow("Original", imutils.resize(original, height = 650))
cv2.imshow("Edged", imutils.resize(edged, height = 650))
cv2.imshow("Warped", imutils.resize(warped, height = 650))
cv2.waitKey(0)
以下是原始、边缘和最终扭曲的二值化输出:
enter image description here
请注意 StructuredEdgeDetection用于更好的边缘检测。您可以下载model.yml来自链接的文件:https://cdn.rawgit.com/opencv/opencv_extra/3.3.0/testdata/cv/ximgproc/model.yml.gz
另请注意,Wolf & Julion 二值化技术用于更好的输出。
您需要安装opencv-contrib-python通过 pip 打包 StructuredEdgeDetectionniBlackThreshold .

关于python - openCV:各种尺寸图像的翘曲透视图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63829831/

相关文章:

python - CELERYBEAT_SCHEDULE 在你的项目中放在哪里?

opencv - 图像中简单基准点的位置识别

JavaCV 示例/教程

python - 如何在cv2中在黑色背景上绘制红色形状?

python - Selenium Chrome Webdriver 进程在本地工作但不在 Heroku 上工作

python - 如何以不可知对象是列表还是字典的方式迭代对象?

python - 警告 :0 terminating async callback error in cv2

python - 如何将 cv2 图像转换为 skimage?

python - 在 django 中,如何从初始化脚本中调用子命令 'syncdb'?

c++ - 从俯仰角检测头部点头姿势