c# 实现photoshop 抠图功能,分离人物和背景

昵称你还要唯一神经病 2010-06-22 11:04:19
我在工作中遇到了这样一个需求,用代码将人物从图片中分离出来,然后更换背景。
举例:
图片就类似咱们照的证件照那种,背景是纯色的,现在要通过程序把纯色的背景换成风景。
胡睿先生用Delphi实现了,而且也告诉我原理是大律阀值分割法,不过我不会用,有高人可以用c#实现吗?
身边的朋友很少有涉及图形图像编程,没办法只能求助大家了。
...全文
2241 45 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
45 条回复
切换为时间正序
请发表友善的回复…
发表回复
wbloodc 2010-11-15
  • 打赏
  • 举报
回复
纯色的话,相对处理要容易很多,可以直接使用Photoshop的插件完成,类似的插件网上有很多。或者自己写PS script也可以的,实现也不是很难。
int64 2010-11-15
  • 打赏
  • 举报
回复
啥客户啊,真会提要求啊
xiulijing19870911 2010-11-15
  • 打赏
  • 举报
回复
好贴~~~关注~~~我也在找C#抠图的方法
deyygywxf 2010-10-30
  • 打赏
  • 举报
回复
具体没搞个,但是我知道.net 中有一个方法取得 某个坐标点的像素 取得这个像素就好办了,如果能取得纯色背景的某个座标点,然后分析可能有得搞.....

具体在System.Draw 或 System.Draw.Image命名空间下面

deedzhaoyun 2010-10-30
  • 打赏
  • 举报
回复
正在学图像处理,大家的回答好有启发啊,收藏这个帖子
deyygywxf 2010-10-30
  • 打赏
  • 举报
回复
具体没搞个,但是我知道.net 中有一个方法取得 某个坐标点的像素 取得这个像素就好办了,如果能取得纯色背景的某个座标点,然后分析可能有得搞.....

具体在System.Draw 或 System.Draw.Image命名空间下面
liyan 2010-10-30
  • 打赏
  • 举报
回复
真没想到c#强大到这个程度!
命名空间了得!
看看!
porschev 2010-10-28
  • 打赏
  • 举报
回复
搞不定。。。只是围观一下
kiddc 2010-10-28
  • 打赏
  • 举报
回复
我只会对已经描出多边形的region换背景。pictureBox1里的图就是要换的背景图
GraphicsPath Path = new GraphicsPath();
path.AddPolygon(point);//point是存了多边形顶点坐标的数组
Graphics g = Graphics.FromImage(this.pictureBox1.Image);
g.setClips(path);
g.DrawImage(new Bitmap("刚刚那个有多边形的图.jpg"), this.ClientRectangle);
g.Dispose();
多边形是这样,人形就不知道了。
人形难啊,期待高手,看看有没有方法学习一下

LorenLiu 2010-10-16
  • 打赏
  • 举报
回复 1
给一个例子你参考一下吧,这个方法会在人物和背景的边界留下一圈背景色。


private Color m_BackgroundColor;

public Bitmap TransparentBackground(Bitmap bmp)
{
if (bmp == null)
return null;

Int32 width = bmp.Width;
Int32 height = bmp.Height;
Bitmap result = new Bitmap(width, height);
m_BackgroundColor = bmp.GetPixel(0, 0);

for (Int32 y = 0; y < height; y++)
for (Int32 x = 0; x < width; x++)
{
if (TestIfColorBelongsToBackground(bmp, x, y))
result.SetPixel(x, y, Color.Transparent);
else
result.SetPixel(x, y, bmp.GetPixel(x, y));
}
return result;
}

// This is the method need to be optimized
// Currently the border of people will contains
// the background color
private Boolean TestIfColorBelongsToBackground(Bitmap bmp, Int32 x, Int32 y)
{
if (bmp == null)
return false;

Int32 width = bmp.Width;
Int32 height = bmp.Height;

Color cp = bmp.GetPixel(x, y);
Color cp0;
Color cp1;
Color cp2;
Color cp3;
Color cp4;
Color cp5;
Color cp6;
Color cp7;

// p0 p1 p2
// p3 p p4
// p5 p6 p7
// cp0 = bmp.GetPixel(x - 1, y - 1);
// cp1 = bmp.GetPixel(x, y - 1);
// cp2 = bmp.GetPixel(x + 1, y - 1);
// cp3 = bmp.GetPixel(x - 1, y);
// cp4 = bmp.GetPixel(x + 1, y);
// cp5 = bmp.GetPixel(x - 1, y + 1);
// cp6 = bmp.GetPixel(x, y + 1);
// cp7 = bmp.GetPixel(x + 1, y + 1);
if (x == 0 && y == 0)
{
cp4 = bmp.GetPixel(x + 1, y);
cp6 = bmp.GetPixel(x, y + 1);
cp7 = bmp.GetPixel(x + 1, y + 1);
return (cp == cp4 && cp == cp6 && cp == cp7 && cp == m_BackgroundColor);
}
else if (x == 0 && y == height - 1)
{
cp1 = bmp.GetPixel(x, y - 1);
cp2 = bmp.GetPixel(x + 1, y - 1);
cp4 = bmp.GetPixel(x + 1, y);
return (cp == cp1 && cp == cp2 && cp == cp4 && cp == m_BackgroundColor);
}
else if (x == width - 1 && y == 0)
{
cp3 = bmp.GetPixel(x - 1, y);
cp5 = bmp.GetPixel(x - 1, y + 1);
cp6 = bmp.GetPixel(x, y + 1);
return (cp == cp3 && cp == cp5 && cp == cp6 && cp == m_BackgroundColor);
}
else if (x == width - 1 && y == height - 1)
{
cp0 = bmp.GetPixel(x - 1, y - 1);
cp1 = bmp.GetPixel(x, y - 1);
cp3 = bmp.GetPixel(x - 1, y);
return (cp == cp0 && cp == cp1 && cp == cp3 && cp == m_BackgroundColor);
}
else if (x != 0 && x != width - 1 && y == 0)
{
cp3 = bmp.GetPixel(x - 1, y);
cp4 = bmp.GetPixel(x + 1, y);
cp5 = bmp.GetPixel(x - 1, y + 1);
cp6 = bmp.GetPixel(x, y + 1);
cp7 = bmp.GetPixel(x + 1, y + 1);
return (cp == cp3 && cp == cp4 && cp == cp5 && cp == cp6 && cp == cp7 && cp == m_BackgroundColor);
}
else if (x != 0 && x != width - 1 && y == height - 1)
{
cp0 = bmp.GetPixel(x - 1, y - 1);
cp1 = bmp.GetPixel(x, y - 1);
cp2 = bmp.GetPixel(x + 1, y - 1);
cp3 = bmp.GetPixel(x - 1, y);
cp4 = bmp.GetPixel(x + 1, y);
return (cp == cp0 && cp == cp1 && cp == cp2 && cp == cp3 && cp == cp4 && cp == m_BackgroundColor);
}
else if (x == 0 && y != 0 && y != height - 1)
{
cp1 = bmp.GetPixel(x, y - 1);
cp2 = bmp.GetPixel(x + 1, y - 1);
cp4 = bmp.GetPixel(x + 1, y);
cp6 = bmp.GetPixel(x, y + 1);
cp7 = bmp.GetPixel(x + 1, y + 1);
return (cp == cp1 && cp == cp2 && cp == cp4 && cp == cp6 && cp == cp7 && cp == m_BackgroundColor);
}
else if (x == width - 1 && y != 0 && y != height - 1)
{
cp0 = bmp.GetPixel(x - 1, y - 1);
cp1 = bmp.GetPixel(x, y - 1);
cp3 = bmp.GetPixel(x - 1, y);
cp5 = bmp.GetPixel(x - 1, y + 1);
cp6 = bmp.GetPixel(x, y + 1);
return (cp == cp0 && cp == cp1 && cp == cp3 && cp == cp5 && cp == cp6 && cp == m_BackgroundColor);
}
else
{
cp0 = bmp.GetPixel(x - 1, y - 1);
cp1 = bmp.GetPixel(x, y - 1);
cp2 = bmp.GetPixel(x + 1, y - 1);
cp3 = bmp.GetPixel(x - 1, y);
cp4 = bmp.GetPixel(x + 1, y);
cp5 = bmp.GetPixel(x - 1, y + 1);
cp6 = bmp.GetPixel(x, y + 1);
cp7 = bmp.GetPixel(x + 1, y + 1);
return (cp == cp0 && cp == cp1 && cp == cp2 && cp == cp3 && cp == cp4 && cp == cp5 && cp == cp6 && cp == cp7 && cp == m_BackgroundColor);
}
}
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 huwei001982 的回复:]
光在论坛上说很难说清楚,外包给别人做吧
[/Quote]

不值1小时工资,咋包?
  • 打赏
  • 举报
回复
这可不需要遍历图片
  • 打赏
  • 举报
回复
基本上假设你取图像上的某一个点,例如左上方的点,那么它周围的几个点跟它相差多少是很容易计算的吧?!

把不接近的点记录下来,把接近的点继续迭代地去判断,最终迭代会因为找不到更多接近的外部点而停止,你记录下来的就是边界。
hrwang 2010-10-16
  • 打赏
  • 举报
回复
初学者,路过,帮顶,很有难度。
yudengchang 2010-10-16
  • 打赏
  • 举报
回复
你的背景颜色不是一色的吗,这样你可以取得背景颜色的元素,把其他的保存到另外的地方就可以了,取得像素可以使用GDI+ bitmap 的 GetPixel,具体实现:

//像素点的坐标值,根据实际情况来
int x = 20, y = 40;

using (Bitmap bmp = new Bitmap(@"文件路径"))
{
Color pixelColor = bmp.GetPixel(x, y);

//像素点颜色的 Alpha 值
byte alpha = pixelColor.A;
//颜色的 RED 分量值
byte red = pixelColor.R;
//颜色的 GREEN 分量值
byte green = pixelColor.G;
//颜色的 BLUE 分量值
byte blue = pixelColor.B;
}
bloodish 2010-10-15
  • 打赏
  • 举报
回复
FloodFill算法,实现类似PS魔术棒的效果
这里有个C#的例子下载
Flood Fill
koukoujiayi 2010-10-15
  • 打赏
  • 举报
回复
这里有一位图形方面的强人,可联系之!
http://topic.csdn.net/u/20101014/21/a74f7ac5-e23e-407b-b837-3b7ed89b9930.html
火柴没帽 2010-10-15
  • 打赏
  • 举报
回复
有一个开源的C#图形处理软件,功能和PS差不多,可以下来看看源码,名字忘了,LZ自己百度去吧
crackdung 2010-10-15
  • 打赏
  • 举报
回复
你试试 Luxand FaceSDK




my blog
http://ufo-crackerx.blog.163.com/
ErrorCode1987 2010-10-15
  • 打赏
  • 举报
回复
好贴
关注~
加载更多回复(24)

111,092

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧