我正在为2幅图像编码直方图匹配。我找不到我的2反cdf之间的匹配。 以下是我的代码段。我仅计算RGB空间的直方图。 HistogrammeRGB分别计算每个通道的直方图。 HistogrammeCumuleRGB计算每个通道的cdf。 InverseHistogrammeRGB计算每个通道的inverse-cdf。我使用哈希表来存储它。
public static void HistogrammeRGB(Mat m,float[] R,float[] G,float[] B)
{
byte[] col=new byte[3];
for(int i=0;i<m.rows();i++)
{
for(int j=0;j<m.cols();j++)
{
m.get(i, j,col);
R[byteColorCVtoIntJava(col[2])]+=1;
G[byteColorCVtoIntJava(col[1])]+=1;
B[byteColorCVtoIntJava(col[0])]+=1;
}
}
int N=m.rows()*m.cols();
for(int i=0;i<256;i++)
{
R[i]/=N;
G[i]/=N;
B[i]/=N;
}
}
public static void HistogrammeCumuleRGB(Mat m,float[] R,float[] G,float[] B,float[] RC,float[] GC,float[] BC,float N)
{
float valueR=0;float valueG=0;float valueB=0;
for(int i=0;i<256;i++)
{
valueR+=R[i];RC[i]=R[i]==0?0:valueR;
valueG+=G[i];GC[i]=G[i]==0?0:valueG;
valueB+=B[i];BC[i]=B[i]==0?0:valueB;
}
}
public static void InverseHistogrammeRGB(float[] RC,float[] GC,float[] BC,Hashtable<Float, Integer> InvHistoCumulR,Hashtable<Float, Integer> InvHistoCumulG,Hashtable<Float, Integer> InvHistoCumulB )
{
for(int i=0;i<256;i++)
{
InvHistoCumulR.put(RC[i], i);
InvHistoCumulG.put(GC[i], i);
InvHistoCumulB.put(BC[i], i);
}
}
public static void MatchingHistogram(Mat imRef,Mat imTarget,Mat result)
{
float[] RRef=new float[256];float[] RCRef=new float[256];Hashtable<Float, Integer> InvHistoCumulRRef=new Hashtable<>();
float[] GRef=new float[256];float[] GCRef=new float[256];Hashtable<Float, Integer> InvHistoCumulGRef=new Hashtable<>();
float[] BRef=new float[256];float[] BCRef=new float[256];Hashtable<Float, Integer> InvHistoCumulBRef=new Hashtable<>();
float[] RTar=new float[256];float[] RCTar=new float[256];Hashtable<Float, Integer> InvHistoCumulRTar=new Hashtable<>();
float[] GTar=new float[256];float[] GCTar=new float[256];Hashtable<Float, Integer> InvHistoCumulGTar=new Hashtable<>();
float[] BTar=new float[256];float[] BCTar=new float[256];Hashtable<Float, Integer> InvHistoCumulBTar=new Hashtable<>();
int N=imRef.cols()*imRef.rows();
HistogrammeRGB(imRef, RRef, GRef, BRef);
HistogrammeCumuleRGB(imRef, RRef, GRef, BRef,RCRef,GCRef,BCRef,N);
InverseHistogrammeRGB(RCRef, GCRef, BCRef, InvHistoCumulRRef, InvHistoCumulGRef, InvHistoCumulBRef);
HistogrammeRGB(imTarget, RTar, GTar, BTar);
HistogrammeCumuleRGB(imTarget, RTar, GTar, BTar,RCTar,GCTar,BCTar,N);
InverseHistogrammeRGB(RCTar, GCTar, BCTar, InvHistoCumulRTar, InvHistoCumulGTar, InvHistoCumulBTar);
byte[] pixel=new byte[3];
byte[] pixelTarget=new byte[3];
//
for(int i=0;i<imRef.rows();i++)
{
for(int j=0;j<imRef.cols();j++)
{
imRef.get(i, j,pixel);
imTarget.get(i, j,pixelTarget);
byte blue=pixel[0];byte green=pixel[1];byte red=pixel[2];
/*int r=InvHistoCumulRTar.get(RCRef[byteColorCVtoIntJava(red)])==null?byteColorCVtoIntJava(pixelTarget[2]):InvHistoCumulRTar.get(RCRef[byteColorCVtoIntJava(red)]);
int g=InvHistoCumulGTar.get(GCRef[byteColorCVtoIntJava(green)])==null?byteColorCVtoIntJava(pixelTarget[1]):InvHistoCumulGTar.get(GCRef[byteColorCVtoIntJava(green)]);
int b=InvHistoCumulBTar.get(BCRef[byteColorCVtoIntJava(blue)])==null?byteColorCVtoIntJava(pixelTarget[0]):InvHistoCumulBTar.get(BCRef[byteColorCVtoIntJava(blue)]);*/
float r=InvHistoCumulRTar.get(RCRef[byteColorCVtoIntJava(red)])==null?byteColorCVtoIntJava(pixel[2])*byteColorCVtoIntJava(pixelTarget[2])/255:InvHistoCumulRTar.get(RCRef[byteColorCVtoIntJava(red)]);
float g=InvHistoCumulGTar.get(GCRef[byteColorCVtoIntJava(green)])==null?byteColorCVtoIntJava(pixel[1])*byteColorCVtoIntJava(pixelTarget[1])/255:InvHistoCumulGTar.get(GCRef[byteColorCVtoIntJava(green)]);
float b=InvHistoCumulBTar.get(BCRef[byteColorCVtoIntJava(blue)])==null?byteColorCVtoIntJava(pixel[0])*byteColorCVtoIntJava(pixelTarget[0])/255:InvHistoCumulBTar.get(BCRef[byteColorCVtoIntJava(blue)]);
System.out.println(InvHistoCumulRTar.get(RCRef[byteColorCVtoIntJava(red)])+" - "+InvHistoCumulGTar.get(GCRef[byteColorCVtoIntJava(green)])+" - "+InvHistoCumulBTar.get(BCRef[byteColorCVtoIntJava(blue)]));
pixel[0]=(byte)b;
pixel[1]=(byte)g;
pixel[2]=(byte)r;
result.put(i, j, new double[]{b,g,r});
}
}
}
public static int byteColorCVtoIntJava(byte b)
{
int i=(b+128)+128;
return b>=0?(int)b:i;
}