AIStudio扫描王实现与原理详解

★★★ 本文源自AI Studio社区精品项目,【点击此处】查看更多精品内容 >>>


AIStudio扫描王实现与原理详解

一、前言

  大家经常有需要使用扫描件的时候,如果是要求不太高的场景,我们通常会使用手机拍照,再经过一些APP应用的处理,就生成了扫描件。但是,通常会有广告,并且一些功能是收费的,那么我们有没有其他的办法实现这些功能呢?下面本项目将展示如何实现。

二、代码与原理

  只需要将图像加载到相应的代码中,无需任何应用程序即可在几秒钟内获得输出。这个代码可以通过Numpy和OpenCV基本函数来实现。示例图片如图所示。

  首先,我们需要导入库函数;其次使用滤波函数将阴影部分去除;最后输出需要的图像文件。那么什么是图像滤波呢?下面简单介绍一下图片滤波。

  图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性[1]。

  图像滤波按图像域可分为两种类型:

  邻域滤波(Spatial Domain Filter),其本质是数字窗口上的数学运算。一般用于图像平滑、图像锐化、特征提取(如纹理测量、边缘检测)等,邻域滤波使用邻域算子——利用给定像素周围像素值以决定此像素最终输出的一种算子。邻域滤波方式又分为线性滤波和非线性滤波,其中线性滤波包括均值滤波、方框滤波和高斯滤波等,非线性滤波包括中值滤波和双边滤波等。

  频域滤波(Frequency Domain Filter),其本质是对像素频率的修改。一般用于降噪、重采样、图像压缩等。按图像频率滤除效果主要分为两种类型:低通滤波(滤除原图像的高频成分,即模糊图像边缘与细节)和高通滤波(滤除原图像的低频成分,即图像锐化)。

[1]图像滤波参考链接:https://blog.csdn.net/crossoverpptx/article/details/127307179

%matplotlib inlineimport cv2
import numpy as np
import matplotlib.pyplot as plt

2.1 最大滤波

  最大最小值滤波是一种比较保守的图像处理手段,与中值滤波类似,首先要排序周围像素和中心像
素值,然后将中心像素值与最小和最大像素值比较,如果比最小值小,则替换中心像素为最小值,
如果中心像素比最大值大,则替换中心像素为最大值。

  让我们假设我们有一定大小的图像I。我们编写的算法应该逐个遍历I的像素,并且对于每个像素(x,y),它必须找到该像素周围的邻域(大小为N x N的窗口)中的最大灰度值,并进行写入A中相应像素位置(x,y)的最大灰度值。所得图像A称为输入图像I的最大滤波图像。现在让我们通过代码来实现这个概念。

  1. max_filtering()函数接受输入图像和窗口大小N。
  2. 它最初在输入数组周围创建一个“墙”(带有-1的填充),当我们遍历边缘像素时会有所帮助。
  3. 然后,我们创建一个“ temp”变量,将计算出的最大值复制到其中。
  4. 然后,我们遍历该数组并围绕大小为N x N的当前像素创建一个窗口。
  5. 然后,我们使用“ amax()”函数在该窗口中计算最大值,并将该值写入temp数组。
  6. 我们将该临时数组复制到主数组A中,并将其作为输出返回。
  7. A是输入I的最大滤波图像。
def max_filtering(N, I_temp):wall = np.full((I_temp.shape[0]+(N//2)*2, I_temp.shape[1]+(N//2)*2), -1)wall[(N//2):wall.shape[0]-(N//2), (N//2):wall.shape[1]-(N//2)] = I_temp.copy()temp = np.full((I_temp.shape[0]+(N//2)*2, I_temp.shape[1]+(N//2)*2), -1)for y in range(0,wall.shape[0]):for x in range(0,wall.shape[1]):if wall[y,x]!=-1:window = wall[y-(N//2):y+(N//2)+1,x-(N//2):x+(N//2)+1]num = np.amax(window)temp[y,x] = numA = temp[(N//2):wall.shape[0]-(N//2), (N//2):wall.shape[1]-(N//2)].copy()return A

2.2 最小滤波

  最小滤波:此算法与最大滤波完全相同,但是我们没有找到附近的最大灰度值,而是在该像素周围的N x N邻域中找到了最小值,并将该最小灰度值写入B中的(x,y)。所得图像B称为图像I的经过最小滤波的图像,代码如下。

def min_filtering(N, A):wall_min = np.full((A.shape[0]+(N//2)*2, A.shape[1]+(N//2)*2), 300)wall_min[(N//2):wall_min.shape[0]-(N//2), (N//2):wall_min.shape[1]-(N//2)] = A.copy()temp_min = np.full((A.shape[0]+(N//2)*2, A.shape[1]+(N//2)*2), 300)for y in range(0,wall_min.shape[0]):for x in range(0,wall_min.shape[1]):if wall_min[y,x]!=300:window_min = wall_min[y-(N//2):y+(N//2)+1,x-(N//2):x+(N//2)+1]num_min = np.amin(window_min)temp_min[y,x] = num_minB = temp_min[(N//2):wall_min.shape[0]-(N//2), (N//2):wall_min.shape[1]-(N//2)].copy()return B

变量N(用于过滤的窗口大小)将根据图像中粒子或内容的大小进行更改。对于测试图像,选择大小N = 20。增强后的最终输出图像如下所示:

def background_subtraction(I, B):O = I - Bnorm_img = cv2.normalize(O, None, 0,255, norm_type=cv2.NORM_MINMAX)return norm_img

完整代码如下所示

%matplotlib inlineimport cv2
import numpy as np
import matplotlib.pyplot as pltdef max_filtering(N, I_temp):wall = np.full((I_temp.shape[0]+(N//2)*2, I_temp.shape[1]+(N//2)*2), -1)wall[(N//2):wall.shape[0]-(N//2), (N//2):wall.shape[1]-(N//2)] = I_temp.copy()temp = np.full((I_temp.shape[0]+(N//2)*2, I_temp.shape[1]+(N//2)*2), -1)for y in range(0,wall.shape[0]):for x in range(0,wall.shape[1]):if wall[y,x]!=-1:window = wall[y-(N//2):y+(N//2)+1,x-(N//2):x+(N//2)+1]num = np.amax(window)temp[y,x] = numA = temp[(N//2):wall.shape[0]-(N//2), (N//2):wall.shape[1]-(N//2)].copy()return Adef min_filtering(N, A):wall_min = np.full((A.shape[0]+(N//2)*2, A.shape[1]+(N//2)*2), 300)wall_min[(N//2):wall_min.shape[0]-(N//2), (N//2):wall_min.shape[1]-(N//2)] = A.copy()temp_min = np.full((A.shape[0]+(N//2)*2, A.shape[1]+(N//2)*2), 300)for y in range(0,wall_min.shape[0]):for x in range(0,wall_min.shape[1]):if wall_min[y,x]!=300:window_min = wall_min[y-(N//2):y+(N//2)+1,x-(N//2):x+(N//2)+1]num_min = np.amin(window_min)temp_min[y,x] = num_minB = temp_min[(N//2):wall_min.shape[0]-(N//2), (N//2):wall_min.shape[1]-(N//2)].copy()return Bdef background_subtraction(I, B):O = I - Bnorm_img = cv2.normalize(O, None, 0,255, norm_type=cv2.NORM_MINMAX)return norm_imgdef min_max_filtering(M, N, I):if M == 0:#max_filteringA = max_filtering(N, I)#min_filteringB = min_filtering(N, A)#subtractionnormalised_img = background_subtraction(I, B)elif M == 1:#min_filteringA = min_filtering(N, I)#max_filteringB = max_filtering(N, A)#subtractionnormalised_img = background_subtraction(I, B)return normalised_img
P = cv2.imread('Test_image.jpeg',0)
plt.imshow(P,cmap='gray')
plt.title("original image")
plt.show()

在这里插入图片描述

#We can edit the N and M values here for P and C images
O_P = min_max_filtering(M = 0, N = 20, I = P)#Display final output
plt.imshow(O_P, cmap = 'gray')
plt.title("Final output")
plt.show()

在这里插入图片描述

总结

  进行图片转换时,有两件事要注意。由于图像是灰度图像,如果图像背景较浅且对象较暗,则必须先执行最大滤波,然后再执行最小滤波。如果图像背景较暗且物体较亮,我们可以先执行最小滤波,然后再进行最大滤波。如果图像的背景较浅,我们要先执行最大过滤,这将为我们提供增强的背景,并将该最大过滤后的图像传递给最小过滤功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1380342.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

基于 requests 的全能扫描王爬虫实践

投稿人:Alan 摘要:全能扫描王是文件扫描留档的重要工具,本文利用requests爬虫将手机客户端的扫描文件,同步至电脑端。 一、背景 在审计工作中,需要大批量扫描文件留档,全能扫描王成为主流的手机端扫描工具。…

【OpenCV】基于Qt的“破产版”全能扫描王

功能介绍 图片打开和保存图片矫正(证件扫描、文字纠正…)图片锐化增强图片清空阈值设置 项目实现 基本思路(证件扫描) 抠图:提取轮廓矫正:透视变换锐化增强:二值化 算法设计(证…

eNSP:ibgp的破水平切割练习

实验要求&#xff1a; 拓扑展示&#xff1a; 命令操作&#xff1a; R1&#xff1a; <Huawei>sys [Huawei]sys r1 [r1]int g 0/0/1 [r1-GigabitEthernet0/0/1]ip add 12.1.1.1 24 [r1-GigabitEthernet0/0/1]int lo0 [r1-LoopBack0]ip add 1.1.1.1 24 [r1-LoopBack0]osp…

css clip-path 画五角星

简介 使用裁剪方式创建元素的可显示区域&#xff0c;实现区域裁剪。 浏览器兼容性 常用的三种方法 1. clip-path: circle(50px at 50px 50px) 以 50px 50px 的坐标为圆心裁剪一个半径 50px 的圆&#xff1b; 2. clip-path: ellipse(30px 40px at 50px 50px) 以 50px 50px…

canvas绘图详解-06-绘制一个五角星-常用绘图原理

先讲如何画一个正规的五角星 在五角星的内外画两个圆&#xff0c;五角星有五个角&#xff0c;360/572度 所以得出这两个角的度数 然后算出这两个点坐标 角度转弧度 角度/180*Math.PI 所以外顶点坐标 x: Math.cos( (1872*i)/180*Math.PI) * R y: Math.sin((1872*i)/180*Math.P…

钓鱼网站原理实验

实验环境:一台Windows 2003&#xff08;WA&#xff09;作为客户机&#xff0c;一台Linux&#xff08;LB&#xff09;作为服务器。 1.LB设置网络适配器 2.LB配置eth0&#xff08;vim /etc/sysconfig/network-scripts/ifcfg-eth0&#xff09; 3.LB将eth0的内容copy一份到eth1 …

电子邮件如何追溯到他们的源IP地址

你要做的第一件事当你听到检查发送电子邮件通知,对吧? 这是最快的方法找出谁是电子邮件,以及可能的内容。 但是你知道每个邮件都有更多的信息比出现在大多数的电子邮件客户端? 有主机的信息发送者包括在邮件头信息可以用来跟踪电子邮件回源。 下面是如何跟踪,邮件回它是从哪…

红队攻击:轻松玩转邮件钓鱼

首发在合天智汇&#xff1a;https://mp.weixin.qq.com/s/sRXnwIdy3eQ0CJS58_bI1g 邮件钓鱼老生常谈&#xff0c;攻击手段也并不新颖。但对于网络安全工程师来说,“懂原理”和“会使用”是两个概念。会用&#xff0c;用得好不好&#xff0c;又是不同的层次。红队攻击要讲究攻击的…

seeker+ngrok 钓鱼获取目标位置

免责说明&#xff1a;本文章只是参考&#xff0c;一切后果自行承担&#xff0c;网络环境靠大家&#xff0c;遵守网络安全法是每个人应尽的责任 文章目录 一、工具介绍seekerngrok 二、使用步骤 一、工具介绍 seeker seeker工具是一款社会工程学的利器&#xff0c;可以通过see…

使用十六进制IP地址的网络钓鱼攻击活动

网络犯罪分子正在不断优化其网络攻击工具&#xff0c;策略和技术&#xff0c;以逃避垃圾邮件检测系统。 由于一些系统会直接提取邮件中内嵌的链接进行检测&#xff0c;而一种此类URL混淆技术采用了URL主机名部分中使用的编码十六进制IP地址格式来逃避检测。 由于IP地址可以用多…

1. 如何爬取自己的CSDN博客文章列表(获取列表)(博客列表)(手动+python代码方式)

文章目录 写在最前步骤打开chrome浏览器&#xff0c;登录网页按pagedown一直往下刷呀刷呀刷&#xff0c;直到把自己所有的博文刷出来然后我们按F12&#xff0c;点击选取元素按钮然后随便点一篇博文&#xff0c;产生如下所示代码然后往上翻&#xff0c;找到头&#xff0c;复制然…

Maven在IDEA2021版本中全局配置(一次配置处处生效)

前言 我们在开发中&#xff0c;Maven是必不可少的&#xff0c;但是每次都需要设置一遍Maven的仓库和settings.xml。真的是心累&#xff0c;今天教大家全局配置一下。再也不要每次项目都配了&#xff0c;Maven还经常出问题。 解决方案 友情提示&#xff1a;小编的IDEA版本为2…

Tableau 聚合计算 - 分组求和(sum、fixed、include的使用)

一、聚合计算例子 有以下数据&#xff1a; // 计算1 SUM(IF [shuxue]123 then [yingyu] END)// 计算2 IF [shuxue]123 then {fixed [shuxue]: SUM([yingyu])} END// 计算3 IF [shuxue]123 then {SUM([yingyu])} END// 计算4 {fixed [shuxue]: SUM([yingyu])}// 计算5 {include…

Kubernetes pod调度约束[亲和性 污点] 生命阶段 排障手段

调度约束 Kubernetes 是通过 List-Watch 的机制进行每个组件的协作&#xff0c;保持数据同步的&#xff0c;每个组件之间的设计实现了解耦。 用户是通过 kubectl 根据配置文件&#xff0c;向 APIServer 发送命令&#xff0c;在 Node 节点上面建立 Pod 和 Container。 APIServer…

[Pandas] 分组比例计算求和

美图欣赏2022/08/01 问题:在最近的需求开发中&#xff0c;有这么个分组比例计算求和问题&#xff0c;根据字段CPN进行分组&#xff0c;计算每一笔PO Line Actual CT2R * line 数量比重&#xff0c;取名为Weighted(QTY)CT2R&#xff0c;再根据相同的CPN对每行Weighted(QTY)CT2R值…

SQL多字段分组求和

表结构 表数据 按店铺名称、发货时间分组并求总数 select g.[店铺名称],g.[发货时间],sum(g.[数量]) as 总数 from t_goods g GROUP BY g.[店铺名称],g.[发货时间] ORDER BY g.[店铺名称]

oracle 分析函数之分组求和、连续求和

最近在《sql cookbook》书上发现了名叫 分析函数 的东西&#xff0c;之前学 oracle 时没有印象&#xff0c;现在感觉其分析函数的功能相当强大、神奇&#xff0c; 就特意去找到了 chm 文档研究了一下&#xff0c;想要的朋友在本文末尾自行下载。 本文的例子都来源于 chm 文档…

简单卡通水

参考 https://roystan.net/articles/toon-water/ 源码 https://github.com/IronWarrior/ToonWaterShader 两张噪声图 挂在相机上&#xff0c;开启深度模式&#xff0c;使shader可以拿到深度图 using UnityEngine;public class ChangeCameraDepth : MonoBehaviour {public De…

编写简单的动画

UIImageView提供了实现简单动画的功能。比如要实现这样的功能&#xff1a; 跳动的火焰。基本思路是&#xff0c;一个数组&#xff0c;包含火焰跳动所需的多张图片。然后设置播放时间&#xff0c;并开始播放。UIImageView已经提供了这方面的机制&#xff0c;只需把图片数组交给它…