本期,边肖将为您带来关于如何使用OpenCV快速查找图像差异的信息。文章内容丰富,从专业角度进行分析和描述。希望你看完这篇文章能有所收获。
如何使用结构相似性指数(SSIM)用Python比较两幅图像。
使用这种方法,我们可以很容易地确定由于轻微的图像处理、压缩伪像或有目的的篡改,两幅图像是相同的还是不同的。
今天,我们将扩展SSIM方法,这样我们就可以使用OpenCV和Python来可视化图像之间的差异。具体来说,我们将在两个不同的输入图像中围绕该区域绘制一个边界框。
OpenCV和Python的图像差异
为了计算两幅图像之间的差异,我们将使用结构相似性指数,这是由王等人在2004年的论文《图像质量评价:从错误可见性到结构相似性》中首次提出的。该方法已在scikit-image库中实现,用于图像处理。
诀窍是学习如何根据(x,y)-坐标位置准确确定图像差异的位置。
为此,我们首先需要确保我们的系统有Python、OpenCV、scikit-image和imutils。
您可以使用我的OpenCV安装教程来学习如何在您的系统上配置和安装Python和OpenCV。
如果您尚未安装/升级scikit映像,请通过以下方式进行升级:
$ pipinstall-upgrade scikit-image当您在这里时,继续安装/升级imutils:
$ pipinstall-upgradeimutils现在我们的系统已经准备好了先决条件,让我们继续。
计算图像差异
你能找到这两幅图像的区别吗?
图1:手动检查两个输入图像(源)之间的差异
如果你花一秒钟研究这两张信用卡,你会注意到万事达卡的标志出现在左边的图像上,但已经从右边的图像上删除了。
您可能已经立即注意到了这种差异,或者可能花了几秒钟。无论哪种方式,这都证明了比较图像差异的一个重要方面——有时图像差异是微妙的——如此微妙,肉眼很难立即理解差异(我们将在这篇博客文章的后面看到这样一个图像的例子)。
那么为什么计算图像差异如此重要呢?
网络钓鱼就是一个例子。攻击者可以稍微操纵图像来欺骗没有验证网址的不知情用户,并使他们认为自己正在登录他们的银行网站——这被证明是一个骗局。
将网页上的徽标和已知用户界面(UI)元素与现有数据集进行比较有助于减少网络钓鱼攻击(感谢查尔斯克利夫兰传递网络钓鱼:通过将网络钓鱼网站视为应用计算机视觉预防的示例来检测网络钓鱼网站)。
网络钓鱼检测系统的发展显然比简单的图像差异复杂得多,但我们仍然可以应用这些技术来确定给定的图像是否被操纵。
现在,让我们计算两张图像之间的差异,并使用OpenCV、scikit-image和Python并排查看差异。
打开一个新文件并命名为image_diff。py,并插入以下代码:
#导入必要的软件包
fromskimage . measure importcompare _ ssim
重要分析
importimutils
importcv2
# construttheargumentparseandbarthearguments
ap=argparse。ArgumentParser()
参数('-f ','- first ',必选=True,
帮助='firstinputimage ')
ap.add_argument('-s ','- se
cond", required=True,
help="second")
args = vars(ap.parse_args())
# load the two input images
imageA = cv2.imread(args["first"])
imageB = cv2.imread(args["second"])
# convert the images to grayscale
grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)
# compute the Structural Similarity Index (SSIM) between the two
# images, ensuring that the difference image is returned
(score, diff) = compare_ssim(grayA, grayB, full=True)
diff = (diff * 255).astype("uint8")
print("SSIM: {}".format(score))
# threshold the difference image, followed by finding contours to
# obtain the regions of the two input images that differ
thresh = cv2.threshold(diff, 0, 255,
cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
# loop over the contours
for c in cnts:
# compute the bounding box of the contour and then draw the
# bounding box on both input images to represent where the two
# images differ
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(imageA, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv2.rectangle(imageB, (x, y), (x + w, y + h), (0, 0, 255), 2)
# show the output images
cv2.imshow("Original", imageA)
cv2.imshow("Modified", imageB)
cv2.imshow("Diff", diff)
cv2.imshow("Thresh", thresh)
cv2.waitKey(0)
第2-5行显示我们的进口。我们将使用 compare_ssim (来自scikit-image), argparse , imutils 和 cv2 (OpenCV)。
我们建立两个命令行参数, - first 和 - second ,它们是我们希望比较的两个相应输入图像的路径(第8-13行)。
接下来,我们将从磁盘加载每个图像并将其转换为灰度:
我们载入我们的第一和第二图像, - 第一 和 - 第二 ,上 线16和17,它们存储为 imageA 和 imageB 分别。
然后我们在第20行和第21行将每个转换为灰度。
接下来,让我们计算两个灰度图像之间的结构相似性指数(SSIM)。
使用 scikit-image中的 compare_ssim函数,我们计算 得分 和差异图像 diff (第25行)。
所述 得分 表示两个输入图像之间的结构相似性指数。该值可以落在[-1,1]范围内 ,值为1是“完美匹配”。
该 差异 的图像包含实际 图像的差异 ,我们希望以可视化的两个输入图像之间。差异图像当前表示为[0,1]范围内的浮点数据类型, 因此我们首先将数组转换为[0,255](第26行)范围内的8位无符号整数, 然后我们才能进一步处理它使用OpenCV。
现在,让我们找到轮廓,以便我们可以在标识为“不同”的区域周围放置矩形:
在 第31行和第32行,我们 使用cv2对我们的差异图像进行 阈值 处理。THRESH_BINARY_INV 和 cv2 。THRESH_OTSU - 使用垂直条'或'符号,|同时应用这两个设置 。有关Otsu双峰阈值设置的详细信息,请参阅此OpenCV文档。
随后我们 在 第33-35行找到了thresh的轮廓 。第35行的三元运算符 简单地适应了各种版本的OpenCV中cv2.findContours返回签名之间的差异。
下面图4中的图像清楚地显示了已被操纵的图像的ROI:
图4:使用阈值处理使用OpenCV和Python突出显示图像差异。
从第38行开始 ,我们遍布我们的轮廓, cnts 。首先,我们使用cv2计算轮廓周围的边界框 。boundingRect 函数。我们将相关的 (x,y )坐标存储为 x 和 y 以及矩形的宽度/高度为 w 和 h 。
然后我们使用这些值在每个图像上用cv2绘制一个红色矩形 。矩形 (第43和44行)。
最后,我们用差异图像,差异图像和阈值图像显示比较图像(第47-50行)。
我们打电话给 cv2 。waitKey 上 50线,直到按下一个键,这使得程序等待(此时脚本将退出)。
接下来,让我们运行脚本并可视化一些图像差异。
可视化图像差异
使用此脚本和以下命令,我们可以快速轻松地突出显示两个图像之间的差异:
$ python image_diff.py --first images/original_02.png --second images/modified_02.png
正如您在图6中看到的那样,安全芯片和帐户持有者的名称都被删除了:
让我们尝试另一个计算图像差异的例子,这次是由杰拉尔德·R·福特总统(来源)撰写的支票。
通过运行下面的命令并提供相关图像,我们可以看到这里的差异更加微妙:
$ python image_diff.py --first images/original_03.png --second images/modified_03.png
请注意图7中的以下更改:
-
贝蒂福特的名字被删除了。
-
支票号码已删除。
-
日期旁边的符号将被删除。
-
姓氏已删除。
在像检查这样的复杂图像上,通常很难用肉眼找到 所有差异。幸运的是,我们现在可以使用Python,OpenCV和scikit-image制作的这个方便的脚本轻松计算差异并可视化结果。
上述就是小编为大家分享的如何用OpenCV快速寻找图像差异处了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/147385.html