使用Julia进行图像处理--图像表示与匹配算法,【工作感悟】

文章详细介绍了使用imcorner函数及其不同方法(Harris,Shi-Tomasi,Kitchen-Rosenfeld)在图像中检测角点,同时对比了FAST方法。此外,文章还展示了如何使用BRIEF特征描述符进行图像重复检测,并展示了在创建全景图方面的应用。
摘要由CSDN通过智能技术生成

result

在猫上看到黑点表示由快速角点函数标识的角点。使用其他来匹配相同的对象。

使用imcorner函数进行角点检测

Imcorner函数是FAST替代方法。它也用于图像的角点,并提供不同的方法集:

  1. harris

  2. shi-tomasi

  3. kitchen-rosenfield

每种方法都以其自己独特的算法执行,因此特征表示将有所不同。为了更好地理解差异,将它们全部绘制在单个图像上。首先加载棋盘图像并将其转换为浮点表示形式:

using Images, ImageFeatures, ImageMorphology, ImageView

img = restrict(load(“board-157165_640.png”))

img_f = Float16.(Gray.(img))

接下来,运行四种不同的算法。其中的三个由imcorner函数提供,最后一个是fastcorners:

img_harris = copy(img)

img_harris[dilate(imcorner(img_f, method=harris)) .> 0.01] .= colorant"yellow"

img_shi = copy(img)

img_shi[dilate(imcorner(img_f, method=shi_tomasi)) .> 0.01] .= colorant"yellow"

img_rosenfield = copy(img)

img_rosenfield[dilate(imcorner(img_f, method=kitchen_rosenfeld)) .> 0.01] .= colorant"yellow"

img_fast = copy(img)

img_fast[dilate(fastcorners(img_f, 12, 0.05)) .> 0.01] .= colorant"yellow"

通常,imcorner和fastcorners的结果很小,例如一个像素。从ImageMorphology软件包中应用了膨胀函数,以突出显示通过imcorner或FAST确定的结果,可以让用户在绘制和预览特征时更好地表示特征。还使用了着色剂技术来获得精确的颜色值。

将所有四个图像合并为一个图像:

new_img = vcat(

hcat(img_harris, img_shi),

hcat(img_rosenfield, img_fast)

)

new_img[Int(size(new_img, 1) / 2), :] .= colorant"yellow"

new_img[:, Int(size(new_img, 2) / 2)] .= colorant"yellow"

imshow(new_img)

combined

尝试在猫的图像上运行相同的代码,然后再次比较结果以查看是否有任何变化:

using Images, ImageFeatures, ImageMorphology, ImageView

img = Gray.(restrict(load(“cat-3417184_640.jpg”)))

img_f = Float16.(Gray.(img))

img_harris = copy(img)

img_harris[dilate(imcorner(img_f, method=harris)) .> 0.01] .= colorant"yellow"

img_shi = copy(img)

img_shi[dilate(imcorner(img_f, method=shi_tomasi)) .> 0.01] .= colorant"yellow"

img_rosenfield = copy(img)

img_rosenfield[dilate(imcorner(img_f, method=kitchen_rosenfeld)) .> 0.01] .= colorant"yellow"

img_fast = copy(img)

img_fast[dilate(fastcorners(img_f, 12, 0.05)) .> 0.01] .= colorant"yellow"

new_img = vcat(

hcat(img_harris, img_shi),

hcat(img_rosenfield,img_fast)

)

imshow(new_img)

result

除FAST以外的所有方法在图像周围都有角点。原因是,imcorner函数返回所有角点而没有任何阈值参数。

更新阈值以仅检索特征的前5%,然后再次比较结果:

img = Gray.(restrict(load(“cat-3417184_640.jpg”)))

img_f = Float16.(Gray.(img))

img_harris = copy(img)

img_harris[dilate(imcorner(img_f, Percentile(95), method=harris)) .> 0.01] = colorant"yellow"

img_shi = copy(img)

img_shi[dilate(imcorner(img_f, Percentile(95), method=shi_tomasi)) .> 0.01] = colorant"yellow"

img_rosenfield = copy(img)

img_rosenfield[dilate(imcorner(img_f, Percentile(95), method=kitchen_rosenfeld)) .> 0.01] = colorant"yellow"

img_fast = copy(img)

img_fast[dilate(fastcorners(img_f, 12, 0.05)) .> 0.01] = colorant"yellow"

new_img = vcat(

hcat(img_harris, img_shi),

hcat(img_rosenfield, img_fast)

)

imshow(new_img)

从下图可以看到,结果已经相似:

result

性能比较

进行性能比较以查看哪种算法更快也很重要。为了运行分析,在以下代码中使用了BenchmarkTools包中的@btime宏:

julia> using Images, ImageFeatures, BenchmarkTools

julia> @btime fastcorners(img_f, 12, 0.15);

667.308 μs (7 allocations: 40.33 KiB)

julia> @btime fastcorners(img_f, 12, 0.05);

916.183 μs (7 allocations: 40.33 KiB)

julia> @btime imcorner(img_f, method=harris);

1.050 ms (3041 allocations: 2.12 MiB)

julia> @btime imcorner(img_f, Percentile(95), method=harris);

821.515 μs (317 allocations: 2.13 MiB)

julia> @btime imcorner(img_f, method=shi_tomasi);

1.123 ms (3814 allocations: 2.15 MiB)

julia> @btime imcorner(img_f, method=kitchen_rosenfeld);

1.055 ms (4626 allocations: 2.05 MiB)

尽管使用fastcorners函数时阈值较小的时间会增加,但是内存消耗仍然很小且固定。

BRIEF–有效检测重复图像的方法


二元鲁棒独立基本特征(Binary Robust Independent Elementary Features, BRIEF)是二元特征点描述符。 BRIEF是一个非常简单的特征描述符,因此不能应用于缩放或旋转的图像。尽管有其局限性,它也可以有效地用于诸如重复检测之类的任务。

识别图像重复项

在以下示例中,将比较猫的原始图像与经过稍微修改和加水印的猫。

首先,加载图像并将其转换为灰度版本:

using Images, ImageFeatures, ImageDraw, ImageView

img1 = Gray.(load(“cat-3417184_640.jpg”))

img2 = Gray.(load(“cat-3417184_640_watermarked.jpg”))

imshow(restrict(hcat(img1, img2)))

imshow_compare

接下来,使用fastcorners函数检索关键点或角点,并比较每个图像的计数。通过在调用fastcorners时使用阈值参数的高值来减少返回的关键点的数量:

keypoints_1 = Keypoints(fastcorners(img1, 12, 0.5));

0.5 - very high threshold

keypoints_2 = Keypoints(fastcorners(img2, 12, 0.5));

size(keypoints_1) # result varies from 190 to 200

size(keypoints_2) # result varies from 190 to 200

参数的数量非常接近。下一步是初始化Brief,并调用create_descriptor函数来创建特征。调用match_keypoints函数以匹配两个图像的结果:

brief_params = BRIEF()

desc_1, ret_features_1 = create_descriptor(img1, keypoints_1, brief_params);

desc_2, ret_features_2 = create_descriptor(img2, keypoints_2, brief_params);

matches = match_keypoints(ret_features_1, ret_features_2, desc_1, desc_2, 0.5)

matchs变量应返回特征之间的匹配数。返回size将显示计数,如以下代码所示:

size(matches) # returns (197,)

所以,匹配的数目是197,预览结果以确认一切正确。通过合并两个图像并绘制一条连接匹配项的白线来实现此目的:

grid = hcat(img1, img2)

offset = CartesianIndex(0, size(img1, 2))

map(m -> draw!(grid, LineSegment(m[1], m[2] + offset)), matches)

imshow(grid)

尽管图像发生了变化,但可以看到主要特征已正确匹配。该过程运行相对较快,而且效果很好:

result_match

如果大规模运行重复检测,可以将create_descriptor的结果保存在某种数据库中。因此,当出现新图像时,只需要将其与已经预先计算的特征进行比较即可。

因为BRIEF仅针对单个像素使用信息,所以它对噪声敏感。为了克服此限制,它应用了高斯模糊,可以在初始化BRIEF时对其进行配置。

使用多张图像创建全景图

可以使用BRIEF执行的另一有趣活动是创建全景视图。假设有一个样本地点的许多图像,并且希望将它们连接在一起得出一张图片。可以尝试使用Brief来基于它们的共同特征来拼接图像。

先将图像加载到Julia中,然后将其分为两部分,再尝试进行连接:

using Images, ImageFeatures, ImageDraw, ImageShow

img = load(“cat-3418815_640.jpg”)

img_width = size(img, 2)

img_left_width = 400

img_right_width = 340

接下来,使用前面的设置创建两个新图像。保留原始版本和灰度版本。灰度版本将用于查找关键点,而彩色版本将用于创建最终结果:

img_left = view(img, :, 1:img_left_width)

img_left_gray = Gray.(img_left)

img_right = view(img, :, (img_width - img_right_width):img_width)

img_right_gray = Gray.(img_right)

imshow(img_left)

imshow(img_right)

以下图像是接下来将尝试连接的两个新图像:

imshow_pic

因此,使用以下代码从fastcorners函数的结果中找到关键点:

keypoints_1 = Keypoints(fastcorners(img_left_gray, 12, 0.3));

keypoints_2 = Keypoints(fastcorners(img_right_gray, 12, 0.3));

初始化BRIEF并找到特征之间的匹配:

brief_params = BRIEF()

desc_1, ret_features_1 = create_descriptor(img_left_gray, keypoints_1, brief_params);

desc_2, ret_features_2 = create_descriptor(img_right_gray, keypoints_2, brief_params);

matches = match_keypoints(ret_features_1, ret_features_2, desc_1, desc_2, 0.1)

查看关键点是否正确匹配:

grid = hcat(img_left, img_right)

offset = CartesianIndex(0, size(img_left_gray, 2))

map(m -> draw!(grid, LineSegment(m[1], m[2] + offset)), matches)

imshow(grid)

最后

不知道你们用的什么环境,我一般都是用的Python3.6环境和pycharm解释器,没有软件,或者没有资料,没人解答问题,都可以免费领取(包括今天的代码),过几天我还会做个视频教程出来,有需要也可以领取~

给大家准备的学习资料包括但不限于:

Python 环境、pycharm编辑器/永久激活/翻译插件

python 零基础视频教程

Python 界面开发实战教程

Python 爬虫实战教程

Python 数据分析实战教程

python 游戏开发实战教程

Python 电子书100本

Python 学习路线规划

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python爬虫全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:python)
img

-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZlaTM0Nzc5NTc5MA==,size_16,color_FFFFFF,t_70)

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python爬虫全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:python)
[外链图片转存中…(img-4CIkchnJ-1711210933131)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值