882 字
4 分钟
CV: 使用OpenCV找出图像中的不同点

使用OpenCV找出图像中的不同点#

问题:#

提供三组图像:{0-0.jpg,0-1.jpg,0-2.jpg},{1-0.jpg,1-1.jpg},{2-0.jpg,2-1.jpg};每一组中的不同图像拍摄的是同一个场景,但是场景中部分区域发生了变化。以#-0.jpg为参考图,找出#-1.jpg, #-2.jpg中的变化区域。

下面展示的是0-0.jpg,0-1.jpg,可以看出两者之间的变化。

思路:#

1. 获取SIFT特征和特征点#

使用上节课使用的特征匹配的knnMatch获取好的匹配点:

由于有的图像设置good阈值以后似乎会导致没有好的匹配,所以此处选择不断改变阈值thresh,直到能够找到至少44对点。对应代码SIFTMatch函数最开始部分

接着把这些”好的特征点从所有特征点里删去”。[noMatch函数]

得到未匹配特征后大概是这样的:[绿色表示图片2有的图片1没有,红色表示图片1有的图片2没有]

2. 去除多余特征点#

发现很多特征点都是多余的,比如键盘上很多点,

发现这些多余的特征点都有一个共性: 周围红色绿色特征点混杂(也就是内点),所以我的办法是对每一个红色的特征点(本图有而另一张图没有的特征点),在绿色特征点[本图没有而另一张图有的特征点]里找距离最近的一个特征点,如果这个距离小于某个阈值threshthresh,则认为是内点,直接去除。[对应代码findNoMatch函数】

去除完多余特征点大概就是这样:

看得出来,只剩下花的特征点了。

3. 聚类: 对应代码Clustering函数#

给这些特征点聚类。

嗯,这是最麻烦的一步,如果聚类的聚类半径设置的太大:

[当然,这里只取占比总特征点数比较大的一些类别,不然会有很多误检测]

会把两个弄到一起。

如果设置的很小,加上只取占比比较大的类别,则会造成漏检测[电脑屏幕被漏检测了]:

我的想法是,由于应该处于一个大类的特征点本身分布就不均匀[电脑上的两堆特征点本身分布就比较分开],所以我们要允许两堆比较大[防止一些外点进入导致误检]且比较靠近的一些类有融合的操作。

所以在我的Clustering函数中就利用上述条件把一些靠近的类融合在一起。

这样的效果就好了很多。

4. 画矩形: 对应代码中的drawRecs函数#

由于聚类完毕后得到的是一堆点集合,所以还要对点集合找一个合适的矩形,就找点集里最小的x,yx,y坐标,最大的x,yx,y坐标即可。

不过发现有的时候还会有多重矩形(相交矩形):

类似于这种,所以应该把它们合成一个大矩形,

最后就大功告成了。

后记#

花了很多时间调参,也花了很多时间思考到底该怎么把这朵花在往下多框一些[只框住了有特征点的部分]

试图使用BFSBFS遍历像素,找像素值近的点扩张一下范围,不过似乎效果不是很好?

另外调参也每调到让每一幅图像都满意的程度,哎。

CV: 使用OpenCV找出图像中的不同点
http://blog.fragments.work/posts/blogs/cv-lab3/
作者
Lixin WANG
发布于
2024-06-08
许可协议
CC BY-NC-SA 4.0