は私がrsbwebから別のコードを試してみました(私はすでにクラスタリングステップを実装しました)...と効果はOpenCVのよりもはるかに優れています!
は、ここで私はより良い結果を得るためにではなくYIQよりマブラヴを使用して、コードの一部を変更し、私の新しい結果
です。ここで
easyrgbが私のコードであるから、色の方程式は、
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class test {
public static void main(String[] args) throws IOException {
BufferedImage img = ImageIO.read(new File("2.png"));
filterRGBImage(img);
ImageIO.write(img, "png", new File("3.png"));
}
private static int rad = 10, rad2=rad*rad;
private static double radCol2 = Math.pow(10,2);
private static void RGB2XYZ(double rgb[], double xyz[])
{
double var_R = (rgb[0]/255.),var_G = (rgb[1]/255.),var_B = (rgb[2]/255.);
if (var_R > 0.04045)
var_R = Math.pow(((var_R + 0.055)/1.055),2.4);
else
var_R = var_R/12.92;
if (var_G > 0.04045)
var_G = Math.pow((var_G + 0.055)/1.055 , 2.4);
else
var_G = var_G/12.92;
if (var_B > 0.04045)
var_B = Math.pow((var_B + 0.055)/1.055 ,2.4);
else
var_B = var_B/12.92;
var_R = var_R * 100;
var_G = var_G * 100;
var_B = var_B * 100;
xyz[0] = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805;
xyz[1] = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722;
xyz[2] = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505;
}
private static void XYZ2RGB(double xyz[], double rgb[])
{
double var_X = xyz[0]/100, var_Y = xyz[1]/100 , var_Z = xyz[2]/100;
double var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986,
var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415,
var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570;
if (var_R > 0.0031308)
var_R = 1.055 * Math.pow(var_R, 1/2.4 ) - 0.055;
else
var_R = 12.92 * var_R;
if (var_G > 0.0031308)
var_G = 1.055 * Math.pow(var_G , 1/2.4) - 0.055;
else
var_G = 12.92 * var_G;
if (var_B > 0.0031308)
var_B = 1.055 * Math.pow(var_B ,1/2.4) - 0.055;
else
var_B = 12.92 * var_B;
rgb[0] = var_R * 255;
rgb[1] = var_G * 255;
rgb[2] = var_B * 255 ;
}
private static void XYZ2Luv(double xyz[], double luv[])
{
double var_U = (4 * xyz[0])/(xyz[0] + (15 * xyz[1]) + (3 * xyz[2])),
var_V = (9 * xyz[1])/(xyz[0] + (15 * xyz[1]) + (3 * xyz[2])),
var_Y = xyz[1]/100;
if (var_Y > 0.008856)
var_Y = Math.pow(var_Y, 1./3);
else
var_Y = (7.787 * var_Y) + (16./116);
double ref_X = 95.047, ref_Y = 100.000, ref_Z = 108.883;
double ref_U = (4 * ref_X)/(ref_X + (15 * ref_Y) + (3 * ref_Z)),
ref_V = (9 * ref_Y)/(ref_X + (15 * ref_Y) + (3 * ref_Z));
luv[0] = (116 * var_Y) - 16;
luv[1] = 13 * luv[0] * (var_U - ref_U);
luv[2] = 13 * luv[0] * (var_V - ref_V);
}
private static void Luv2XYZ(double luv[],double xyz[])
{
double var_Y = (luv[0] + 16)/116;
if (Math.pow(var_Y,3) > 0.008856)
var_Y = Math.pow(var_Y,3);
else
var_Y = (var_Y - 16./ 116)/7.787;
double ref_X = 95.047 ,ref_Y = 100.000,ref_Z = 108.883;
double ref_U = (4 * ref_X)/(ref_X + (15 * ref_Y) + (3 * ref_Z)),
ref_V = (9 * ref_Y)/(ref_X + (15 * ref_Y) + (3 * ref_Z));
double var_U = luv[1]/(13 * luv[0]) + ref_U,
var_V =luv[2]/(13 * luv[0]) + ref_V;
xyz[1] = var_Y * 100;
xyz[0] = - (9 * xyz[1] * var_U)/((var_U - 4) * var_V - var_U * var_V);
xyz[2] = (9 * xyz[1] - (15 * var_V * xyz[1]) - (var_V * xyz[0]))/(3 * var_V);
}
//http://rsbweb.nih.gov/ij/plugins/download/Mean_Shift.java
public static void filterRGBImage(BufferedImage ip) {
int width = ip.getWidth();
int height = ip.getHeight();
double[][][] pixelsf = new double[width][height][3];
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
int argb = ip.getRGB(x,y);
int r = (argb >> 16) & 0xff;
int g = (argb >> 8) & 0xff;
int b = (argb) & 0xff;
// YIQ
/*pixelsf[x][y][0] = 0.299f *r + 0.587f *g + 0.114f *b;
pixelsf[x][y][1] = 0.5957f *r - 0.2744f*g - 0.3212f *b;
pixelsf[x][y][2] = 0.2114f *r - 0.5226f*g + 0.3111f *b;*/
double tmp[]={r,g,b},tmp2[]={0,0,0};
RGB2XYZ(tmp,tmp2);
XYZ2Luv(tmp2,pixelsf[x][y]);
}
}
double shift = 0;
int iters = 0;
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
int xc = x;
int yc = y;
int xcOld, ycOld;
double YcOld, IcOld, QcOld;
double Yc = pixelsf[x][y][0];
double Ic = pixelsf[x][y][1];
double Qc = pixelsf[x][y][2];
iters = 0;
do {
xcOld = xc;
ycOld = yc;
YcOld = Yc;
IcOld = Ic;
QcOld = Qc;
float mx = 0;
float my = 0;
float mY = 0;
float mI = 0;
float mQ = 0;
int num=0;
for (int ry=-rad; ry <= rad; ry++) {
int y2 = yc + ry;
if (y2 >= 0 && y2 < height) {
for (int rx=-rad; rx <= rad; rx++) {
int x2 = xc + rx;
if (x2 >= 0 && x2 < width) {
//if (ry*ry + rx*rx <= rad2) {
double Y2 = pixelsf[x2][y2][0];
double I2 = pixelsf[x2][y2][1];
double Q2 = pixelsf[x2][y2][2];
double dY = Yc - Y2;
double dI = Ic - I2;
double dQ = Qc - Q2;
if (dY*dY+dI*dI+dQ*dQ <= radCol2) {
mx += x2;
my += y2;
mY += Y2;
mI += I2;
mQ += Q2;
num++;
}
//}
}
}
}
}
double num_ = 1./num;
Yc = mY*num_;
Ic = mI*num_;
Qc = mQ*num_;
xc = (int) (mx*num_+0.5);
yc = (int) (my*num_+0.5);
int dx = xc-xcOld;
int dy = yc-ycOld;
double dY = Yc-YcOld;
double dI = Ic-IcOld;
double dQ = Qc-QcOld;
shift = dx*dx+dy*dy+dY*dY+dI*dI+dQ*dQ;
iters++;
}
while (shift > 3 && iters < 100);
double tmp[]={Yc,Ic,Qc},tmp2[]={0,0,0};
Luv2XYZ(tmp,tmp2);
XYZ2RGB(tmp2,tmp);
int r_ = (int) tmp[0];
int g_ = (int) tmp[1];
int b_ = (int) tmp[2];
ip.setRGB(x, y, (0xFF<<24)|(r_<<16)|(g_<<8)|b_);
}
}
}
}