文档图片阴影去除

news/2024/11/16 20:46:50/

文章目录

  • 一、前言
  • 二、通过 Gamma 校正来去除阴影 (旧方法)
    • 2.1 原理
    • 2.2 C++ 代码
    • 2.3 运行结果对比图
  • 三、通过自适应阈值化来去除阴影 (新方法)
    • 3.1 原理
    • 3.2 代码
    • 3.3 运行结果对比图
  • 四、新旧方法对比图
  • 五、BEDSR-Net 去除阴影 (模型)

一、前言

在 OCR 的预处理中需要对文档图片中有阴影的部分进行消除, 在此之前使用过图像增强的算法对其进行处理, 本质就是二值化的处理.

在这篇文章中使用了新的方法进行处理, 并且将新方法和老方法之间进行了对比. 在文章最后还有使用模型对图片进行处理的效果.

二、通过 Gamma 校正来去除阴影 (旧方法)

这是之前使用的旧方法, 但是在移植到安卓的时候的时候出现了问题.

2.1 原理

对图片进行二值化处理之后, 会产生黑色的噪声, Gamma 矫正其实是对二值化后的图片进行一个对比度的增强.

2.2 C++ 代码

#include <opencv.hpp>using namespace std;
using namespace cv;//Gamma校正 fGamaa=0.45是常用值
void GammaCorrection(Mat& src, Mat& dst, float fGamma)
{CV_Assert(src.data);// accept only char type matricesCV_Assert(src.depth() != sizeof(uchar));// build look up tableunsigned char lut[256];for (int i = 0; i < 256; i++){lut[i] = saturate_cast<uchar>(pow((float)(i / 255.0), fGamma) * 255.0f);}dst = src.clone();const int channels = dst.channels();switch (channels){case 1:{MatIterator_<uchar> it, end;for (it = dst.begin<uchar>(), end = dst.end<uchar>(); it != end; it++)*it = lut[(*it)];break;}case 3:{MatIterator_<Vec3b> it, end;for (it = dst.begin<Vec3b>(), end = dst.end<Vec3b>(); it != end; it++){(*it)[0] = lut[((*it)[0])];(*it)[1] = lut[((*it)[1])];(*it)[2] = lut[((*it)[2])];}break;}}
}int main(int argc, char** argv)
{string addr = "C:\\Users\\YSXCC\\Desktop\\test.jpg";Mat image = imread(addr);//划分算法//如果混合色与基色相同则结果色为白色//如混合色为白色则结果色为基色不变//如混合色为黑色则结果色为白色Mat src = image.clone();src.convertTo(src, CV_32FC3, 1.0 / 255);Mat gauss;Mat dst = src.clone();GaussianBlur(src, gauss, Size(101, 101), 0);dst = src / gauss;dst.convertTo(dst, CV_8UC3, 255);//gamma变换Mat ss;Mat matGamma;ss = dst.clone();GammaCorrection(ss, matGamma, 1.5);//显示最终结果imwrite("C:\\Users\\YSXCC\\Desktop\\test_out.jpg", matGamma);return 0;
}

2.3 运行结果对比图

三、通过自适应阈值化来去除阴影 (新方法)

这部分代码来自以下博客,感谢博主提供的方法.
https://blog.csdn.net/yohnyang/article/details/127295751

3.1 原理

自适应阈值, 则是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值. 这样做的好处:

  1. 每个像素位置处的二值化阈值不是固定不变的, 而是由其周围邻域像素的分布来决定的.

  2. 亮度较高的图像区域的二值化阈值通常会较高, 而亮度低的图像区域的二值化阈值则会相适应的变小.

  3. 不同亮度、对比度、纹理的局部图像区域将会拥有相对应的局部二值化阈值.

3.2 代码

#include <opencv.hpp>
#include <iostream>
#include <string>using namespace cv;
using namespace std;Mat ImageSharp(const Mat& src, int nAmount) {Mat dst;double sigma = 3;float amount = nAmount / 100.0f;Mat imgBlurred;cv::GaussianBlur(src, imgBlurred, cv::Size(7, 7), sigma, sigma, 4);Mat temp_sub;cv::subtract(src, imgBlurred, temp_sub);cv::addWeighted(src, 1, temp_sub, amount, 0, dst);return dst;
}Mat ReduceBackGroundAlgorithm(const Mat& src, int flag) {Mat gauss, dst2, dst3;if (flag == 1) {cv::GaussianBlur(src, gauss, cv::Size(31, 31), 0, 0, 4);}else {cv::blur(src, gauss, cv::Size(101, 101));}cv::divide(src, gauss, dst2);dst2 = ImageSharp(dst2, 101);dst2.convertTo(dst3, CV_8UC1, 255);return dst3;
}std::vector<string> readImgs(const string& path) {vector<string> img_path;vector<cv::String> fn;glob(path, fn, false);size_t count = fn.size();for (size_t i = 0; i < count; i++) {img_path.push_back(fn[i]);}return img_path;
}void showImg(const::cv::Mat& img, std::string& w_name) {CV_Assert(!img.empty());cv::namedWindow(w_name, cv::WINDOW_NORMAL);cv::imshow(w_name, img);
}void getbw(const cv::Mat& src, Mat& dst, double th = 15) {cv::Mat img_src = src.clone();if (img_src.cols < 1500) {resize(img_src, img_src, img_src.size() * 2, 0, 0, cv::INTER_CUBIC);}Mat gray, res, res1;cv::cvtColor(img_src, gray, COLOR_BGR2GRAY);cv::adaptiveThreshold(gray, res, 255, ADAPTIVE_THRESH_MEAN_C, 0, 31, th);res.convertTo(res1, CV_32FC1, 1.0 / 255);dst = ReduceBackGroundAlgorithm(res1, 1);
}int main(int argc, char const* argv[])
{string path = "C:\\Users\\YSXCC\\Desktop\\test.jpg";string save_path = "C:\\Users\\YSXCC\\Desktop\\result";std::vector<string> imgs = readImgs(path);for (int i = 0; i < imgs.size(); i++) {Mat src = imread(imgs[i]);if (src.empty()) {return -1;}std::cout << i << " - " << src.size() << std::endl;cv::Mat result;getbw(src, result);string save_filename = save_path + "res_" + to_string(i) + ".png";cv::imwrite(save_filename, result);std::cout << "finish " + std::to_string(i) << std::endl;}waitKey(27);return 0;
}

3.3 运行结果对比图

四、新旧方法对比图

左边为旧方法的效果图, 右边为新方法的效果图

可以观察到, 新方法处理图片后会在图片中留下明显黑点。

当阴影部分非常严重, 甚至整张图片光线偏暗的时候, 新方法效果就会变差. 原图如下所示:

对比图如下所示:

新方法对阴影严重的图片处理后效果不及旧方法. 可以发现旧方法处理图片后会留下很明显的边框, 新方法则使得阴影下的文字不可识别, 且还是会有明显边框.

五、BEDSR-Net 去除阴影 (模型)


http://www.ppmy.cn/news/886304.html

相关文章

div 边框阴影

div边框加阴影效果,求高手帮忙~ 浏览次数&#xff1a;60次悬赏分&#xff1a;0 | 解决时间&#xff1a;2011-8-10 15:39 | 提问者&#xff1a;zmjailwy 在css样式里建了.mydiv{ width:500px;height:auto;border:#909090 1px solid;background:#fff;color:#333; filter:progi…

WEB前端代码:边框阴影、边框图片、背景样式、文本样式、字体样式

1、边框阴影 box-shadow:5px 10px 20px #000; 1)5px 相对于原div的左上角的x偏移 2)10px 相对于原div的左上角的y偏移 3)20px 在偏移的基础上进行模糊处理 4)#000 阴影div的颜色 .div1{margin:100px;width:256px;height:256px;background: #888;box-shadow:15px 15px 30px #00…

Microsoft Word 教程:如何在 Word 中插入艺术字?

欢迎观看 Microsoft Word 教程&#xff0c;小编带大家学习 Microsoft Word 的使用技巧&#xff0c;了解如何在 Word 中插入艺术字。 创建和更改艺术字&#xff0c;如果想让文本在页面上引人注目&#xff0c;可以使用艺术字向文字添加轮廓、阴影和其他效果。 选择「插入」-「文…

Word线条边框和表格的应用

用Word进行编辑的时候,需要使用线条、边框和表格进行美化, 1.下划线: 编辑试卷的填空题时要使用下划线做空格,我们可以先输入一些空格,然后选中这些空格,在给空格设置横线为下划线就可以了。 2.文字边框 首先选择要使用边框的文字,选择“格式”菜单下的“边框和底纹”选…

计算机应用基础蓝色方框在哪,word段落设置3磅蓝色单线边框并加底纹怎...

2016-08-10 19:31龚家逵 客户经理 表格,设置单元格对齐方式为中部居中。 ③单击“李甲”平均成绩单元格,单击“表格”→“公式”,在弹出的“公式”对话框的“公式”框中输入AVERAGE(LEFT),保留两位小数,单击“确定”按钮。同样方法输入其他人的平均成绩。 ④保存文件。 3、…

Word水印为计算机红色水平,Word 大一计算机考试操作题

(1)页面设置为A4纸&#xff0c;上下左右页边距2.5cm&#xff1b; 打开菜单&#xff1a;“文件”->”页面设置”- 选“纸张”选项卡—从“页面大小”下拉列表框中选择”A4”----选择“页边距”选项卡-----在 “页边距”栏下分别设置“左”“右”为“2.5厘米”。 (2)标题使用艺…

计算机实验word,实验六计算机基础——word段落设置

实验六计算机基础——word段落设置 (5页) 本资源提供全文预览&#xff0c;点击全文预览即可全文预览,如果喜欢文档就下载吧&#xff0c;查找使用更方便哦&#xff01; 14.90 积分 WORD编辑排版实验六 WORD段落设置一&#xff0e;实验目的1&#xff0e;掌握Word文档基本操作2&a…

HCIA配置命令集

目录 扩展 交换机 路由器 路由器网关配置 DHCP服务器 Telnet &#xff1a;远程登录协议 静态路由配置 动态路由 OSPF RIP NAT—网络地址转换 ACL—访问控制列表 ACL的分类&#xff1a; 配置 配置基础ACL &#xff1a; 例一&#xff1a; 例二&#xff1a; 配…