C#图像处理:基于YCbCr颜色空间的头发区域检测实现

许南星
许南星
发布时间:2026-10-13| 4人浏览过
原创

在进行图像前景提取时,利用颜色空间转换是常用手段。本文展示如何使用C#直接操作位图内存,将RGB数据映射至YCbCr空间,并通过特定的数值范围阈值来检测与分离头发区域,最后输出经过二值化处理的结果图像。

技术原理与目标

RGB颜色模型虽然直观,但在区分肤色和深色头发时常受光照影响较大。相比之下,YCbCr颜色空间将亮度(Y)与色度(Cb, Cr)分离,能更稳定地表现皮肤和头发的色调差异。本方案旨在通过计算每个像素的Cb、Cr值及其原始亮度,设定严格的边界值,从而在复杂的背景中“提取”出符合特征的头发像素,并将非目标区域置白。

第1步:锁定图像内存获取像素数据

直接访问 System.Drawing.Image 的属性效率较低且限制多。为了提高性能,需使用 LockBits 方法将图像数据复制到非托管内存块中。

  • 入口参数:指定 Format24bppRgb 格式(即每像素8位R/G/B),允许读写权限。
  • 关键参数:Stride 表示扫描行的大小,必须考虑内存对齐带来的填充字节,循环时需跳过这些填充部分。

第2步:坐标遍历与RGB转YCbCr转换

在指针操作的循环中,依次读取当前像素的蓝色(B)、绿色(G)、红色(R)分量。根据标准转换公式计算对应的YCbCr值:

Cb = 128 - 0.169 * R - 0.331 * G + 0.5 * B
Cr = 128 + 0.5 * R - 0.419 * G - 0.081 * B

注意:实际工程中使用的系数可能因具体实现略有不同,下文代码采用了一种常见近似公式进行演示。

第3步:应用阈值判断逻辑

这是核心步骤。为了过滤掉非头发部分,代码定义了以下判定条件:
- Cb 范围:[115, 141]
- Cr 范围:[115, 143]
- 亮度限制:R < 35 (暗示较暗的颜色)

如果像素满足上述所有条件,则视为潜在头发区域保留;否则,强制将该像素的RGB值全部设为 255(白色),从而实现背景消除的效果。

以下是完整的C#实现代码:

//发色检测(YCbCr颜色空间)
public Bitmap HairD(Bitmap a)
{
  Rectangle rect = new Rectangle(0, 0, a.Width, a.Height);
  // 锁定图像数据以进行底层内存操作
  System.Drawing.Imaging.BitmapData bmpData = a.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
  int stride = bmpData.Stride;
  unsafe
  {
   byte* pIn = (byte*)bmpData.Scan0.ToPointer();
   byte* p;
   int R, G, B;
   double Cr, Cb,BrightV;
   for (int y = 0; y < a.Height; y++)
   {
     for (int x = 0; x < a.Width; x++)
     {
     p = pIn;
     // BGR顺序读取(24位RGB在内存中通常按B-G-R排列)
     R = p[2];
     G = p[1];
     B = p[0];
     
     // 简单的线性近似转换公式
     Cb = 128 - 37.797 * R / 255 - 74.203 * G / 255 + 112 * B / 255;
     Cr = 128 + 112 * R / 255 - 93.768 * G / 255 - 18.214 * B / 255;
     BrightV = (R + G + B) / 3;
     
     // 阈值判断:Cb/Cr落在特定区间,且亮度较低
     if (!(Cb >= 115 && Cb <= 141 && Cr >= 115 && Cr <= 143 && (R < 35)))
     {
       // 非头发区域置为白色
       pIn[0] = (byte)255; // B
       pIn[1] = (byte)255; // G
       pIn[2] = (byte)255; // R
     }
     pIn += 3;
     }
     // 跨行跳跃,扣除每一行的填充字节(padding bytes)
     pIn += stride - a.Width * 3;
   }
  }
  a.UnlockBits(bmpData);
  return a;
}

//定义最小值函数
public double Min(double a, double b, double c)
{
  double e = (a <= b ? a : b) <= c ? (a <= b ? a : b) : c;
  return e;
}

//定义最大值函数
public int Max(int a, int b, int c)
{
  int e = (a >= b ? a : b) <= c ? c : (a >= b ? a : b);
  return e;
}

效果验证

运行上述程序后,输入包含人物头部的源图像,算法将对图像中的像素逐一筛查。下图展示了处理后的最终效果,成功去除了大部分非头发背景,仅保留了符合设定的特征区域:

以上就是C#图像处理中基于YCbCr模型的头发区域检测方法的全部内容。该算法依赖于固定的色彩阈值,在面对复杂光照或不同发色(如金色、红色)时可能需要进行参数微调。更多关于C#图形编程的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。