Python切图脚本

背景:

时值疫情,作业需要在网上提交。最近老师改变了交作业方式,之前是提交完整的作业图片即可,现在需要将完整的作业图片切分成一题一题的提交,如果手动切分较麻烦,故本人写了个python脚本实现自动切分。

程序:

import cv2
import numpy as np

img = cv2.imread('20200302092016.jpg')
rmb = np.int32(img[:, :, 2]) - np.int32(img[:, :, 0]) > 40
rmg = np.int32(img[:, :, 2]) - np.int32(img[:, :, 1]) > 40
rp = np.where(np.logical_and(rmb, rmg))
s = 0
n = 0
for i in rp[0]:
    if i - s > 100:
        cv2.imwrite(f'output{n}.jpg', cv2.resize(img[s:i], (0, 0), fx=0.25, fy=0.25))
        n += 1
        s = i
cv2.imwrite(f'output{n}.jpg', cv2.resize(img[s:], (0, 0), fx=0.25, fy=0.25))

用法:

  • 第一步:在作业中题目与题目之间的间隙用笔点上一个小点,用来标明切分位置,如图:

  • 第二步:用相机将作业拍下来,注意一张图片一页,且尽量保持画面水平,因为切图是水平切的。
  • 第三步:将图片传到电脑,对脚本进行必要的修改,其中:
    • 20200302092016.jpg 是图片的文件名,路径和文件名不能有中文
    • 两个40 表示该点红色通道比蓝色和绿色通道大多少,如果你发现你的红点没被识别,可以适当缩小这两个值,如果把其他的点识别成红点了,可以适当调大这个值;
    • 100 表示单道题目在图片中的“高度”至少为多少,如果你发现有的题目消失了,可以适当调小这个值,但必须保证这个值大于红点在图片中的“高度”;
    • 四个0.25 表示输出图片是否需要放缩,0.25表示缩小为原来的4倍,如果不需要放缩可以把0.25都改为1。
  • 第四步:运行脚本(需要安装Python库Numpy和OpenCV),输出的文件名以output开头的图片就是切分得到的图片。

总结:

  • 图片的像素值需要转换成int32,因为原来是unsigned byte,相减后如果是负数会溢出。numpy底层是C语言实现的,所以需要考虑溢出问题。
  • 对numpy数组进行逻辑与操作需要用函数numpy.logical_and 不能直接用and 运算符。
  • numpy.where 只以一个数组做参数时返回的是一个元组,元组第i个元素储存原数组中值为1的元素的第i维坐标。
posted @ 2020-06-09 10:12  YuanZiming  阅读(598)  评论(0编辑  收藏  举报