快速照片扫描方法记录
方法 快速 记录 扫描 照片
2023-06-13 09:12:50 时间
假期找了点时间把家里的老照片都扫成了电子版,下面记录一下简单快捷的照片扫描方法
法1
因为不太清楚photoshop有自动裁切的功能,所以我最开始花了一个小时多写了一个小程序帮我自动裁切扫描出来的影像的白边。
原图:
裁切后:
额外预留的一些白边,总体效果还行。
程序用到了 python + opencv + numpy,基本可以满足我个人需求。
总体思路:
- 先将图片从 RGB 空间转为 HSV 空间
- 通过调整阈值找到图片所在的大致位置(兴趣区域),并二值化
- 开运算(先腐蚀再膨胀)以去除毛刺和噪点
- 找出二值化后图形的边缘
- 找出包裹最大面积的边缘
- 找出可包住上步面积的最小的方框
- 计算方框倾斜角度
- 根据方框倾斜角度矫正图片倾斜
- 计算旋转后的方框范围并切割图片
下面是我的程序:
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)
法2
首先打开 -》窗口 -》 动作
先录制一套宏:
点记录,然后做一整套操作,再点击白色方形结束录制,完成后如图:
之后在 Photoshop 中 -》 文件 -》 自动 -》 批处理
然后按如下图配置:
记住要勾选“覆盖动作中的打开命令”和“覆盖动作中的储存为命令”
文件命名部分根据个人喜好进行命名,这是我自己个人的喜好,仅供参照。
完成设置后点击确定就好
比较
Photoshop 的自动化固然更加小白,但是我个人使用起来的话还是自己客制化的程序更加好用(参数可以根据照片的特征进行调整),裁切也较为准确
Photoshop在这种老照片的裁切中还是存在切歪的情况(在大多数情况下裁切还是很准确的,下面是我的程序切不好的几张图片拿给 Photoshop 切的效果):
相关文章
- ognl和el表达式有什么区别-struts2 调用OGNL表达式使用方法(EL废弃)
- 在写左关联时SQL语句出现 Duplicate column name 'NAME'名字重复错误解决方法
- 空格 在不同浏览器中显示距离不一致问题解决方法详解编程语言
- Linux快速生成大文件的方法(linux生成大文件)
- Linux软件快速安装指南(linux软件安装方法)
- Linux改变所属组:快速实现方法(linux改变所属组)
- Oracle中创建连续数字序列的方法(oracle连续数字)
- Linux下快速删除文件的方法(linux上删除文件)
- MySQL快速插入多个记录的方法(mysql插入多条记录)
- Linux网络配置教程:快速连接VPN的方法(linux如何连接vpn)
- 快速实现MySQL数据库导出的方法!(mysql导出全部数据库)
- “Linux轻松与Windows双启:引导快速添加方法”(linux添加windows引导)
- 快速获取Oracle数据库中单个记录的方法(oracle返回一条记录)
- MySQL中快速清空表的方法(mysql快速清空表)
- Linux网络文件配置简单方法示范(linux配置网络文件)
- Linux轻松上手:一种实现快速入门的例程方法(linux例程)
- Linux服务启动命令:快速掌握开机自启与手动启动的方法!(linux服务启动命令)
- 快速实现Linux数据库重启方法(linux 重启数据库)
- Linux系统快速输入汉字的好方法(linux打汉字)
- Linux快速安全保存只读文件的方法(linux保存只读文件)
- 快速进入Redis客户端的方法(怎么进入redis客户端)
- android之自定义Toast使用方法
- 单台服务器的PHP进程之间实现共享内存的方法
- 80端口被Pid为4的未知程序占用导致Apache不能启动的解决方法
- node.js中的fs.truncate方法使用说明