OpenCV如何去除图片中的阴影的实现

一、前言

如果你自己打印过东西,应该有过这种经历。如果用自己拍的图片,在手机上看感觉还是清晰可见,但是一打印出来就是漆黑一片。比如下面这两张图片:

因为左边的图片有大片阴影,所有打印出来的图片不堪入目(因为打印要3毛钱,所以第二张图片只是我用程序模拟的效果)。

那有什么办法可以解决吗?答案是肯定的,今天我们就来探讨几个去除阴影的方法。

二、如何去除阴影?

首先为了方便处理,我们通常会对图片进行灰度转换(即将图片转换成只有一个图层的灰色图像)。

然后我们分析一下,在上面的图片中有三个主色调,分别是字体颜色(黑色)、纸张颜色(偏白)、阴影颜色(灰色)。知道这点后我们就好办了。我们只需要把灰色和白色部分都处理为白色就好了。

那要我怎么才知道白色和灰色区域呢?对于一个8位的灰度图,黑色部分的像素大致在0-30左右。白色和灰色应该在31-255左右(这个范围只是大致估计,实际情况需要看图片)。如图:

左边是原图,右边是处理后的图片。我们将灰色和接近白色的部分都处理成了白色。

那下面我们就开始处理吧。

三、numpy的ndarray数组

可能有些读者没有接触过numpy,这里简单说一下。

numpy是一个第三方的模块,用它我们可以很方便的处理多维数组(ndarray数组)。而图片在OpenCV中的存储方式正好是ndarray,所以我们对数组的操作就是对图片的操作。

在使用之前我们需要安装一下OpenCV模块:

pip install opencv-python

在安装OpenCV时会自动安装numpy。

下面我们主要是看看布尔索引的操作,先看下面代码:

import numpy as np
# 创建一个元素为1, 0, 1, 1的ndarray数组
arr = np.array([1, 0, 1, 1])
# 判断数组中有没有0
res = arr == 0
# 将数组中为0的元素赋值为10
arr[res] = 10

如果没有接触过numpy会不太理解上面的语法。我们来详细说一下:

创建ndarray数组:我们通过np.array可以将现有的列表装换成一个ndarray对象,这个很好理解

判断数组中有没有0:我们可以直接用ndarray对象来判断,比如:arr == 0,他会返回一个元素结构和数量一样的ndarray对象。但是返回的对象原始类型式bool,我们来看看res的输出:

[False True False False]

从结果可以看出,我们比较arr==0就是对数组中每个元素进行比较,并返回比较的布尔值。

将数组中为0的元素赋值为10:而最难理解的arr[res]操作。它其实就是拿到res中为True的视图,比如上面的结果是第二个为True则只会返回第二个元素的视图。我们执行下面的代码:

arr[res] = 10

就是把对应res为True的部分赋值为10,也就是将arr中值为0的部分赋值为10。

下面是arr最后的结果:

[ 1 10 1 1]

可以看到原本的0处理为了1。

四、去除阴影

现在我们知道了布尔索引,我们可以对图片进行处理了。我们只需要读取图片,然后将像素值大于30的部分处理为白色就好了。下面是我们的代码:

import cv2
# 读取图片
img = cv2.imread('page.jpg', 0)
# 将像素值大于30的部分修改为255(白色)
img[img > 30] = 255
# 保存修改后的图片
cv2.imwrite('res.jpg', img)

上面的代码非常简单,我们使用cv2.imread函数读取图片,第一个参数是图片路径,第二个参数表示读取为灰度图。我们来看看效果图:

可以看到阴影部分被很好地去除了。有些字比较模糊,我们可以通过调节灰白色地范围调整。比如:

img[img > 40] = 255

具体的值就要根据要处理的图片来决定了。

五、改进

对于上面地处理,还可以做一个小小地改进。我们可以让纸张颜色不那么白,我们来看改进后的代码:

import cv2
import numpy as np
img = cv2.imread('page.jpg', 0)
# 计算灰白色部分像素的均值
pixel = int(np.mean(img[img > 140]))
# 把灰白色部分修改为与背景接近的颜色
img[img > 30] = pixel
cv2.imwrite('res.jpg', img)

在上面的代码中我们不再是将灰白色部分设置为255,而是事先计算了一个数值。

pixel = int(np.mean(img[img > 140]))

猜测阴影部分的颜色值小于140,因此先索引出图像中大于140的部分。然后求平均值,这样我们算出来的大致就是原图的背景颜色,然后将图片不是文字的部分处理为背景颜色,就是最终结果了。下面是我们的效果图:

可以看到这次效果要更好了。但是因为背景都是一个颜色,所以看起来还是会有一些差别。

不过有一点需要说一下,上面的操作只适用于比较简单的图片,比如试卷这种。

到此这篇关于OpenCV如何去除图片中的阴影的实现的文章就介绍到这了,更多相关OpenCV 去除图片阴影内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python 基于opencv去除图片阴影

    一.前言 如果你自己打印过东西,应该有过这种经历.如果用自己拍的图片,在手机上看感觉还是清晰可见,但是一打印出来就是漆黑一片.比如下面这两张图片: 因为左边的图片有大片阴影,所以打印出来的图片不堪入目(因为打印要3毛钱,所以第二张图片只是我用程序模拟的效果). 那有什么办法可以解决吗?答案是肯定的,今天我们就来探讨几个去除阴影的方法. 二.如何去除阴影? 首先为了方便处理,我们通常会对图片进行灰度转换(即将图片转换成只有一个图层的灰色图像). 然后我们分析一下,在上面的图片中有三个主色调,分别是

  • OpenCV如何去除图片中的阴影的实现

    一.前言 如果你自己打印过东西,应该有过这种经历.如果用自己拍的图片,在手机上看感觉还是清晰可见,但是一打印出来就是漆黑一片.比如下面这两张图片: 因为左边的图片有大片阴影,所有打印出来的图片不堪入目(因为打印要3毛钱,所以第二张图片只是我用程序模拟的效果). 那有什么办法可以解决吗?答案是肯定的,今天我们就来探讨几个去除阴影的方法. 二.如何去除阴影? 首先为了方便处理,我们通常会对图片进行灰度转换(即将图片转换成只有一个图层的灰色图像). 然后我们分析一下,在上面的图片中有三个主色调,分别是

  • java如何去除图片中的白色背景

    最近在做一个需求是从数据库里面取出图片,但是图片都有一个白色的背景,于是项目组希望可以将图片的白色的背景去掉. 本文为大家分享了java去除图片中的白色背景的方法,供大家参考,具体内容如下 如图所示: 当然在这个上面是看不出来的,其实第一张图片是有一个白色的背景的,但是第二张图片没有,相信你理解我说的,那么这个代码我应该如何实现: package com.wdg.util; import java.awt.Graphics2D; import java.awt.Image; import jav

  • Python实现去除图片中指定颜色的像素功能示例

    本文实例讲述了Python实现去除图片中指定颜色的像素功能.分享给大家供大家参考,具体如下: 这里用python去除图片白色像素 需要python和pil from PIL import Image import numpy as np import cv2 img2 = Image.open('./Amazing_COL_2Fix.bmp') img1 = Image.open('./Amazing_RGB_2L.bmp') # img1 = img1.convert('RGBA') img2

  • 使用opencv相关函数确定图片中的直线问题

    目录 使用opencv相关函数确定图片中的直线 OpenCV:直线检测 使用opencv相关函数确定图片中的直线 #pip install opencv-python==4.4.0.42 opencv-contrib-python==4.4.0.42 import cv2 import numpy as np from matplotlib import pyplot as plt import matplotlib.image as mpimg import matplotlib as mpl

  • Java实现去除文档阴影的示例代码

    目录 一.前言 二.实现原理 1. 图像 2. 灰度转换 3.阈值处理 三.代码实现 1.读取图像 2.阈值处理 一.前言 文稿扫描大家用的都比较频繁.想是各种证件.文件都可以通过扫描文稿功能保存到手机.相比直接拍照,在扫描文稿时,程序会对图像进行一些矫正.比如去除阴影.修正倾斜.旋转矫正等.进行这些处理后的图片要更加容易识别.今天就来讨论以下去除阴影的操作. 二.实现原理 1. 图像 在开始实现前,我们来了解一些图像相关的知识.这里讨论RGB图像,也就是我们俗称的彩色的图像.图像可以被看作是一

  • OpenCV实现去除背景识别的方法总结

    目录 实现效果 实现代码 补充 实现效果 效果如图,只识别一定距离内的物体 哈哈哈哈哈哈哈哈哈,但我不知道这有什么用 实现代码 import pyrealsense2 as rs import numpy as np import cv2 # 排除背景色 WIDTH = 848 HEIGHT = 480 # 初始化 config = rs.config() config.enable_stream(rs.stream.color, WIDTH, HEIGHT, rs.format.bgr8, 3

  • OpenCV如何提取图片中曲线

    简单介绍   在实际的应用中,我们常常需要对图像中的曲线进行描述.处理,这个曲线可以是轮廓,骨架或者其他.可以用deque<Point> 描述曲线,接下来简单介绍下如何从图片中搜索这些曲线并保存.   首先,输入的图片是一张二值图片 (白色为曲线),其中包含的曲线宽度为 1 像素的 (如果曲线不是 1 像素的 先提取其骨架).遍历寻找图像中第一个白色的点,然后从这个点开始延伸寻找曲线.注意,第一个找到的点不一定是曲线的端点,因此应该分别向两边寻找相邻的点,因此deque 会好一些.每找到一个点

  • OpenCV利用对比度亮度变换实现水印去除

    目录 导读 背景介绍 实现步骤 导读 本文主要介绍使用OpenCV亮度/对比度变换来去除图片水印的实例. 背景介绍 OpenCV中去除水印最常用的方法是inpaint,通过图像修复的方法来去除水印,最终效果也要根据实际图像来看(时好时坏).有些图像并不适用inpaint方法来去除水印,比如下面的这种包含文本的图像中的水印,即便提供了水印的mask图,修复后也会丢失文字信息,这并不是我们想要的. 那么问题来了,上面图像中的水印该如何去除?有没有一种通用方法,能很好去除这些水印?答案是:没有通用方法

  • Python OpenCV学习之图像形态学

    目录 背景 一.图像二值化 二.自适应阈值 三.腐蚀 四.卷积核获取 五.膨胀 六.开运算 七.闭运算 八.形态学梯度 九.顶帽运算 十.黑帽运算 总结 背景 形态学处理方法是基于对二进制图像进行处理的,卷积核决定图像处理后的效果:形态学的处理哦本质上相当于对图像做前处理,提取出有用的特征,以便后续的目标识别等任务: 一.图像二值化 定义:将图像的每个像素变成两种值,如0和255: 全局二值化的函数原型: threshold(img,thresh,maxVal,type) img:最好是灰度图像

  • iOS去除图片背景颜色的方法

    实际项目场景:去除图片的纯白色背景图,获得一张透明底图片用于拼图功能 介绍两种途径的三种处理方式(不知道为啥想起了孔乙己),具体性能鶸并未对比,如果有大佬能告知,不胜感激. Core Image Core Graphics/Quarz 2D Core Image Core Image是一个很强大的框架.它可以让你简单地应用各种滤镜来处理图像,比如修改鲜艳程度,色泽,或者曝光. 它利用GPU(或者CPU)来非常快速.甚至实时地处理图像数据和视频的帧.并且隐藏了底层图形处理的所有细节,通过提供的AP

随机推荐