0
点赞
收藏
分享

微信扫一扫

Python 基于open cv实现答题卡区域轮廓裁剪


答题卡模板扫描后图片: 

Python 基于open cv实现答题卡区域轮廓裁剪_图像平滑

识别裁剪后图片:

Python 基于open cv实现答题卡区域轮廓裁剪_图像平滑_02

 

import cv2

class CutImg:
"""
识别答题卡答题区域工具类

资料: https://weread.qq.com/web/reader/30232de0719146363020e69kc81322c012c81e728d9d180

处理过程:
1. 读取图片
2. 图像平滑处理
3. 图像阈值处理
4. 图像轮廓
5. 裁剪对比原图面积比在 小于0.8 大于0.05 图像保留

暂留代码块
# 中值滤波
# thd1 = cv2.medianBlur(thd1, 7)
# cv2.imshow('mediu', thd1)
# cv2.waitKey(0)

# 查找轮廓
# cnts, hierarchy = cv2.findContours(thd1, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
# img = cv2.drawContours(image, cnts, -1, (0, 0, 255), 3)
# cv2.imshow('hierarchy', img)
# cv2.waitKey(0)

"""

def __init__(self, path):
"""
@param path: 待处理答题卡图片路径
"""
self.img_data = cv2.imread(path, 0)
self.process_img = None # 处理中答题卡图片数据

def process(self):
"""
图像平滑处理
图像阈值处理
@return:
"""
# retval代表返回的阈值 dst代表阈值分割结果图像,与原始图像具有相同的大小和类型
# thresh代表要设定的阈值
# maxval代表当type参数为THRESH_BINARY或者THRESH_BINARY_INV类型时,需要设定的最大值
retval, dst = cv2.threshold(self.img_data, thresh=250, maxval=255, type=cv2.THRESH_BINARY)
# 图像平滑处理: 高斯滤波
# ksize是滤波核的大小。滤波核大小是指在滤波处理过程中其邻域图像的高度和宽度。需要注意,滤波核的值必须是奇数
dst = cv2.GaussianBlur(dst, ksize=(31, 31), sigmaX=0, sigmaY=0)
# 针对图像平滑处理再次阈值处理
retval, dst = cv2.threshold(dst, 250, 255, cv2.THRESH_BINARY)

self.process_img = dst
return self

def save(self):
"""
保存答题区域
图像轮廓
裁剪对比原图面积比在 小于0.8 大于0.05 图像保留

@todo 可以将裁剪图片转成字节流转base64 保存数据库, 前端将base64转换成图片格式
@return:
"""
# cv2.RETR_CCOMP 检索所有轮廓并将它们组织成两级层次结构
cnts, hierarchy = cv2.findContours(self.process_img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
for c, i in zip(cnts, hierarchy[0]):
x, y, w, h = cv2.boundingRect(c) # 包覆此轮廓的最小正矩形
ROI = self.img_data[y:y + h, x:x + w]
if 0.8 > ROI.size / self.img_data.size > 0.05: # 小于0.8 大于0.05面积比=>图像保留
cv2.imwrite("/home/chentong/test/tmp/{}.png".format(i), ROI)


if __name__ == '__main__':
import time
s = time.time()
path = "WX20201202-161308@2x.png" # 读取图像文件夹
for _ in range(1000):
c = CutImg(path)
c.process().save()
print(time.time()-s)

 

举报

相关推荐

0 条评论