百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

从头开始在python中实现拉普拉斯斑点检测器

toyiye 2024-06-21 19:11 12 浏览 0 评论

Harris Corner Detector生成的特征对于缩放不是不变的。对于特征跟踪,我们需要对仿射变换不变的特征。拉普拉斯斑点检测器是生成对缩放不变的特征的基本方法之一。

拉普拉斯斑点检测器的想法是将图像与多个尺度的“斑点滤波器”进行卷积,并在得到的尺度空间中寻找滤波器响应的极值。

斑点滤波器(Blob Filter):

这个滤波器是由沿x轴和y轴的double derivating Gaussian filter产生并相加。以上也称为高斯拉普拉斯算子。

当图像中有一个角时,LOG滤波器的输出最大。

我们想通过将图像与不同的sigma卷积来找到blob的特征尺度。但随着我们增加sigma,blob滤波器对图像的响应会降低,因此我们可能无法找到更好的尺度(scale)。为了减少这种影响,我们将LOG滤波器σ平方相乘。这个过程称为尺度归一化。

拉普拉斯档案对半径为r的binary圆的最大响应是σ= 1.414 * r

以上是blob滤波器的一些基础知识。整个过程归结为两个步骤

  1. 在几个尺度上用尺度归一化拉普拉斯变换卷积图像(不同尺度意味着不同的西格玛)
  2. 在尺度空间中找到平方拉普拉斯响应的最大值

拉普拉斯Blob检测的Python代码

该代码有四个主要步骤:

  1. 生成LOG滤波器
  2. 用高斯滤波器对图像进行卷积
  3. 找到最大峰值
  4. 绘制blob。

生成LOG滤波器的Python代码

import cv2
from pylab import *
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("sunflowers.jpg",0) #gray scale conversion
from scipy import ndimage
from scipy.ndimage import filters
from scipy import spatial
k = 1.414
sigma = 1.0
img = img/255.0 #image normalization
def LoG(sigma):
 #window size 
 n = np.ceil(sigma*6)
 y,x = np.ogrid[-n//2:n//2+1,-n//2:n//2+1]
 y_filter = np.exp(-(y*y/(2.*sigma*sigma)))
 x_filter = np.exp(-(x*x/(2.*sigma*sigma)))
 final_filter = (-(2*sigma**2) + (x*x + y*y) ) * (x_filter*y_filter) * (1/(2*np.pi*sigma**4))
 return final_filter

LoG函数将sigma作为输入,并生成大小为6 * sigma(最佳选项)的滤波器。

用高斯滤波器对图像进行卷积

图像与不同的LOG滤波器进行卷积,Python代码如下:

def LoG_convolve(img):
 log_images = [] #to store responses
 for i in range(0,9):
 y = np.power(k,i) 
 sigma_1 = sigma*y #sigma 
 filter_log = LoG(sigma_1) #filter generation
 image = cv2.filter2D(img,-1,filter_log) # convolving image
 image = np.pad(image,((1,1),(1,1)),'constant') #padding 
 image = np.square(image) # squaring the response
 log_images.append(image)
 log_image_np = np.array([i for i in log_images]) # storing the #in numpy array
 return log_image_np
log_image_np = LoG_convolve(img)
#print(log_image_np.shape)

要选择不同的sigma,我将sigma与k ^ i相乘。log_image_np数组的维度为z * image_height * image_width,其中z表示与sigma相乘的第k次方。

在上面的函数中,我只生成了9个滤波器,图中的9个滤波器是

找到最大峰值

def detect_blob(log_image_np):
 co_ordinates = [] #to store co ordinates
 (h,w) = img.shape
 for i in range(1,h):
 for j in range(1,w):
 slice_img = log_image_np[:,i-1:i+2,j-1:j+2] #9*3*3 slice
 result = np.amax(slice_img) #finding maximum
 if result >= 0.03: #threshold
 z,x,y = np.unravel_index(slice_img.argmax(),slice_img.shape)
 co_ordinates.append((i+x-1,j+y-1,k**z*sigma)) #finding co-rdinates
 return co_ordinates
co_ordinates = list(set(detect_blob(log_image_np)))

在每个像素处,在所有尺度上考虑3x3邻域,其给出9x3x3矩阵。矩阵的最大峰值由矩阵的最大值给出。

对于每个像素,都会有一个最大值。但并非所有像素都有助于blob。所以我们需要通过阈值来消除它们。

如果最大值大于阈值,则考虑该点并存储坐标。

(z,x,y)是切片图像的坐标,因此我们需要将它们更改为原始图像坐标。在更改它们之后,我们将它们存储在co_ordinates列表中并绘制它们。Python代码如下:

fig, ax = plt.subplots()
nh,nw = img.shape
count = 0
ax.imshow(img, interpolation='nearest',cmap="gray")
for blob in co_ordinates:
 y,x,r = blob
 c = plt.Circle((x, y), r*1.414, color='red', linewidth=1.5, fill=False)
 ax.add_patch(c)
ax.plot() 
plt.show()

上面的代码在存储列表的每个点绘制blob。

结果

在上面的图像中,我们可以发现许多blob都是重叠的。为了减少重叠的斑点,我们将找到斑点之间的重叠区域。如果该区域大于阈值,则将丢弃具有较小半径的斑点。python实现如下:

#provided in scipy doucumentaion
def blob_overlap(blob1, blob2):
 n_dim = len(blob1) - 1
 root_ndim = sqrt(n_dim)
 #print(n_dim)
 
 # radius of two blobs
 r1 = blob1[-1] * root_ndim
 r2 = blob2[-1] * root_ndim
 
 d = sqrt(np.sum((blob1[:-1] - blob2[:-1])**2))
 
 #no overlap between two blobs
 if d > r1 + r2:
 return 0
 # one blob is inside the other, the smaller blob must die
 elif d <= abs(r1 - r2):
 return 1
 else:
 #computing the area of overlap between blobs
 ratio1 = (d ** 2 + r1 ** 2 - r2 ** 2) / (2 * d * r1)
 ratio1 = np.clip(ratio1, -1, 1)
 acos1 = math.acos(ratio1)
ratio2 = (d ** 2 + r2 ** 2 - r1 ** 2) / (2 * d * r2)
 ratio2 = np.clip(ratio2, -1, 1)
 acos2 = math.acos(ratio2)
a = -d + r2 + r1
 b = d - r2 + r1
 c = d + r2 - r1
 d = d + r2 + r1
area = (r1 ** 2 * acos1 + r2 ** 2 * acos2 -0.5 * sqrt(abs(a * b * c * d)))
 return area/(math.pi * (min(r1, r2) ** 2))
 
def redundancy(blobs_array, overlap):
 sigma = blobs_array[:, -1].max()
 distance = 2 * sigma * sqrt(blobs_array.shape[1] - 1)
 tree = spatial.cKDTree(blobs_array[:, :-1])
 pairs = np.array(list(tree.query_pairs(distance)))
 if len(pairs) == 0:
 return blobs_array
 else:
 for (i, j) in pairs:
 blob1, blob2 = blobs_array[i], blobs_array[j]
 if blob_overlap(blob1, blob2) > overlap:
 if blob1[-1] > blob2[-1]:
 blob2[-1] = 0
 else:
 blob1[-1] = 0
return np.array([b for b in blobs_array if b[-1] > 0])
co_ordinates = np.array(co_ordinates)
co_ordinates = redundancy(co_ordinates,0.5)

删除重叠blob后输出为

我们可以看到大多数斑点已被消除。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码