前几天帮同专业的哥们扒他专业课课件里的截图文字,几百张图一张一张敲简直要疯,后来翻出吃灰半年的MATLAB,花了俩小时搭了个小工具,终于不用当人肉打字机了
MATLAB软件,图片文字识别,GUI界面,汉字和英文识别提取,匹配,写入txt中 中英文都可以,图片文字识别也可以
最开始我以为要自己写OCR模型调参数,结果翻了下MATLAB官方文档,发现R2019b之后直接内置了ocr函数,专门处理印刷体文字识别,完全不用自己造轮子。先试了单张图片的基础用法,代码超精简:
% 读取目标图片 img = imread("课件截图1.png"); % 调用内置OCR识别 ocrResults = ocr(img); % 直接输出识别结果 disp(ocrResults.Text); % 一键写入txt文件 writelines(ocrResults.Text, "单张识别结果.txt");这段代码跑起来几乎没门槛,就是读个图、扔给OCR函数、存结果。不过第一次踩坑了:拿手机拍的手写笔记试了下,识别率惨不忍睹,后来才反应过来自带的OCR对印刷体友好,手写的还是得换深度学习模型,不过咱们平时扒课件截图、扫描版论文,全是印刷体,完全够用。
后来觉得每次跑命令行太麻烦,就用MATLAB的App Designer搭了个可视化界面,拖拖拽拽就弄好了所有元素:放了个坐标轴显示图片预览,三个按钮分别是「选择单张图片」「批量选择图片」「开始识别」,一个下拉框选筛选类型(就是咱们要的匹配功能),一个大文本框显示识别结果,还加了个手动保存的按钮。
先给大家看选单张图片的回调代码,逻辑超简单:
function SelectImagePushed(app, event) % 弹出文件选择框,支持png/jpg/jpeg格式 [filename, pathname] = uigetfile({'*.png;*.jpg;*.jpeg', '图片文件 (*.png, *.jpg, *.jpeg)'}, '选择待识别图片'); if isequal(filename,0) return; % 用户点了取消就直接退出 end % 存下图片路径,后面识别要用 app.imgPath = fullfile(pathname, filename); % 在坐标轴里显示图片预览 img = imread(app.imgPath); imshow(img, app.UIAxes); end点了识别按钮之后,就会调用OCR函数,然后根据下拉框选的匹配类型筛选文字——这也是我做这个工具最实用的点:比如要只提取汉字,就用正则表达式匹配中文字符和中文标点;要只提取英文,就匹配英文字母、数字和常用英文标点,不用手动删来删去。核心代码如下:
function RecognizePushed(app, event) % 先判断有没有选图片 if ~isfield(app, 'imgPath') uialert(app.UIFigure, '请先选择图片!', '提示'); return; end img = imread(app.imgPath); % 加个预处理,提高暗图的识别率 img_gray = rgb2gray(img); img_bin = imbinarize(img_gray, 'adaptive'); ocrResults = ocr(img_bin); rawText = ocrResults.Text; % 核心匹配筛选逻辑 switch app.MatchTypeDropDown.Value case '仅汉字' % 匹配所有中文字符+中文标点 chineseText = regexp(rawText, '[\u4e00-\u9fa5,。、;:“”‘’()!?]+', 'match'); app.ResultTextArea.Value = strjoin(chineseText, ''); case '仅英文' % 匹配英文字母、数字、常用英文标点和空格 englishText = regexp(rawText, '[a-zA-Z0-9\s.,!?;:()\''"]+', 'match'); app.ResultTextArea.Value = strjoin(englishText, ''); otherwise % 直接输出全部识别结果 app.ResultTextArea.Value = rawText; end end这里的[\u4e00-\u9fa5]是Unicode里汉字的编码范围,加上常用中文标点的规则,就能精准把汉字和中文标点捞出来;英文那边的正则也覆盖了大部分日常用到的字符,完全够用。
MATLAB软件,图片文字识别,GUI界面,汉字和英文识别提取,匹配,写入txt中 中英文都可以,图片文字识别也可以
批量处理的逻辑也差不多,就是把单张处理改成循环,给每个图片生成单独的结果文件,还自动建了个OCR_Results文件夹存所有结果,不用手动整理:
function BatchRecognizePushed(app, event) [filenames, pathname] = uigetfile({'*.png;*.jpg;*.jpeg', '图片文件 (*.png, *.jpg, *.jpeg)'}, '批量选择待识别图片', 'MultiSelect', 'on'); if isequal(filenames,0) return; end % 自动创建保存文件夹 saveDir = fullfile(pathname, 'OCR_Results'); if ~exist(saveDir, 'dir') mkdir(saveDir); end for i = 1:length(filenames) imgPath = fullfile(pathname, filenames{i}); img = imread(imgPath); img_gray = rgb2gray(img); img_bin = imbinarize(img_gray, 'adaptive'); ocrResults = ocr(img_bin); rawText = ocrResults.Text; % 同样用匹配筛选逻辑 switch app.MatchTypeDropDown.Value case '仅汉字' chineseText = regexp(rawText, '[\u4e00-\u9fa5,。、;:“”‘’()!?]+', 'match'); textOut = strjoin(chineseText, ''); case '仅英文' englishText = regexp(rawText, '[a-zA-Z0-9\s.,!?;:()\''"]+', 'match'); textOut = strjoin(englishText, ''); otherwise textOut = rawText; end % 用原图片名生成对应的结果文件 [~, name, ~] = fileparts(filenames{i}); writelines(textOut, fullfile(saveDir, [name '_OCR结果.txt'])); end uialert(app.UIFigure, ['批量识别完成!结果已保存到:' saveDir], '完成'); end上次帮哥们处理300多张课件截图,跑批量的时候我就去摸鱼了,回来直接去文件夹里拿结果,连整理都省了,他还给我带了杯奶茶,血赚(不是)。
最后提一嘴,要是不想每次都开MATLAB跑代码,还能用MATLAB自带的deploytool把这个APP打包成独立的exe文件,发给不用装MATLAB的朋友也能直接用,就是打包的时候会有点慢,不过胜在方便。
其实这个小工具还能加不少功能,比如识别表格里的文字、支持手写体识别、加个关键词搜索之类的,不过目前用来扒课件截图已经完全够用了。反正现在我是再也不想当人肉打字机了。
