void LABtoRGBimage(const ImageLab & src, kn::Image<unsigned char> & dest) { MatrixXd coeff(3,3); coeff << 3.0628971, -1.3931791, -0.4757517, -0.9692660, 1.8760108, 0.0415560, 0.0678775, -0.2288548, 1.0693490; for(unsigned j(0); j<src.height(); ++j) { for(unsigned i(0); i<src.width(); ++i) { Vector3d lab; lab << src(i,j)[0], src(i,j)[1], src(i,j)[2]; Vector3d xyz; LABtoXYZ(lab, xyz); Vector3d rgb; rgb = coeff*xyz; rgb *= 255.; dest(i,j)[0] = rgb[0]; dest(i,j)[1] = rgb[1]; dest(i,j)[2] = rgb[2]; } } }
void LABtoRGB(const double lab[], unsigned char rgb[]) { MatrixXd coeff(3,3); coeff << 3.0628971, -1.3931791, -0.4757517, -0.9692660, 1.8760108, 0.0415560, 0.0678775, -0.2288548, 1.0693490; Vector3d _lab; _lab << lab[0], lab[1], lab[2]; Vector3d xyz; LABtoXYZ(_lab, xyz); Vector3d _rgb; _rgb = coeff*xyz; _rgb *= 255.; rgb[0] = _rgb[0]; rgb[1] = _rgb[1]; rgb[2] = _rgb[2]; }
JNIEXPORT void JNICALL Java_jp_dego_sample_ipcv_MainActivity_checkColorSpace(JNIEnv *env, jobject obj, jobject bmp) { AndroidBitmapInfo info; void* pixels; // Bitmapの情報を取得 if (AndroidBitmap_getInfo(env, bmp, &info) < 0) return; // Bitmapのフォーマットをチェック if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) return; // Bitmapをロック if (AndroidBitmap_lockPixels(env, bmp, &pixels) < 0) return; int i, j; jint *p = pixels; for (j = 0; j < info.height; j++) { for (i = 0; i < info.width; i++) { ARGB argb = {0, 0, 0, 0}; argb.red = getR(p[j * info.width + i]); argb.green = getG(p[j * info.width + i]); argb.blue = getB(p[j * info.width + i]); XYZ xyz; // LUV luv; // RGBtoXYZ(&argb, &xyz); // XYZtoLUV(&xyz, &luv); // LUVtoXYZ(&luv, &xyz); // XYZtoRGB(&xyz, &argb); LAB lab; RGBtoXYZ(&argb, &xyz); XYZtoLAB(&xyz, &lab); LABtoXYZ(&lab, &xyz); XYZtoRGB(&xyz, &argb); p[j * info.width + i] = createColorFromARGB(argb); } } }
//----------------------------------------------------------------------------- // LCH(ab) to RGB void LCHABtoRGB(float L, float C, float H, float* RGB) { LCHtoLAB(L,C,H,RGB); LABtoXYZ(RGB[0],RGB[1],RGB[2],RGB); XYZtoRGB(RGB[0],RGB[1],RGB[2],RGB); }
//----------------------------------------------------------------------------- void LABtoRGB(float L, float A, float B, float* RGB) { LABtoXYZ(L,A,B,RGB); XYZtoRGB(RGB[0],RGB[1],RGB[2],RGB); }
void convert(unsigned char *buf, int width, int height, int de) { double angle_chroma[360]; double angle_hue[360]; double angle_hue2[360]; double minchroma = 999; double maxchroma = 0; { int i; for (i = 0; i < 360; i++) { angle_chroma[i] = 9999; } double f; for (f = 0; f < 360; f += .25) { angle_hue[(int) ((angletohue(f) - angletohue(0)) / (angletohue(360) - angletohue(0)) * 360)] = f; angle_hue2[(int) f] = ((angletohue(f) - angletohue(0)) / (angletohue(360) - angletohue(0)) * 360); } double a; for (a = -80; a <= 80; a += .1) { int dir; for (dir = -1; dir <= 1; dir += 2) { double b = dir * 335.582 * exp(- a * a / (2 * 15.5723 * 15.5723)) / (15.5723 * sqrt(2 * M_PI)); double h = atan2(b, a); double c = sqrt(a * a + b * b); h -= 0.075; if (h < 0) { h += 2 * M_PI; } h = floor(h * 180 / M_PI); if (c < angle_chroma[(int) h]) { angle_chroma[(int) h] = c; } } } for (i = 0; i < 360; i++) { if (angle_chroma[i] < minchroma) { minchroma = angle_chroma[i]; } if (angle_chroma[i] > maxchroma) { maxchroma = angle_chroma[i]; } } } int *buf2 = malloc(width * height * 4 * sizeof(int)); int x, y; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { int r = buf[(y * width + x) * 4 + 0]; int g = buf[(y * width + x) * 4 + 1]; int b = buf[(y * width + x) * 4 + 2]; double X, Y, Z; double L, A, B; double C, H; RGBtoXYZ(r, g, b, &X, &Y, &Z); XYZtoLAB(X, Y, Z, &L, &A, &B); LABtoLCH(L, A, B, &L, &C, &H); if (H < 0) { H += 2 * M_PI; } if (de) { // desaturate C = C * minchroma / angle_chroma[(int) (H * 180 / M_PI)]; // shift hue int hh = (int) (H * 180 / M_PI + 720) % 360; H = angle_hue2[hh] * M_PI / 180; } else { // shift hue int hh = (int) (H * 180 / M_PI + 720) % 360; H = angle_hue[hh] * M_PI / 180; // resaturate C = C / minchroma * angle_chroma[(int) (H * 180 / M_PI)]; C *= minchroma / maxchroma; } LCHtoLAB(L, C, H, &L, &A, &B); LABtoXYZ(L, A, B, &X, &Y, &Z); XYZtoRGB(X, Y, Z, &r, &g, &b); buf2[(y * width + x) * 4 + 0] = r; buf2[(y * width + x) * 4 + 1] = g; buf2[(y * width + x) * 4 + 2] = b; } } int max = 0; for (x = 0; x < width * height; x++) { int i; for (i = 0; i < 3; i++) { if (buf2[x * 4 + i] > max) { max = buf2[x * 4 + i]; } } } for (x = 0; x < width * height; x++) { int i; for (i = 0; i < 3; i++) { buf[x * 4 + i] = buf2[x * 4 + i] * 255 / max; if (buf2[x * 4 + i] < 0) { buf[x * 4 + i] = 0; } } } }