基于 OpenCV 的图像阴影去除
作者 | 努比
来源 | 小白学视觉
我们经常需要通过扫描将纸上的全部内容转换为图像。有很多在线工具可以提高图像的亮度,或者消除图像中的阴影。但是我们可以手动删除阴影吗?当然可以,我们只需要将图像加载到相应的代码中,无需任何应用程序即可在几秒钟内获得输出。这个代码可以通过Numpy和OpenCV基本函数来实现。为了说明该过程,使用了以下图像进行操作。
Test_image
1.图像中有一个非常明显的阴影需要删除。首先当然是将必要的软件包导入环境。
import cv2
import numpy as np
import matplotlib.pyplot as plt
2.删除阴影时,有两件事要注意。由于图像是灰度图像,如果图像背景较浅且对象较暗,则必须先执行最大滤波,然后再执行最小滤波。如果图像背景较暗且物体较亮,我们可以先执行最小滤波,然后再进行最大滤波。
那么,最大过滤和最小过滤到底是什么?
3.最大滤波:让我们假设我们有一定大小的图像I。我们编写的算法应该逐个遍历I的像素,并且对于每个像素(x,y),它必须找到该像素周围的邻域(大小为N x N的窗口)中的最大灰度值,并进行写入A中相应像素位置(x,y)的最大灰度值。所得图像A称为输入图像I的最大滤波图像。现在让我们通过代码来实现这个概念。
max_filtering()函数接受输入图像和窗口大小N。
它最初在输入数组周围创建一个“墙”(带有-1的填充),当我们遍历边缘像素时会有所帮助。
然后,我们创建一个“ temp”变量,将计算出的最大值复制到其中。
然后,我们遍历该数组并围绕大小为N x N的当前像素创建一个窗口。
然后,我们使用“ amax()”函数在该窗口中计算最大值,并将该值写入temp数组。
我们将该临时数组复制到主数组A中,并将其作为输出返回。
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
4.最小滤波:此算法与最大滤波完全相同,但是我们没有找到附近的最大灰度值,而是在该像素周围的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
5.因此,如果图像的背景较浅,我们要先执行最大过滤,这将为我们提供增强的背景,并将该最大过滤后的图像传递给最小过滤功能,该功能将负责实际的内容增强。
6.因此,执行最小-最大滤波后,我们获得的值不在0-255的范围内。因此,我们必须归一化使用背景减法获得的最终阵列,该方法是将原始图像减去最小-最大滤波图像,以获得去除阴影的最终图像。
#B is the filtered image and I is the original image
def background_subtraction(I, B):O = I - Bnorm_img = cv2.normalize(O, None, 0,255, norm_type=cv2.NORM_MINMAX)
return norm_img
7.变量N(用于过滤的窗口大小)将根据图像中粒子或内容的大小进行更改。对于测试图像,选择大小N = 20。增强后的最终输出图像如下所示:
Test_image_output
输出图像相较于原始图像已经没有任何的阴影啦。
代码链接:https://github.com/kavyamusty/Shading-removal-of-images
往
期
回
顾
资讯
冬奥会夺金背后的杀手锏,是他
技术
10个超级常用的Python方法总结
技术
5分钟速通 AI 计算机视觉发展应用
资讯
M2芯片终于要来了?全线换新
分享
点收藏
点点赞
点在看
相关文章:

not exists 跟not in 纪念一下
转载于:https://www.cnblogs.com/zzzzw/p/4973378.html

jquery $.proxy使用 Jquery实现ready()的源码
jquery $.proxy使用 在某些情况下,我们调用Javascript函数时候,this指针并不一定是我们所期望的那个。例如: 1 //正常的this使用2 $(#myElement).click(function() {3 4 // 这个this是我们所期望的,当前元素的this.5 6 $(…

PHP session回收机制
由于PHP的工作机制,它并没有一个daemon线程,来定时地扫描session信息并判断其是否失效。当一个有效请求发生时,PHP会根据全局变量 session.gc_probability/session.gc_divisor(同样可以通过php.ini或者ini_set()函数来修改&#x…

WPF学习拾遗(二)TextBlock换行
原文:WPF学习拾遗(二)TextBlock换行下午在帮组里的同事解决一个小问题,为了以后方便,把就把它收集一下吧。 新建一个TextBlock作为最基础的一个控件,他所携带的功能相对于其他的控件要来的比较少, 比较值得…

Meta 开发 AI 语音助手,用于创建虚拟世界和实时翻译
编译 | 禾木木 出品 | AI科技大本营(ID:rgznai100) Meta 在近日的「用人工智能构建元宇宙」的讨论会上,展示了最新的 AI 黑科技 「Builder Bot」 ,并且在此次会议上 Meta 公布了关于构建元宇宙的人工智能计划,其中包括…

MySQL的基础
2019独角兽企业重金招聘Python工程师标准>>> 数据库和SQL 什么数据库 数据库是存储在一起的相关数据的集合,这些数据是结构化的,无有害的或不必要的冗余,并为多种应用服务。 什么是SQL 结构化查询语言(Structured Query Language)…

Python:Bug 官网不要了,全迁去 GitHub
近几年,GitHub 开发者数量逐年上升,仅过去一年 GitHub 的新增用户便有 1600 万人,总用户数更是达到了 7300 万——在开源浪潮席卷全球中,GitHub 无疑成为了许多开发者迈入开源的一个重要途径。 Python 开发团队或许正是看中了这一…

最新的全球编程语言,操作系统,web服务器等使用率分析报告
由www.w3techs.com 根据alexa排名前100万的网站数据给出的分析报告,并每天持续更新。1.服务器端编程语言排名 http://w3techs.com/technologies/overview/programming_language/all点评:PHP是最高的,说明目前php是主流,但是asp.ne…

javascript中有关this的使用
this在面向对象编程中非常重要,他的值取决于调用的模式。 在Javascript中有4种调用模式:方法调用模式、函数调用模式、构造器调用和apply调用。 1. 方法调用模式:当一个方法被调用时,this被绑定到该对象。方法可以使用this访问自己…

Vue中v-if和v-show的使用场景
1. 官方文档 https://cn.vuejs.org/v2/guide/conditional.html#v-if-vs-v-show 2. v-if 和 v-show 的区别 2.1 官方解释 v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。 v-if 也是惰性的:如果在初…

手机自带的显示基站命令
安卓手机自带快捷指令显示当前的网络信息,不过手机厂商不同,命令也不一样。每次要用时总想不起来命令,记下备用。(1) HTC 安卓手机在拨号键盘输入 *#*#4636#*#* , 选择 “手机信息” (2)三星安卓手机 *#*#4636#*#* , 选择 “手机信息” (3)摩…

LB负载均衡集群 - NAT
前提:客户机 : eth0 192.168.0.200 eth1 192.168.205.129dir主机: eth0 192.168.0.166 eth1 192.168.205.128rs1主机: eth0 192.168.0.207rs2主机: eth0 192.168.0.208rs1 和 rs2的网关是dir 192…

时序预测的三种方式:统计学模型、机器学习、循环神经网络
作者 | luanhz来源 | 小数志导读时序预测是一类经典的问题,在学术界和工业界都有着广泛的研究和应用。甚至说,世间万物加上时间维度后都可抽象为时间序列问题,例如股票价格、天气变化等等。关于时序预测问题的相关理论也极为广泛,…

Python 爬虫练手项目—酒店信息爬取
from bs4 import BeautifulSoup import requests import time import reurl http://search.qyer.com/hotel/89580_4.html urls [http://search.qyer.com/hotel/89580_{}.html.format(str(i)) for i in range(1,10)] # 最多157页 infos [] # print(urls)# 批量爬取数据 def g…

应用交换技术的负载均衡算法
原文出处是:http://hi.baidu.com/ruijievideo/blog/item/5959be1f3c1621ff1bd576d2.html 应用交换技术的负载均衡算法应用交换技术里主要包括四项关键的技术:◆截获和检查流量◆服务器监控健康检查◆负载均衡算法◆会话保持截获和检查流量保证只有合适的…

平民架构的春天——UCloud数据方舟实战记
LNMP是最亲民的网页服务架构,整合了优秀的开源软件,想必大家再熟悉不过了,随着云计算的落地;大众创业,万众创新的倡导,为了更好的服务和安全,LNMP也迁入了云平台,比如像UCloud这样优…

用 Python 制作可视化报表,这也太快了!
作者 | 小F来源 | 法纳斯特在数据展示中使用图表来分享自己的见解,是个非常常见的方法。这也是Tableau、Power BI这类商业智能仪表盘持续流行的原因之一,这些工具为数据提供了精美的图形解释。当然了,这些工具也有着不少缺点,比如…

Django 错误汇总
1、 解决:python manage.py migrate sessions 2、转载于:https://blog.51cto.com/jacksoner/2130665

几种负载均衡算法
几种负载均衡算法 本地流量管理技术主要有一下几种负载均衡算法: 静态负载均衡算法包括:轮询,比率,优先权 动态负载均衡算法包括: 最少连接数,最快响应速度,观察方法,预测法,动态性能分配&#…

cassandra命令
压力测试:cassandra-stress [command] -node [nodes] -mode thrift user[user] password[password] example: cassandra-stress write n10 -node 192.168.0.105 -mode thrift usercassandra passwordcassandra

《2022产业互联网安全十大趋势》发布,专家学者透析产业安全新变化
2月28日,在中国产业互联网发展联盟指导下,人民邮电报、中国信息安全、腾讯安全联合实验室、腾讯研究院联合推出《2022产业互联网安全十大趋势》。该报告由《中国信息安全》杂志出品人温哲、腾讯副总裁丁珂、腾讯研究院院长司晓等20余位行业顶级专家、学者…

slurm用户快速入门手册
1. 概述2. 架构3. 命令3.1 sacct3.2 sattach3.4 sbatch3.5 sbcast3.6 scancel3.7 scontrol3.8 sinfo3.9 smap3.10 squeue3.11 srun3.12 strigger3.13 sview1. 概述 Slurm 是一个开源、容错、高可伸缩的集群管理和大型小型 Linux 集群作业调度系统。slurm不需要对操作系统内核进…

什么是CGI、FastCGI、PHP-CGI、PHP-FPM、Spawn-FCGI?
原文地址:http://www.mike.org.cn/articles/what-is-cgi-fastcgi-php-fpm-spawn-fcgi/什么是CGICGI全称是“公共网关接口”(Common Gateway Interface),HTTP服务器与你的或其它机器上的程序进行“交谈”的一种工具,其程序须运行在网络服务器上…

5个短小精悍的 Python 趣味脚本,太赞了,非常适合小白上手!
作者 | 菜鸟哥来源 | 菜鸟学Python今天特地为大家准备了几个简单的“开胃小菜”。希望大家能够通过这几个简单而实用的小案例,活跃一下自己的思维,为接下来的工作和学习做好准备。话不多说,我们接下来就开始介绍。1、图片尺寸缩小所需库&…

AjaxFileUpload文件上传组件(php+jQuery+ajax)
jQuery插件AjaxFileUpload可以实现ajax文件上传,下载地址:http://www.phpletter.com/contents/ajaxfileupload/ajaxfileupload.js 主要参数说明:1,url表示处理文件上传操作的文件路径,可以测试URL是否能在浏览器中直接…

Hadoop生态圈-Flume的组件之自定义拦截器(interceptor)
Hadoop生态圈-Flume的组件之自定义拦截器(interceptor) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任。 本篇博客只是举例了一个自定义拦截器的方法,测试字节传输速度。 1>.自…

Pandas 重复数据处理大全
作者 | 东哥起飞来源 | Python数据科学本次来介绍重复值处理的常用方法。重复值处理主要涉及两个部分,一个是找出重复值,第二个是删除重复值,也就是根据自己设定的条件进行删除操作。定位重复值对于重复值,我们首先需要查看这些重…

DEDECMS教程:上/下一篇文章标题长度的截取方法
对dedecms了解的朋友们,想必对如何获取上一篇、下一篇文章的标签也是非常熟悉。dedecms获取上一篇、下一篇文章的标签分别为:{dede:prenext getpre/}、{dede:prenext getnext}。 在这个标签里,并没有设置上一篇、下一篇文章标题字数的功能&am…

以太网帧最小字节数以及以太网碰撞
说明:本文源自多个网页,原文链接已经不可寻 以太网是无连接的,不可靠的服务,采用尽力传输的机制。以太网CSMA/CD我就不多讲了,我相信大家都了解这个原理。以太网是不可靠的,这意味着它并不知道对方有没有收…

lodash 提取前N个元素 take
_.take(array, [n1])从数组的起始元素开始提取 N 个元素。 <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><…