>我有一个 3 通道Mat
图像,类型是 CV_8UC3
.我想循环比较一个像素的强度值与其相邻像素,然后设置0
或1
相邻像素是否更大。我可以得到强度调用Img.at<Vec3b>(x,y)
.
但我的问题是:我如何比较两个Vec3b
?
我是否应该比较每个通道(BGR 或 Vec3b[0]
、Vec3b[1]
和 Vec3b[2]
)的像素值,然后将三个通道结果合并到单个Mat
对象中?
我又:)
如果要比较(或多或少)两个 RGB 值,则需要将三维 RGB 空间投影到平面或轴上。
当然,有很多可能性可以做到这一点,但一个简单的方法是使用 HSV 颜色空间。然而,色调(H
)不适合作为线性阶函数,因为它是圆形的(即值1.0与0.0相同,因此您无法决定0.5>0.0还是0.5<0.0)。但是,饱和度 ( S
) 或值 ( V
) 是适合您目的的投影函数:
- 如果要使彩色像素比单色像素"大",则首选
S
。 - 如果要使较亮的像素大于较暗的像素,则可能更喜欢
V
。 - 此外,
S
和V
的任意组合都将是一个有效的投影函数,例如S+V
.
据我了解,您需要一个度量来计算两个 Vec3b 像素之间的距离/相似性。这可以反映到在n数学空间中查找两个向量之间的距离的一般问题中。
其中一个著名的度量(我认为这就是你所要求的),是欧几里得距离。
如果您使用的是Opencv,那么您可以简单地使用:
cv::Vec3b a(1, 1, 1);
cv::Vec3b b(5, 5, 5);
double dist = cv::norm(a, b, CV_L2);
您可以参考此内容来阅读有关 cv::norm 及其选项的信息。
编辑:如果您这样做是为了测量颜色相似性,建议使用 LAB 颜色空间,因为它证明了 LAB 空间中的欧几里得距离是人类对颜色感知的良好近似值。
编辑2:我明白你的意思,为此你可以得到每个向量的大小,然后比较它们,像这样:
double a_magnitude = cv::norm(a, CV_L2);
double b_magnitude = cv::norm(b, CV_L2);
if(a_magnitude > b_magnitude)
// do something
else
// do something else.