从图像中精确裁切文档纸 [英] Crop exactly document paper from image

查看:73
本文介绍了从图像中精确裁切文档纸的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  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)
结果= cv2.bitwise_and(图像,图像,mask = masked_image)
轮廓= cv2.findContours(masked_image.copy(),cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
轮廓= imutils.grab_contours(轮廓)
cv2.drawContours(masked_image,轮廓,-1,( 0、255、0),3)
max_area_contour = max(轮廓,键= cv2.contourArea)
x,y,w,h = cv2.boundingRect(max_area_contour)
cv2.rectangle(结果(x,y),(x + w,y + h),(0,255,0),3)
cont_filename = generate_contours_filename()
cv2.imwrite(cont_filename,np.hstack ([图像,结果]))
logger.info(成功保存的文件:%s'%cont_filename)
img = image [y:y + h, x:x + w]
filename = generate_filename()
cv2.imwrite(filename,img)
logger.info('成功保存的裁剪文件:%s'%filename)
返回img,文件名

以下是前后的图像:

  import cv2 
import numpy as np

#将图像读取为灰度
img = cv2.imread( 'paper.jpg')

#转换为灰度
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

#门槛
阈值= cv2.threshold(gray,190,255,cv2.THRESH_BINARY)[1] \

#应用形态
内核= np.ones((7,7),np.uint8)
morph = cv2.morphologyEx(阈值,cv2.MORPH_CLOSE,内核)
内核= np.ones((9,9),np.uint8)
morph = cv2.morphologyEx(morph, cv2.MORPH_ERODE,内核)

#获得最大轮廓
轮廓= cv2.findContours(morph,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
轮廓=轮廓[0],如果len(contours)== 2否则,轮廓[1]
area_thresh = 0
对于c在轮廓中:
面积= cv2.contourArea(c)
如果area> area_thresh:
area_thresh =面积
big_contour = c


#获取边界框
x,y,w,h = cv2.boundingRect(big_contour)

#在黑色背景上绘制填充轮廓
mask = np.zeros_like(gray)
mask = cv2.merge([mask,mask,mask])
cv2。 drawContours(mask,[big_contour],-1,(255,255,255),cv2.FILLED)

#将掩码应用于输入
result1 = img.copy()
result1 = cv2 .bitwise_and(result1,mask)

#作物结果
result2 = result1 [y:y + h,x:x + w]

#查看结果
cv2.imshow(阈值,阈值)
cv2.imshow( morph,morph)
cv2.imshow( mask,mask)
cv2.imshow( result1,result1)
cv2.imshow( result2,result2)
cv2.waitKey(0)
cv2.destroyAllWindows()

#保存结果
cv2.imwrite( paper_thresh.jpg,脱粒)
cv2.imwrite( paper_morphesh.jpg,变形)
cv2.imwrite( paper_mask.jpg,遮罩)
cv2.imwrite( paper_result1.jpg,result1)
cv2.imwrite( paper_result2.j pg,结果2)

阈值图像:





形态学清洁图像:





从最大轮廓遮罩图像:





屏蔽输入的结果:





裁剪前一张图片的结果:




I am using the following code to crop image currently

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

Following are theimages before and after: This is original image

This is resulting image

I need image that crops paper part only

Thanks in advance

解决方案

Here is one way to do that in Python/Opencv.

  • Read the input
  • Convert to grayscale
  • Threshold
  • Apply morphology to clean it of small regions
  • Get contours and filter to keep the largest one
  • Get the bounding box
  • Draw the largest contour filled on a black background as a mask
  • Apply the mask to blacken out the background of the paper
  • Use the bounding box to crop the masked input
  • Save the results

Input:

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)

Thresholded image:

Morphology cleaned image:

Mask image from largest contour:

Result of masking the input:

Result of cropping previous image:

这篇关于从图像中精确裁切文档纸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆