我有一个使用Canny边缘检测器导出的Mat
对象,我使用findContours
函数从此类图像中提取了轮廓。现在,我想为每个这样的轮廓做些什么,就是检查一下两侧的颜色。
对于“颜色”,我离散了HSI色彩空间,但是对于如何在给定轮廓的两侧“拾取颜色”感到非常困惑。
有没有一种简便的方法?
答案 0 :(得分:2)
您可以使用应用了Canny边缘检测器的图像来执行此操作。拍摄该图像的gradient。渐变是向量。如Wiki页面图像所示(如下所示),渐变指向最大增长率的方向。如果采用负梯度,则它指向最大降低率的方向。因此,如果在轮廓点处采样图像的梯度,则这些点处的正和负梯度应指向轮廓点两侧的区域。因此,您可以沿这些方向对点进行采样,以了解所需的颜色。
图像渐变:
示例python代码显示了如何针对下面显示的简单图像完成此操作。它使用Sobel来计算梯度。
输入图像:
Canny边缘和采样点:
绿色:轮廓上的点
红色:指向正梯度方向
蓝色:指向负梯度方向
import cv2
import numpy as np
from matplotlib import pyplot as plt
im = cv2.imread('grad.png', 0)
dx = cv2.Sobel(im, cv2.CV_32F, 1, 0)
dy = cv2.Sobel(im, cv2.CV_32F, 0, 1)
edge = cv2.Canny(im, 64, 192)
dx = dx / np.sqrt(dx*dx + dy*dy + 0.01)
dy = dy / np.sqrt(dx*dx + dy*dy + 0.01)
r = 20
y, x = np.nonzero(edge)
pos1 = (np.int32(x[128]+r*dx[y[128], x[128]]), np.int32(y[128]+r*dy[y[128], x[128]]))
pos2 = (np.int32(x[128]-r*dx[y[128], x[128]]), np.int32(y[128]-r*dy[y[128], x[128]]))
im2 = cv2.cvtColor(edge, cv2.COLOR_GRAY2BGR)
cv2.circle(im2, pos1, 10, (255, 0, 0), 1)
cv2.circle(im2, pos2, 10, (0, 0, 255), 1)
cv2.circle(im2, (x[128], y[128]), 10, (0, 255, 0), 1)
plt.imshow(im2)