python - 对背景较浅的图像进行伽马校正
问题描述
我正在尝试使用下面的代码检测图像中身份证的边界。关键是我使用的伽玛值。我使用 2 或 3 的值(假设我希望卡片在背景中突出)。我在使用背景较浅或与卡片颜色本身一样浅的照片时遇到问题。请看下面的图片..第一个是带有深色 b/g 的原件,第二个是带有伽马校正的..与下一个 2 相同。我在想办法弄清楚我怎么能处理背景较浅的图片。还粘贴了我用来执行伽玛校正的代码。请让我知道你们是否可以将我厚厚的脑袋指向正确的方向:)
import cv2
import numpy as np
import imutils
import math
import sys
img = cv2.imread( sys.argv[1] )
gray1 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
invGamma = 3.0
table = np.array([((i / 255.0) ** invGamma) * 255
for i in np.arange(0, 256)]).astype("uint8")
gray = cv2.LUT(gray1, table)
ret,thresh1 = cv2.threshold( gray, 80, 255, cv2.THRESH_BINARY )
cv2.imwrite( 'LUT.jpg', thresh1 )
_, contours, hierarchy = cv2.findContours(thresh1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
解决方案
据我了解你的问题,你主要是想检测卡的边缘?或者您是否试图将卡片与图像完全分开(即切出)?
您对伽玛的使用只是在将整个图像转换为灰色后改变了整个图像的明显对比度。OpenCV 有很多自己的边缘和对象检测例程,因为我假设您正在尝试进行预处理以提供帮助?
一个概念(非代码)答案:
单独的频道
让我为你指出一个不同的方向。如果输入图像始终是彩色的,请考虑仅使用三个 RGB 颜色通道之一。这是一个例子:
红色通道:
绿色通道:
蓝色通道:
注意蓝色通道相对于红色通道有多少对比度。根据图像内容,您通常会发现一个通道对所需对象具有更好的分离效果。
如果您查看直方图:
您可以看到蓝色通道的右侧峰(所需对象)和左侧峰(桌子上的亮点)之间的距离最大。但是红色通道将所有内容都集中在中间。
作为一个想法,您可以使用峰值检测/峰值位置/峰值之间的距离以编程方式确定每个颜色通道中的相对对比度。
您还可以确定哪个颜色通道的峰值与另一个通道中的同一峰值最远,然后减去或使用 DIFFERENCE 或 DIVIDE 两个通道(下面的“通道数学”中的示例)。
桌布
现在用桌布,它上面有一个非常高对比度的图案——白色(灰色)比身份证浅,绿色比身份证深。该卡主要介于两者之间。
使用图像编辑器中的曲线工具提供图形示例,您可以看到将下层和上层钳位为黑色,您可以隔离中档卡片。
但同样,请注意直方图:
虽然几乎所有东西都集中在中频值中,但 RED 通道确实在黑色附近有一个小峰值。以此为指导,我们关闭绿色和蓝色通道,然后 CLAMP 值低于和高于卡值范围的值。
曲线工具:
然后仅生成红色通道 - 请注意这是反转的,以使生成的对比度更清晰:
概括
所以这些隔离概念的要点是
- 检查每个颜色通道以确定哪个颜色通道具有最佳对比度。这将寻找与其他通道最不同的峰和/或寻找它们之间具有最宽“谷”的通道中的峰。
- 钳制低值和高值以隔离所需对象。这将使用在 A 中找到的具有阈值的峰值来确定要钳位和斜坡进入所需图像的点。
仅使用一般“伽马”调整的问题在于,您将拖动整个图像以改变明显的对比度,而您真正想要做的是消除(钳制)图像中不相关的部分.
虽然我意识到这并不是您要问的,但我希望它仍然有用。另外,如果您还没有,我建议您在 OpenCV 中查看更多检测功能。
奖励:通道数学的乐趣
这可能对您有用,也可能没有,但是颜色通道之间的乘法、除法、减法、差异、排除有时可以帮助消除不需要的背景对象。拿桌布和图案。
让我们将绿色和蓝色通道相乘并得到这个:
现在让我们除以红色通道
现在调整 RED 通道的 GAMMA 以消除桌布图案(Gamma 调整为 1.57):
有了这个结果图像:
既然桌布图案消失了,这当然可以进一步增强对比度。
推荐阅读
- sql - 将日期与日期时间进行比较是否与在 SQL Server 中首次将前者转换为日期时间相同?
- vba - 搜索具有通用前缀的工作表并将匹配的工作表移动/保存到新工作簿
- ssh - 循环输出到本地机器
- java - 仅在附加文件时带有 VertX 的 IllegalStateException
- postgresql - 在 PostgreSQL 中恢复 postgres 用户
- c++ - 在不受支持的架构上未使用的 asm() 的行为
- javascript - html 中的函数是否在未导航时执行
- telegram - 使用 Telethon 转发大量消息
- html - 在图像和中心周围添加 div 容器
- docker - CloudFoundry:用于在 Gunicorn (Docker) 之上提供静态内容的 nginx