影楼拍出来的照片背景色是绿色或红色,蓝色。如何精确抠出其中的人物出来,换另外一个背景,如大海,山等大自然的背景?
给出源码者,我立即给分,分五次给。

解决方案 »

  1.   

    这里有一篇:
    可参考一下http://blog.csdn.net/huruihappy/archive/2009/07/22/4371632.aspx
      

  2.   

    读取图片的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;
    }
      

  3.   

    将背景文件也打开,一行行读取RGB,符合替换的,更新到原BMP的相应RGB上,就可以了。
    难度确实大。
      

  4.   

    抠像后的图片,边缘一般都不是很平滑。除非再作一次反走样
    给你个思路:
    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;
      

  5.   

    我的用MATLAB 写过类似的东西  Delphi刚接触 还没写过我个人认为影楼的话用 Photoshop 手工 质量比较好 毕竟照片千差万别 通用的抠图不易实现“影楼拍出来的照片背景色是绿色或红色,蓝色。” 可以尝试用 色度分割
      

  6.   

    所以说 还是用 Photoshop 手工 质量比较好  顾客会更加满意
      

  7.   

    专业的东西,是在这里找不到答案的,人家有也未必肯免费给你,CSDN的分能用来干嘛?
      

  8.   

    我以前有试过一个偷懒的方法,在ps中制作一个通用的抠图动作,然后用delphi 写个程序将数码照片路径传入,执行ps抠图,ps抠图完毕后再显示出来。如此一来,效果就可以很好了,毕竟ps中有好多效果很好的抠图插件嘛。期待更专业的方法。。
      

  9.   

    不用UP,基本上这个东西不会在这里得到完美的解决方案,因为这玩意是有经济市场的。还有一个问题就是,这东西本身就是复杂的工作,比如你要用PS去实现这个效果,你要多少个步骤?这每个步骤有需要人工选择取样点的吗,还是就是基本的PS中菜单操作?