我正在使用emgucv。
我希望进行hsl过滤。
颜色范围是0到359。
我正在过滤黄色,所以我正在寻找30到60之间的色调。
我加载一个现有的位图并将其作为hsv图像加载:
var img = new Image<Hsv, int>(@"D:\yellow.jpg");
当我运行它时,我得到:
System.NotSupportedException: 'There is an error converting Emgu.CV.Structure.Bgr to Emgu.CV.Structure.Hsv: Requested value 'Bgr2Bgr' was not found.'
我可以这样做:
var img = new Image<Hsv, byte>(@"D:\yellow.jpg");
这样可以很好地加载,但是字节值最多只能达到255。
我还能尝试什么?我是否必须将每个“像素”数据乘以值* 255/359?
答案 0 :(得分:0)
将每个像素值乘以255/359会给我带来错误的提示,因为HSL中的三个通道(色调[范围从0度到360度的分量],饱和度,亮度)不对应于这三个通道以RGB(红色,绿色,蓝色)。我对C#并不十分熟悉,但是the following snippets对于您进行颜色转换可能会很有用。
为了您的利益而在此处转贴:
// Convert an HLS value into an RGB value.
public static void HlsToRgb(double h, double l, double s,
out int r, out int g, out int b)
{
double p2;
if (l <= 0.5) p2 = l * (1 + s);
else p2 = l + s - l * s;
double p1 = 2 * l - p2;
double double_r, double_g, double_b;
if (s == 0)
{
double_r = l;
double_g = l;
double_b = l;
}
else
{
double_r = QqhToRgb(p1, p2, h + 120);
double_g = QqhToRgb(p1, p2, h);
double_b = QqhToRgb(p1, p2, h - 120);
}
// Convert RGB to the 0 to 255 range.
r = (int)(double_r * 255.0);
g = (int)(double_g * 255.0);
b = (int)(double_b * 255.0);
}
// Convert an RGB value into an HLS value.
public static void RgbToHls(int r, int g, int b,
out double h, out double l, out double s)
{
// Convert RGB to a 0.0 to 1.0 range.
double double_r = r / 255.0;
double double_g = g / 255.0;
double double_b = b / 255.0;
// Get the maximum and minimum RGB components.
double max = double_r;
if (max < double_g) max = double_g;
if (max < double_b) max = double_b;
double min = double_r;
if (min > double_g) min = double_g;
if (min > double_b) min = double_b;
double diff = max - min;
l = (max + min) / 2;
if (Math.Abs(diff) < 0.00001)
{
s = 0;
h = 0; // H is really undefined.
}
else
{
if (l <= 0.5) s = diff / (max + min);
else s = diff / (2 - max - min);
double r_dist = (max - double_r) / diff;
double g_dist = (max - double_g) / diff;
double b_dist = (max - double_b) / diff;
if (double_r == max) h = b_dist - g_dist;
else if (double_g == max) h = 2 + r_dist - b_dist;
else h = 4 + g_dist - r_dist;
h = h * 60;
if (h < 0) h += 360;
}
}
答案 1 :(得分:0)
最简单的方法是读取文件。那应该给你一个RGBA图像。将RGBA转换为BGR,然后从BGR转换为HLS。
我这样使用Mats:
Mat src = new Mat(@"D:\yellow.jpg");
Mat Bgr = new Mat();
Mat Hls = new Mat();
CvInvoke.CvtColor(src, Bgr, ColorConversion.Rgba2Bgr);
CvInvoke.CvtColor(Bgr, Hls, ColorConversion.Bgr2Hls);
我认为是的。您想要进行HSL过滤,这告诉我您需要HSL格式的图像。在OpenCV中,在所有情况下,HSV,HSL等只能达到255,因此它们非常适合8位图像的字节。如果您使用的是32位深度,则值将保持不变。不支持16位图像。对于HSV,色相的值是0-180(我将BGR与8位无符号值一起使用),我只是乘以或除以2,但这仅在需要向用户显示此值或获取色相值时才需要来自用户。最终,它对我内部如何使用Hue值没有影响。
HSL的处理方式完全相同,8位的Hue值为0-180,不支持16位,而32位则保持不变。
道格