1000分求个自动抠图的源码? 影楼拍出来的照片背景色是绿色或红色,蓝色。如何精确抠出其中的人物出来,换另外一个背景,如大海,山等大自然的背景?给出源码者,我立即给分,分五次给。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 这里有一篇:可参考一下http://blog.csdn.net/huruihappy/archive/2009/07/22/4371632.aspx 读取图片的RGB,看如下代码#include <stdio.h>#include <stdlib.h>#include <malloc.h>typedef unsigned long DWORD;typedef int BOOL;typedef unsigned char BYTE;typedef unsigned short WORD;typedef struct tagBITMAPINFOHEADER{ DWORD biSize; long biWidth; long biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; long biXPelsPerMeter; long biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant;} BITMAPINFOHEADER;int ReadBmp(const char* szFileName);int GetDIBColor(int X, int Y, BYTE *r, BYTE *g, BYTE *b);BITMAPINFOHEADER bih;BYTE *Buffer = NULL;long LineByteWidth;int ReadBmp(const char* szFileName){FILE *file;WORD bfh[7];long dpixeladd;if (NULL == (file = fopen(szFileName, "rb"))){ return 0;}printf("%s\n", szFileName);fread(&bfh, sizeof(WORD), 7, file);if (bfh[0] != (WORD)(((WORD)'B')|('M'<<8))){ fclose(file); return 0;}fread(&bih, sizeof(BITMAPINFOHEADER), 1, file);if (bih.biBitCount < 24){ fclose(file); return 0;}dpixeladd = bih.biBitCount / 8;LineByteWidth = bih.biWidth * (dpixeladd);if ((LineByteWidth % 4) != 0)LineByteWidth += 4 - (LineByteWidth % 4);if ((Buffer = (BYTE*)malloc(sizeof(BYTE)* LineByteWidth * bih.biHeight)) != NULL){ fread(Buffer, LineByteWidth * bih.biHeight, 1, file); fclose(file); return 1;}fclose(file);return 0;}int GetDIBColor(int X, int Y, BYTE *r, BYTE *g, BYTE *b){int dpixeladd;BYTE *ptr;if (X < 0 || X >= bih.biWidth || Y < 0 || Y >= bih.biHeight){ return 0;}dpixeladd = bih.biBitCount / 8;ptr = Buffer + X * dpixeladd + (bih.biHeight - 1 - Y) * LineByteWidth;*b = *ptr;*g = *(ptr + 1);*r = *(ptr + 2);return 1;} 将背景文件也打开,一行行读取RGB,符合替换的,更新到原BMP的相应RGB上,就可以了。难度确实大。 抠像后的图片,边缘一般都不是很平滑。除非再作一次反走样给你个思路:1.获取原图图片的关键色和色差范围(也就是背景的颜色)2.分别判断RGB色,是否在你算出来的色差范围之内,如果是,将该点的alpha 置为03.有了alpha通道,然后再 跟其它背景混合就以你的图片举个例子:关键色是G色,色差是:21当然这个值得自己调整,所谓抠像力度关键色有可能有三种,分别为RGB,然后在扫描每一个像素点,获取ALPHA值,再混算B :if (PS[FCurx] > PS[FCurx + 1] + aKeycolor) and (PS[FCurx] > PS[FCurx + 2] + aKeycolor) then FAlpha := 0else FAlpha := 255;G:if (PS[FCurx + 1] > PS[FCurx] + aKeycolor) and (PS[FCurx+ 1] > PS[FCurx + 2] + aKeycolor) then FAlpha := 0else FAlpha := 255;R:if (PS[FCurx + 2] > PS[FCurx + 1] + aKeycolor) and (PS[FCurx + 2] > PS[FCurx ] + aKeycolor) then FAlpha := 0else FAlpha := 255; 我的用MATLAB 写过类似的东西 Delphi刚接触 还没写过我个人认为影楼的话用 Photoshop 手工 质量比较好 毕竟照片千差万别 通用的抠图不易实现“影楼拍出来的照片背景色是绿色或红色,蓝色。” 可以尝试用 色度分割 所以说 还是用 Photoshop 手工 质量比较好 顾客会更加满意 专业的东西,是在这里找不到答案的,人家有也未必肯免费给你,CSDN的分能用来干嘛? 我以前有试过一个偷懒的方法,在ps中制作一个通用的抠图动作,然后用delphi 写个程序将数码照片路径传入,执行ps抠图,ps抠图完毕后再显示出来。如此一来,效果就可以很好了,毕竟ps中有好多效果很好的抠图插件嘛。期待更专业的方法。。 不用UP,基本上这个东西不会在这里得到完美的解决方案,因为这玩意是有经济市场的。还有一个问题就是,这东西本身就是复杂的工作,比如你要用PS去实现这个效果,你要多少个步骤?这每个步骤有需要人工选择取样点的吗,还是就是基本的PS中菜单操作? 文本文件的保存 打印机问题: 求sql语句! 字符串的问题? 使用DevExpress的QuantumGrid时如何保存和加载Grid的设置信息? 奇怪,TWEBBROWSER没了 Delphi实现球体上面均匀分布点 cxgrid 下拉列表查找问题 delphi中如何调用DLL文件? 为什么窗体在显示为模式窗体时要报错? StringToWideChar在WINDOWS7下和XP下不一样呢? 遇到一个非常麻烦的事情。
可参考一下http://blog.csdn.net/huruihappy/archive/2009/07/22/4371632.aspx
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>typedef unsigned long DWORD;
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
long biWidth;
long biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
long biXPelsPerMeter;
long biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;int ReadBmp(const char* szFileName);
int GetDIBColor(int X, int Y, BYTE *r, BYTE *g, BYTE *b);BITMAPINFOHEADER bih;
BYTE *Buffer = NULL;
long LineByteWidth;int ReadBmp(const char* szFileName)
{
FILE *file;
WORD bfh[7];
long dpixeladd;
if (NULL == (file = fopen(szFileName, "rb")))
{
return 0;
}
printf("%s\n", szFileName);fread(&bfh, sizeof(WORD), 7, file);
if (bfh[0] != (WORD)(((WORD)'B')|('M'<<8)))
{
fclose(file);
return 0;
}
fread(&bih, sizeof(BITMAPINFOHEADER), 1, file);if (bih.biBitCount < 24)
{
fclose(file);
return 0;
}dpixeladd = bih.biBitCount / 8;
LineByteWidth = bih.biWidth * (dpixeladd);
if ((LineByteWidth % 4) != 0)
LineByteWidth += 4 - (LineByteWidth % 4);if ((Buffer = (BYTE*)malloc(sizeof(BYTE)* LineByteWidth * bih.biHeight)) != NULL)
{
fread(Buffer, LineByteWidth * bih.biHeight, 1, file); fclose(file);
return 1;
}fclose(file);
return 0;
}int GetDIBColor(int X, int Y, BYTE *r, BYTE *g, BYTE *b)
{
int dpixeladd;
BYTE *ptr;
if (X < 0 || X >= bih.biWidth || Y < 0 || Y >= bih.biHeight)
{
return 0;
}dpixeladd = bih.biBitCount / 8;
ptr = Buffer + X * dpixeladd + (bih.biHeight - 1 - Y) * LineByteWidth;*b = *ptr;
*g = *(ptr + 1);
*r = *(ptr + 2);return 1;
}
难度确实大。
给你个思路:
1.获取原图图片的关键色和色差范围(也就是背景的颜色)
2.分别判断RGB色,是否在你算出来的色差范围之内,如果是,将该点的alpha 置为0
3.有了alpha通道,然后再 跟其它背景混合
就以你的图片举个例子:
关键色是G色,色差是:21当然这个值得自己调整,所谓抠像力度
关键色有可能有三种,分别为RGB,然后在扫描每一个像素点,获取ALPHA值,再混算
B :
if (PS[FCurx] > PS[FCurx + 1] + aKeycolor) and (PS[FCurx] > PS[FCurx + 2] + aKeycolor) then
FAlpha := 0
else
FAlpha := 255;
G:
if (PS[FCurx + 1] > PS[FCurx] + aKeycolor) and (PS[FCurx+ 1] > PS[FCurx + 2] + aKeycolor) then
FAlpha := 0
else
FAlpha := 255;
R:
if (PS[FCurx + 2] > PS[FCurx + 1] + aKeycolor) and (PS[FCurx + 2] > PS[FCurx ] + aKeycolor) then
FAlpha := 0
else
FAlpha := 255;