首页 > 其他分享 >仿照“全能扫描王”的图像增强-由原理到实现

仿照“全能扫描王”的图像增强-由原理到实现

时间:2022-12-20 19:11:33浏览次数:68  
标签:src 全能 dst src2 混合色 仿照 array 图像增强 基色

一、算法目标: 实现这种背景去除增强的效果,特别是在“全能扫描王”中该算法得到了典型的应用。

 

 

二、使用PS进行模拟 图像处理算法很多时候就是对成熟经验的模拟和复现。首先我们来看PS下的处理。   1.手机拍一张需要电子版的纸质文件:

 

 

  2.打开PS,复制背景,得到图层1:  

 

 

3.对图层1使用滤镜:高斯模糊,半径100像素:  

 

 

4.改变图层1混合模式:划分:

 

 

  5.添加曲线调整层,压暗文字:  

 

 

6.合并可见图层。   7.柔角画笔擦掉彩色噪点和边缘露出的拍摄背景:   那么,这个效果的确实很好的,关键问题就是“划分”是什么操作? PS中划分模式的计算公式:
结果色 = (基色 / 混合色) * 255。 分析每个颜色通道的数值,并用基色分割混合色,基色数值大于或等于混合色数值,混合出的颜色为白色。基色数值小于混合色,结果色比基色更暗。因此结果色对比非常强。
两个一样的图层(复制基色图层),图层混合模式改为划分结果色就是白色
混合色为白色,结果色就是基色;混合色为黑色,结果色就是白色;
公式验证:r值(255/79)*255=823;结果色大于255,系统就默认为最大值255;以公式推断基色数值大于或等于混合色数值,混合出的颜色为白色。

 

 

 

 

 

 


  三、整理流程,转换为代码  
图像A,B,为同一场景在不一样的光照拍摄图片,那么:
光照分布 L = A / B
如果已知 A, L ,则 B = A / L (B 为A去光照的结果)
这里L约等于 gaussFilter(A, 大核)

 

  再进一步转换为代码:  
    Mat src = imread("t1.jpeg");
    src.convertTo(src,CV_32FC3,1.0/255);
    Mat gauss;
    Mat dst = src.clone();
    cv::GaussianBlur(src,gauss,Size(101,101),0);
    
    //划分
    //如果混合色与基色相同则结果色为白色
    //如混合色为白色则结果色为基色不变
    //如混合色为黑色则结果色为白色
    dst = src/gauss;
    waitKey();
 

 

 

在这个基础上,进一步进行封装:  
//USM图像增
void ImageSharp(Mat &src,Mat &dst,int nAmount = 1000)
{
    double sigma = 3;  
    int threshold = 1;  
    float amount = nAmount/100.0f;  
    Mat imgBlurred;
    GaussianBlur(src, imgBlurred, Size(), sigma, sigma);
    Mat lowContrastMask = abs(src-imgBlurred)<threshold;
    dst = src*(1+amount)+imgBlurred*(-amount);
    src.copyTo(dst, lowContrastMask);
}

int main()
{
    Mat src = imread("E:\\未来项目\\白板增强\\images\\t1.jpeg");
    src.convertTo(src,CV_32FC3,1.0/255);
    Mat gauss;
    Mat dst1 = src.clone();
    Mat dst2 = src.clone();
    cv::GaussianBlur(src,gauss,Size(101,101),0);
    dst1 = src/gauss;
    blur(src,gauss,Size(101,101));
    dst2 = src/gauss;
    //划分
    ImageSharp(dst2,dst2,101);
    waitKey();
    return 0;
}
效果更好

 

 

  四、原理解析 算法的效果不错,下一步就是要分析为什么了。 关键点在于blur的话就可以思考得更清楚了,在101*101的格子里面算平均值,然后前景和其进行比较,对于那些有字的,肯定是小于平均值,关键是对于背景,肯定大于平均值,这样一除就变成了全白,问题也就清楚了。 我也找到了ImageShop作者对这个算法的分析,他是专门做增强的,分析的比较有道理:

“这个算法在此类图像中能够成功的核心是:在原图中比较黑的文字部分,占用的整体是比较少的,当大半径模糊时,模糊的值是接近纸张之类的颜色的,也就是比较靠近白色,所以结果基本上没什么变化,而纸张那些地方的颜色,因为模糊的值和他们的原始值基本差不多,所以Src/Blur基本接近1,在乘以255,所以结果就变为白色了。” 

五、补充材料 1、发现OpenCV自带Divide算法,未进一步检测,我自信目前的解决是不错的。
divide
Performs per-element division of two arrays or a scalar by an array.
C++: void divide(InputArray src1, InputArray src2, OutputArray dst, double scale=1, int dtype=-1)
C++: void divide(double scale, InputArray src2, OutputArray dst, int dtype=-1)
Python: cv2.divide(src1, src2[, dst[, scale[, dtype]]]) → dst
Python: cv2.divide(scale, src2[, dst[, dtype]]) → dst
C: void cvDiv(const CvArr* src1, const CvArr* src2, CvArr* dst, double scale=1)
Python: cv.Div(src1, src2, dst, scale=1) → None
Parameters:   
src1 – first input array.
src2 – second input array of the same size and type as src1.
scale – scalar factor.
dst – output array of the same size and type as src2.
dtype – optional depth of the output array; if -1, dst will have depth src2.depth(), but in case of an array-by-array division, you can only pass -1 when src1.depth()==src2.depth().
The functions divide divide one array by another:
or a scalar by an array when there is no src1 :
When src2(I) is zero, dst(I) will also be zero. Different channels of multi-channel arrays are processed independently.
2、【工程应用三】三种不同的文本图像背景漂白/纯化/去除算法。 - Imageshop - 博客园 (cnblogs.com) 3、https://blog.csdn.net/pleasecallmewhy/article/details/8776998 4、机器视觉+图像算法 (https://home.cnblogs.com/u/cvdream/)    

标签:src,全能,dst,src2,混合色,仿照,array,图像增强,基色
From: https://www.cnblogs.com/jsxyhelu/p/16994909.html

相关文章