import cv2
import numpy
import os
def cv_imread(file_path):
cv_img = cv2.imdecode(numpy.fromfile(file_path, dtype=numpy.uint8), -1)
return cv_img
def cv_imwrite(path ,img):
suffix = os.path.splitext(path)[-1]
cv2.imencode(suffix, img)[1].tofile(path)
Path = r"C:/Users/24385/Pictures/ControlCenter4/Scan/"
# 参数 根据自己的情况更改
kernelSize = 150
hsv_low = numpy.array([0, 0, 0])
hsv_high = numpy.array([255, 255, 245])
for fileName in os.listdir(Path):
img = cv_imread(Path + fileName)
padding = int(img.shape[1]/25)
img = cv2.copyMakeBorder(img, padding, padding, padding, padding,
cv2.BORDER_CONSTANT, value=[255, 255, 255])
dst = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # BGR转HSV
dst = cv2.inRange(dst, hsv_low, hsv_high) # 通过HSV的高低阈值,提取图像部分区域
# 开运算 先腐蚀再膨胀 去除毛刺
kernel = numpy.ones((kernelSize, kernelSize), dtype=numpy.uint8)
dst = cv2.morphologyEx(dst, cv2.MORPH_OPEN, kernel, 3)
img_debug = img.copy()
line_width = int(img.shape[1]/100)
# 找边缘
contours, hierarchy = cv2.findContours(dst, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 面积最大的区域
c = max(contours, key = cv2.contourArea)
# 用蓝色画出边缘
cv2.drawContours(img_debug, contours, -1, (255, 0, 0), line_width)
# 找出可包住面积最大区域的方框
x, y, w, h = cv2.boundingRect(c)
# 用绿色绘制方框
cv2.rectangle(img_debug,(x, y), (x + w, y + h), (0, 255, 0), line_width)
# 找出可包住面积最大区域的最小方框 红色绘制
rect = cv2.minAreaRect(c)
box = cv2.boxPoints(rect)
box = numpy.int0(box)
cv2.drawContours(img_debug, [box], 0, (0, 0, 255), line_width)
# 计算图片倾斜角度
angle = rect[2]
if angle < -45:
angle = 90 + angle
# 设定红框中心为旋转轴心 防止照片位置偏太多导致转出图片
w = box[0][0] + box[1][0] + box[2][0] + box[3][0]
h = box[0][1] + box[1][1] + box[2][1] + box[3][1]
center = (w // 4, h // 4)
# 计算旋转矩阵
M = cv2.getRotationMatrix2D(center, angle, 1.0)
# 旋转图片
(h, w) = img.shape[:2]
rotated = cv2.warpAffine(img_debug, M, (w, h),
flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_CONSTANT)
img_final = cv2.warpAffine(img, M, (w, h),
flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_CONSTANT)
# 旋转红框坐标
pts = numpy.int0(cv2.transform(numpy.array([box]), M))[0]
# 计算旋转后红框的范围
y_min = min(pts[0][0], pts[1][0], pts[2][0], pts[3][0])
y_max = max(pts[0][0], pts[1][0], pts[2][0], pts[3][0])
x_min = min(pts[0][1], pts[1][1], pts[2][1], pts[3][1])
x_max = max(pts[0][1], pts[1][1], pts[2][1], pts[3][1])
# 裁切图片
img_crop = rotated[x_min:x_max, y_min:y_max]
img_final = img_final[x_min-20:x_max+20, y_min-20:y_max+20]
# cv2.namedWindow('show',0)
# cv2.imshow('show', img_final)
# cv2.waitKey(0)
cv_imwrite(Path+"Cut_"+fileName,img_final)