Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

since any color space on its own has some problems (bgr with intensity, hsv with "non-colors" like black/white/silver), i'd suggest adding up several colorspaces into a feature vector, in the hope, that one space compensates errors of the other.

Mat feature(const Vec3b &pixel) {
    // normalized bgr;
    float b = float(pixel[0]) / 255;
    float g = float(pixel[1]) / 255;
    float r = float(pixel[2]) / 255;

    // ycrcb
    float y  = 0.299f * r + 0.587f * g + 0.114f * b;
    float cr = 0.713f * (r - y) + 0.5f;
    float cb = 0.564f * (b - y) + 0.5f;

    // hsv
    float M(max(max(b,g),r));
    float m(min(min(b,g),r));
    float md = M - m;
    float A = 1.0f / 6;
    float v =  M;
    float s = (M>0)   ? (md/M) : 0;
    float h = (md==0) ? 0 :
              (M==r)  ? (    A*(g-b)/md) :
              (M==g)  ? (2*A+A*(b-r)/md) :
                        (3*A+A*(r-g)/md);

    return Mat_<float>(1,9) << b,g,r, y,cr,cb, h,s,v; // 9x1
}

trying with skin/noskin data, and a linear svm:

// train data:
7990 positive, 19000 negative probes, [9 x 26990] feature elems.
// test data:
1000 positive, 1000 negative probes, [9 x 2000] query elems.
// confusion
[949, 0;
 51, 1000]
1949/2000 : correct, 0.9745 accuracy.

since any color space on its own has some problems (bgr with intensity, hsv with "non-colors" like black/white/silver), i'd suggest adding stacking up several colorspaces into a feature vector, in the hope, that one space compensates errors of the other.

Mat feature(const Vec3b &pixel) {
    // normalized bgr;
    float b = float(pixel[0]) / 255;
    float g = float(pixel[1]) / 255;
    float r = float(pixel[2]) / 255;

    // ycrcb
    float y  = 0.299f * r + 0.587f * g + 0.114f * b;
    float cr = 0.713f * (r - y) + 0.5f;
    float cb = 0.564f * (b - y) + 0.5f;

    // hsv
    float M(max(max(b,g),r));
    float m(min(min(b,g),r));
    float md = M - m;
    float A = 1.0f / 6;
    float v =  M;
    float s = (M>0)   ? (md/M) : 0;
    float h = (md==0) ? 0 :
              (M==r)  ? (    A*(g-b)/md) :
              (M==g)  ? (2*A+A*(b-r)/md) :
                        (3*A+A*(r-g)/md);

    return Mat_<float>(1,9) << b,g,r, y,cr,cb, h,s,v; // 9x1
}

trying with skin/noskin data, and a linear svm:

// train data:
7990 positive, 19000 negative probes, [9 x 26990] feature elems.
// test data:
1000 positive, 1000 negative probes, [9 x 2000] query elems.
// confusion
[949, 0;
 51, 1000]
1949/2000 : correct, 0.9745 accuracy.