python - OpenCV Python - 替换图像中的通道
问题描述
我目前在 x 和 y 轴上使用 Sobel 滤波器并为此计算一个角度。输出图像是 HSV 颜色空间中两个方向的加权平均值。
我正在尝试用计算出的角度([0,pi] 范围内的一维列表)替换 H 通道,然后如果 H 不为零,则将 S 和 V 通道设置为 255
我用来计算角度的代码是:
Sx = cv2.Sobel(gray, -1, 1, 0, ksize=3)
Sy = cv2.Sobel(gray, -1, 0, 1, ksize=3)
theta = np.arctan2(Sy, Sx)
并交换频道:
color[:,:,0] = np.rad2deg(theta)
color[color[:, :, 0] > 0, 1] = 255
color[color[:, :, 0] > 0, 2] = 255
我的预期结果类似于:
如果输入图像是带有黑色圆圈的白色背景
解决方案
有几个与色彩空间相关的问题(HSV 和 BGR、数组 dtype 和范围)。在大多数情况下,OpenCV 希望用户注意这些事情。
您将 numpy 数组视为在 HSV 颜色空间中,但
cv2.imshow
将图像解释为 BGR。该color
数组需要显式转换为 BGR,如下所示:cv2.imshow("image", cv2.cvtColor(color, cv2.COLOR_HSV2BGR))
如果
gray
是 uint8 图像,则 Sx/Sy 将仅包含非负值。这基本上将所有负导数设置为零,这是错误的。建议将 Sobel ddepth 参数更改为 CV_32F (以确保输出为浮点数):(Sx = cv2.Sobel(gray, cv2.CV_32F, 1, 0, ksize=3)
同样适用于Sy
)。或者您可以明确确保gray.dtype
是np.float32
.的输出
np.rad2deg
(理论上)在 [0, 360] 范围内,但表示图像的 numpy 数组的值应在 [0, 255] 范围内。这是处理这种情况的一种可能方法:
theta = np.arctan2(Sy, Sx)
# Instead of converting [-pi, pi] range to degrees, linearly convert
# the array to [0, 255] range using cv2.normalize.
hue_value = cv2.normalize(theta, dst=None, alpha=255.0, norm_type=cv2.NORM_MINMAX)
# Select nonzero values as a mask.
mask = np.logical_or(theta > 0.01, theta < -0.01)
color[:,:,0] = hue_value
color[mask, 1] = 255
color[mask, 2] = 255
推荐阅读
- html - 如何在加载另一个页面时自动关闭 DIV
- java - 如何将 volatile 参数传递给不同类中的 Java 方法?
- asp.net-core - 部署到 Azure 的 Razor 页面的 Microsoft.AspNetCore.Mvc.Internal.AmbiguousActionException
- css - 一旦标题悬停,如何使无序列表“停留”?
- google-cloud-firestore - 保存离线 webapp Firestore 的数据
- javascript - 如何使用 json 服务器达到特定的端点
- reactjs - 使用 TypeScript 和 ReactJS 加载 JSON 会给出“找不到文件”
- python - 处理来自 json 的数据以反映每个条目的单个值
- embedded-linux - devtool upgrade 错误:配方已经在您的工作区中
- angular - 如何验证用户是否已登录