我正在使用EMGU.CV 3.4.1.2976(最新)库来分析图像,但没有得到预期的结果。我以ImageJ为基准,但是任何图像包都可以。
要测试功能,我正在分析一个简单的蓝色640x320 jpeg,如下所示。该图像的RGB值为0,0,255。
ImageJ的色相直方图(值为170,计数为2048000)
使用下面的代码,我在120而不是170处出现尖峰-计数2048000是正确的。 我在做什么错了?
public void AnalyzeEmgu(object image)
{
int[] arr = new int[256];
using (Bitmap bmp = (Bitmap)image)
{
using (Image<Hsv, byte> hsvImage = new Image<Hsv, byte>(bmp))
{
Image<Gray, byte>[] channels = hsvImage.Split();
Image<Gray, byte> imgHue = channels[0];
for (int x = 0; x < imgHue.Rows; x++)
{
for (int y = 0; y < imgHue.Cols; y++)
{
var b = imgHue.Data[x, y, 0];
arr[b]++; // fill array with Hue data. Add 1 (++) to count amount.
}
}
}
}
GC.Collect();
OnImageFinished(arr); // return array
}
// call function.
Bitmap bmp =new Bitmap(@"c:\test\blue.jpg");
AnalyzeEmgu(bmp);
更新
轮到我需要转换为其他色彩空间,但仍然不是100%正确。 arr
现在返回171而不是170。当然这只是一个微小的差异,但是对于更复杂的图像,这是值得注意的。
可能是什么问题?
public void AnalyzeEmgu(object image)
{
int[] arr = new int[256];
using (Mat orig = new Mat((string)image, ImreadModes.Color))
{
using (Mat hsv = new Mat())
{
// convert color to HSV here.
CvInvoke.CvtColor(orig, hsv, ColorConversion.Bgr2HsvFull);
Mat[] channels = hsv.Split();
using (Image<Bgr, byte> img = channels[0].ToImage<Bgr, byte>())
{
for (int x = 0; x < img.Rows; x++)
{
for (int y = 0; y < img.Cols; y++)
{
var b = img.Data[x, y, 0];
arr[b]++;
}
}
}
channels[1].Dispose();
channels[2].Dispose();
}
}
GC.Collect();
}
OnImageFinished(arr);
答案 0 :(得分:1)
我不使用ImageJ或EMGU.CV,但我会分享一些要考虑的内容...
(1)
正确的色相值为240(不是170)度。
在色轮中,蓝色(0,0,255)的色相为 240 度。请注意,它也可以称为 -120 。
此逻辑可以解释为什么您要在AnalyzeEmgu
函数中针对特定的色调“达到120的峰值” 。
通过添加360可以从负模式恢复。例如: myHue = (-120) + 360;
,其结果为:240
。
(上)图片来源:http://www.graphic-design.com/Photoshop/color_cast/visible_color_spectrum.html
(2)
为什么ImageJ的色相直方图给出 170 ?
如果您查看图像直方图,其最大值为 255 ,但滚轮/圆应为 360 。他们这样做为什么没有逻辑,但是可以解决:
IF: 360 / 255 = 1.4117647058823529411764705882353
THEN: 170 * 1.4117647058823529411764705882353 = 240 degrees.
(3)
“使用下面的代码,我的峰值是120而不是170”
尝试
myHue = 360 - 120; //gives 240
在下面用Photoshop制作的图像中,我显示了(从顶部开始)如果我们变蓝,它将正确列出为 240 度,并且在旅行时发现其距离为88像素向下。
相反的是从底部向上移动,我们看到相同的88像素距离现在给出 120 (绿色)。
您的代码色轮被翻转(上下颠倒)。将 A 与 B 进行比较。
Photoshop使用系统 A ,但是您的值表明您的代码看起来像系统 B 。