[英]Rotate image in python and remove the background
有沒有辦法旋轉這些類型的圖像並刪除背景空白或任何背景並像這樣獲取和圖像
如果圖像沒有任何旋轉,我嘗試刪除背景我可以使用此腳本刪除背景空白,但如果圖像有任何旋轉,它不會刪除任何空間我遵循這個如何裁剪或刪除白色圖像的背景
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)
請嘗試使用任何掃描的圖像並旋轉它並嘗試擺脫背景空白並將其旋轉到其原始尺寸以進行計算機視覺操作
使用cv2.boundingRect將為您提供適合輪廓的最小非旋轉矩形。 cv2.boundingRect結果:
而不是cv2.boundingRect ,您將需要使用cv2.minAreaRect來獲得適合輪廓的矩形。 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)
結果 :
如果保證背景是飽和白色(值 255)並且文檔大部分是不飽和值,則在閾值 255 以下進行二值化並擬合邊界矩形。
我在運行上面提供的代碼時遇到了一些問題,所以這是我稍微修改過的版本:
import cv2
import numpy as np
def crop_minAreaRect(img, rect):
# rotate img
angle = rect[2]
print("angle: " + str(angle))
rows,cols = img.shape[0], img.shape[1]
M = cv2.getRotationMatrix2D((cols/2,rows/2),angle,1)
img_rot = cv2.warpAffine(img,M,(cols,rows))
# rotate bounding box
rect0 = (rect[0], rect[1], angle)
box = cv2.boxPoints(rect0)
pts = np.int0(cv2.transform(np.array([box]), M))[0]
pts[pts < 0] = 0
# crop
img_crop = img_rot[pts[1][1]:pts[0][1],
pts[1][0]:pts[2][0]]
return img_crop
def ResizeWithAspectRatio(image, width=None, height=None, inter=cv2.INTER_AREA):
dim = None
(h, w) = image.shape[:2]
if width is None and height is None:
return image
if width is None:
r = height / float(h)
dim = (int(w * r), height)
else:
r = width / float(w)
dim = (width, int(h * r))
return cv2.resize(image, dim, interpolation=inter)
img = cv2.imread('rotatedCheque.png')
cv2.imshow("orig", img)
img_copy = img.copy()
# (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)
cropped_img = crop_minAreaRect(img, rot_rect)
width, height = img.shape[0], img.shape[1]
if height > width:
cropped_img = cv2.rotate(cropped_img, cv2.ROTATE_90_CLOCKWISE)
resized_img = ResizeWithAspectRatio(cropped_img, width=800)
cv2.imshow("cropped", resized_img)
cv2.waitKey(0)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.