在python中旋转图像并移除背景

在python中旋转图像并移除背景,python,python-3.x,opencv,image-processing,computer-vision,Python,Python 3.x,Opencv,Image Processing,Computer Vision,有没有一种方法可以旋转这些类型的图像,删除背景空白或任何背景,得到这样的图像 我试图删除背景,如果图像没有任何旋转,我可以使用此脚本删除背景空白,但如果图像有任何旋转,它不会删除任何空间 我跟着这个 请尝试使用任何扫描图像并旋转它,尝试去除背景空白并将其旋转到原始尺寸以进行计算机视觉操作考虑到您不知道旋转角度,并且每个扫描图像的旋转角度可能不同,您需要先找到它 把你们已经做过的事情和问题的答案结合起来 对于您提供的图像: Angle is -25.953375702364195 如果保证背景

有没有一种方法可以旋转这些类型的图像,删除背景空白或任何背景,得到这样的图像

我试图删除背景,如果图像没有任何旋转,我可以使用此脚本删除背景空白,但如果图像有任何旋转,它不会删除任何空间 我跟着这个


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

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

把你们已经做过的事情和问题的答案结合起来

对于您提供的图像:

Angle is -25.953375702364195

如果保证背景为饱和白色(值255)且文档大部分为非饱和值,则在阈值255以下进行二值化并拟合一个边框。

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

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

在获得旋转的rect信息后,需要找到模型点和当前点之间的仿射变换矩阵。当前点是在旋转矩形中找到的点,模型点是原始对象的点。在本例中,对象的初始位置(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) 
结果:


尝试使用透视变换。文档链接:@VardanAgarwal问题是,不同图片的图像坐标可能不同,我想你应该问的问题是“如何找到文档角落的坐标”。剩下的工作很简单。@YvesDaoust我怎样才能找到动态图像的坐标,是的!你看了吗?请分享一些文档,我在哪里可以做到,谢谢you@DataDoctor:OpenCV。它使用上述代码旋转图像,但不删除空白。感谢您提供第1部分解决方案。我收到此错误,我使用的是open cv>4.0`wrap_gray=cv2。warpAffine(gray,M,(int(sx),int(sy)))TypeError:参数“%s”应为Ptr`是否可以尝试对灰色变量使用cv2.umat()进行类型转换?i、 我试过这个,也试过这个img=cv2.umat(cv2.jpg,cv2.imread\u COLOR))imgUMat=cv2.umat(cv2.imread(“image.jpg,cv2.imread\u COLOR”)。imgUMat=cv2.umat(img)gray=cv2.cvtColor(imgUMat,cv2.COLOR\u BGR2GRAY)还有这个gray=cv2.cvtColor(cv2.umat(img),cv2.umat(img),cv2.COLOR\bgry)即使进行了修改,你也会得到同样的错误?是的,我想这与warpAffine函数有关,因为使用相同的代码(不包括warpAffine),我可以得到图像响应。
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)