python - OpenCV:隐藏在面具后面的轮廓。如何检测轮廓何时将在掩模边缘附近移动?
问题描述
问题摘要
我正在检测光源前的物体轮廓。为了简化背景并去除噪音,我需要遮盖所有不是光源的东西。如何判断对象何时位于遮罩区域的边缘?
假设
假设无特征(用于边缘检测的单色黑白)和不明确的形状(图像 1 中的正方形可能是图像 2 中的圆形)。
“高质量”数字问题的详细解释
考虑光源前的剪影。它是不同的,我们可以说它嵌套在外轮廓内。图 1 描述了一个简化的案例。
在这种情况下,我们可以将外圈视为蒙版,并轻松忽略不在轮廓内的所有内容。图 2 描述了带有一些边缘检测的简化情况。
一切都很好,直到剪影移动到光源的边缘。突然间,我们遇到了问题。图 3 是边缘形状的示例。
轮廓与背景/蒙面区域的黑色无法区分。OpenCV 要么假设我们的光源的轮廓突然变成了奇怪的形状,并且没有其他物体可以被检测到。
问题重述
我可以使用哪些工具来检测边缘形状是否存在某种中断?是否有一种好的/计算成本低廉的方法来确定我们的轮廓是否与另一个相交?
我所知行不通的墓地
- 假设一个静态或简单的轮廓形状。这些数字是代表一个更复杂的实际问题的漫画。
- 假设一个完美的圆形光源。
HoughCircles
不起作用。
解决方案
您可以使用该cv2.log_polar
功能展开圆形/椭圆形。
之后,np.argmax
可用于查找曲线。尝试使用 Scipy's 平滑曲线signal.savgol_filter()
。当物体遮挡光源时,平滑线和argmax数据会有很大的差异:
这是我使用的代码:
import numpy as np
import cv2
# Read the image
img = cv2.imread('/home/stephen/Desktop/JkgJw.png', 0)
# Find the log_polar image
log_polar = cv2.logPolar(img, (img.shape[0]/2, img.shape[1]/2), 40, cv2.WARP_FILL_OUTLIERS)
# Create a background to draw on
bg = np.zeros_like(log_polar)
# Iterate through each row in the image and get the points on the edge
h,w = img.shape
points = []
for col in range(h-1):
col_slice = log_polar[col:col+1, :]
curve = np.argmax(255-col_slice)
cv2.circle(bg, (curve, col), 0, 255, 1)
points.append((curve, col))
cv2.imshow('log_polar', log_polar)
cv2.waitKey(0)
cv2.destroyAllWindows()
import scipy
from scipy import signal
x,y = zip(*points)
x_smooth = signal.savgol_filter(x,123,2)
import matplotlib.pyplot as plt
plt.plot(x)
plt.plot(x_smooth)
plt.show()
推荐阅读
- sql-server - 需要一个查询,该查询可以报告在 SQL Server 中执行的最后 100 个查询以及它们的执行时间和执行它的用户
- azure - terraform 中一种资源的互斥属性
- excel - 查找表中每个值的最大值
- sharepoint-online - 如何让 PowerApps 查看 SharePoint Online 多选选项字段值?
- javascript - 如何使用 Javascript 将文本从一个字符迭代到另一个字符?
- javascript - if 语句基于 3 个不同的条件
- r - 条形标签从绘图中删除,mai/omi 参数没有解决问题
- flutter - 哪一个是性能方面更好的 Text 或提取的 TextWidget 函数?
- discord.js - 无效的位域标志或数字
- python - Pyspark - 用不同的字符替换字符串的一部分(字符数不均匀)