从图像中精确裁剪文档纸张

Raj*_*Jog 2 python opencv image-processing computer-vision

我当前正在使用以下代码来裁剪图像

def crop_image(image):
image = cv2.imread(image)
original_img = image.copy()
hsv_img = convert_hsv(image)

lower_blue = np.array([0, 0, 120])
upper_blue = np.array([180, 38, 255])

masked_image = mask_img(hsv_img, lower_blue, upper_blue)
result = cv2.bitwise_and(image, image, mask=masked_image)
contours = cv2.findContours(masked_image.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
contours = imutils.grab_contours(contours)
cv2.drawContours(masked_image, contours, -1, (0, 255, 0), 3)
max_area_contour = max(contours, key=cv2.contourArea)
x, y, w, h = cv2.boundingRect(max_area_contour)
cv2.rectangle(result, (x, y), (x+w, y+h), (0, 255, 0), 3)
cont_filename = generate_contours_filename()
cv2.imwrite(cont_filename, np.hstack([image, result]))
logger.info('Successfuly saved file : %s' % cont_filename)
img = image[y:y+h, x:x+w]
filename = generate_filename()
cv2.imwrite(filename, img)
logger.info('Successfully saved cropped file : %s' % filename)
return img, filename
Run Code Online (Sandbox Code Playgroud)

以下是之前和之后的图像: 这是原始图像

这是结果图像

我需要仅裁剪纸张部分的图像

提前致谢

fmw*_*w42 6

这是在 Python/Opencv 中执行此操作的一种方法。

  • 读取输入
  • 转换为灰度
  • 临界点
  • 应用形态学来清除小区域
  • 获取轮廓并过滤以保留最大的轮廓
  • 获取边界框
  • 绘制黑色背景上填充的最大轮廓作为蒙版
  • 应用蒙版将纸张背景变黑
  • 使用边界框裁剪屏蔽输入
  • 保存结果

输入:

在此输入图像描述

import cv2
import numpy as np

# read image as grayscale
img = cv2.imread('paper.jpg')

# convert to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# threshold
thresh = cv2.threshold(gray, 190, 255, cv2.THRESH_BINARY)[1]\

# apply morphology
kernel = np.ones((7,7), np.uint8)
morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
kernel = np.ones((9,9), np.uint8)
morph = cv2.morphologyEx(morph, cv2.MORPH_ERODE, kernel)

# get largest contour
contours = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
contours = contours[0] if len(contours) == 2 else contours[1]
area_thresh = 0
for c in contours:
    area = cv2.contourArea(c)
    if area > area_thresh:
        area_thresh = area
        big_contour = c


# get bounding box
x,y,w,h = cv2.boundingRect(big_contour)

# draw filled contour on black background
mask = np.zeros_like(gray)
mask = cv2.merge([mask,mask,mask])
cv2.drawContours(mask, [big_contour], -1, (255,255,255), cv2.FILLED)

# apply mask to input
result1 = img.copy()
result1 = cv2.bitwise_and(result1, mask)

# crop result
result2 = result1[y:y+h, x:x+w]

# view result
cv2.imshow("threshold", thresh)
cv2.imshow("morph", morph)
cv2.imshow("mask", mask)
cv2.imshow("result1", result1)
cv2.imshow("result2", result2)
cv2.waitKey(0)
cv2.destroyAllWindows()

# save result
cv2.imwrite("paper_thresh.jpg", thresh)
cv2.imwrite("paper_morph.jpg", morph)
cv2.imwrite("paper_mask.jpg", mask)
cv2.imwrite("paper_result1.jpg", result1)
cv2.imwrite("paper_result2.jpg", result2)
Run Code Online (Sandbox Code Playgroud)

阈值图像:

在此输入图像描述

形态学清洗后的图像:

在此输入图像描述

从最大轮廓掩模图像:

在此输入图像描述

屏蔽输入的结果:

在此输入图像描述

裁剪上一张图像的结果:

在此输入图像描述