【问题标题】:Rotate image in python and remove the background在python中旋转图像并删除背景
【发布时间】:2020-04-22 18:10:28
【问题描述】:

有没有办法旋转这些类型的图像并删除背景空白或任何背景并获得这样的图像

如果图像没有任何旋转,我尝试删除背景我可以使用此脚本删除背景空白,但如果图像有任何旋转,它不会删除任何空间 我关注了这个How to crop or remove white background from an image

import cv2
import numpy as np

img = cv2.imread('cheque_img\rotate.PNG')
## (1) Convert to gray, and threshold
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
th, threshed = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV)

## (2) Morph-op to remove noise
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
morphed = cv2.morphologyEx(threshed, cv2.MORPH_CLOSE, kernel)

## (3) Find the max-area contour
cnts = cv2.findContours(morphed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
cnt = sorted(cnts, key=cv2.contourArea)[-1]

## (4) Crop and save it
x,y,w,h = cv2.boundingRect(cnt)
dst = img[y:y+h, x:x+w]
cv2.imwrite("001.png", dst) 

请尝试使用任何扫描的图像并旋转它,并尝试摆脱背景空白并将其旋转到其原始尺寸以进行计算机视觉操作

【问题讨论】:

标签: python python-3.x opencv image-processing computer-vision


【解决方案1】:

考虑到您不知道旋转的角度,并且每个扫描的图像可能不同,您需要先找到它。

将您已经完成的操作与this 问题的已接受答案结合起来。

对于您提供的图片:

Angle is -25.953375702364195

【讨论】:

  • 它会旋转图像,但不会使用上面的代码删除空白。感谢您提供第 1 部分的解决方案
【解决方案2】:

如果保证背景是饱和白色(值 255)并且文档大部分是不饱和值,则在阈值 255 以下进行二值化并拟合边界矩形。

【讨论】:

  • 请分享一些文档,我在哪里可以这样做,谢谢
  • @DataDoctor: OpenCV.
【解决方案3】:

使用 cv2.boundingRect 将为您提供适合轮廓的最小非旋转矩形。 cv2.boundingRect 结果:

您需要使用 cv2.minAreaRect 而不是 cv2.boundingRect 来获得适合轮廓的矩形。 cv2.minAreaRect 结果:

获取旋转后的矩形信息后,需要找到模型点与当前点之间的仿射变换矩阵。当前点是在旋转矩形中找到的点,模型点是原始对象的点。在这种情况下,对象具有初始位置 (0,0) 和旋转矩形的宽度和高度。

仿射在这里可能有点过头了,但一般来说使用仿射变换。

详细解释位于代码中。

import cv2
import numpy as np

img = cv2.imread('Bcm3h.png')

## (1) Convert to gray, and threshold
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
th, threshed = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV)


## (2) Morph-op to remove noise
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
morphed = cv2.morphologyEx(threshed, cv2.MORPH_CLOSE, kernel)

## (3) Find the max-area contour
cnts = cv2.findContours(morphed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
cnt = sorted(cnts, key=cv2.contourArea)[-1]


## This will extract the rotated rect from the contour
rot_rect = cv2.minAreaRect(cnt)

# Extract useful data
cx,cy = (rot_rect[0][0], rot_rect[0][1]) # rect center
sx,sy = (rot_rect[1][0], rot_rect[1][1]) # rect size
angle = rot_rect[2] # rect angle


# Set model points : The original shape
model_pts = np.array([[0,sy],[0,0],[sx,0],[sx,sy]]).astype('int')
# Set detected points : Points on the image
current_pts = cv2.boxPoints(rot_rect).astype('int')

# sort the points to ensure match between model points and current points
ind_model = np.lexsort((model_pts[:,1],model_pts[:,0]))
ind_current = np.lexsort((current_pts[:,1],current_pts[:,0]))

model_pts = np.array([model_pts[i] for i in ind_model])
current_pts = np.array([current_pts[i] for i in ind_current])


# Estimate the transform betwee points
M = cv2.estimateRigidTransform(current_pts,model_pts,True)

# Wrap the image
wrap_gray = cv2.warpAffine(gray, M, (int(sx),int(sy)))


# for display
cv2.imshow("dst",wrap_gray)
cv2.waitKey(0)

#cv2.imwrite("001.png", dst) 

结果:

【讨论】:

  • 我收到此错误,我正在使用 open-cv > 4.0 ` wrap_gray = cv2.warpAffine(gray, M, (int(sx),int(sy))) TypeError: Expected Ptr 用于参数 '%s' `
  • 您可以尝试在 gray 变量上使用 cv2.umat() 进行类型转换吗?即 wrap_gray = cv2.warpAffine(cv2.umat(gray), M, (int(sx),int(sy)))
  • 我试过了,也试过了 img = cv2.UMat(cv2.imread("image.jpg", cv2.IMREAD_COLOR)) imgUMat = cv2.UMat(img) gray = cv2.cvtColor (imgUMat, cv2.COLOR_BGR2GRAY) 还有这个灰色 = cv2.cvtColor(cv2.umat(img), cv2.COLOR_BGR2GRAY)
  • 即使修改了也会出现同样的错误?
  • 是的,我想它与 warpAffine 函数有关,因为使用相同的代码,除了 warpAffine 我可以获得图像响应。
猜你喜欢
  • 2020-12-11
  • 2013-01-15
  • 2020-11-10
  • 1970-01-01
  • 2018-09-05
  • 2011-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多