比较两个直方图时为负值



我使用EmguCV(c#(直方图来比较两个HSV图像。但有时我会得到负值。我假设当我比较2个直方图值时,该值将处于区间<0和1>。然而,色调或饱和度的一些值有时是负数,如-0.145。

首先,我得到了字节图像数组,并将其转换为image<Hsv,字节>-img1.

Image<Hsv, Byte> img1 = null;
Mat byteImageMat = new Mat();
Mat hsvMat = new Mat();
CvInvoke.Imdecode(request.ByteImage, Emgu.CV.CvEnum.ImreadModes.AnyColor, byteImageMat);
CvInvoke.CvtColor(byteImageMat, hsvMat, ColorConversion.Bgr2Hsv);
img1 = hsvMat.ToImage<Hsv, Byte>();

然后我创建密度直方图并分割各个通道。

DenseHistogram ComparedHistoHue = new DenseHistogram(180, new RangeF(0, 180));
DenseHistogram ComparedHistoSaturation = new DenseHistogram(256, new RangeF(0, 256));
DenseHistogram ComparedHistoBrightness = new DenseHistogram(256, new RangeF(0, 256));
Image<Gray, Byte> hueChannel = img1[0];
Image<Gray, Byte> saturationChannel = img1[1];
Image<Gray, Byte> brightnessChannel = img1[2];

之后我计算直方图

ComparedHistoHue.Calculate(new Image<Gray, Byte>[] { hueChannel }, false, null);
ComparedHistoSaturation.Calculate(new Image<Gray, Byte>[] { saturationChannel }, false, null);
ComparedHistoBrightness.Calculate(new Image<Gray, Byte>[] { brightnessChannel }, false, null);

此时,我从之前创建的文件中加载直方图,并将其分配到Mat(loadedMatHue、loadedMatSaturation和loadedMatBrightness(中。

double hue = CvInvoke.CompareHist(loadedMatHue, ComparedHistoHue, Emgu.CV.CvEnum.HistogramCompMethod.Correl);
double satuation = CvInvoke.CompareHist(loadedMatSaturation, ComparedHistoSaturation, Emgu.CV.CvEnum.HistogramCompMethod.Correl);
double brightnes = CvInvoke.CompareHist(loadedMatBrightness, ComparedHistoBrightness, Emgu.CV.CvEnum.HistogramCompMethod.Correl);

有人能告诉我,为什么在色调或饱和度变量中是负值吗?在我的观点和测试中,双变量在一个时刻总是只有一个负值。

对于HSV,数字在0和1之间的想法是不正确的。如果希望图像的值介于0和1之间,则该图像必须为灰度级。

在HSV中,您将其分为三个定义,Hue、S饱和度和V值。

色调存储在0到360度之间,但如果将色调旋转超过0,则可能变为负值。

饱和度考虑从0到1,即灰度值。如果此通道中有负值,请忽略它们,因为此值的最低值应为0。最高值也是如此,它将是1,因为灰度通道的最高值只能是一。就像我之前所说的,最好从0到1的灰度来考虑这个通道。

值与饱和度非常相似,唯一的区别是该值被认为是"饱和度";颜色的亮度乘以给定的S[饱和度]";此值也只能介于0和1之间,并且应剪裁此空间之外的任何值。

如果你想要更深入的解释,你可以看看Stack的这篇文章,它非常详细,我认为它应该在这篇文章中得到赞扬。

如果必须剪裁这些值,则可以始终使用下面的一些示例代码访问每个通道的像素值。

Image<Hsv,Byte> sampleImage = new Image<Hsv,Byte>("pathtoimage");
//X and y are the pixel coordinates on an image
//Hue channel
byte hue = sampleImage.Data[y,x,0];
//Saturation channel
byte sat = sampleImage.Data[y,x,1];
//Value channel
byte val = sampleImage.Data[y,x,2];

您可以将这些值放入循环中,并检查像素是否在边界之外,以及是否分别用高值或低值替换它。

最新更新