我正在研究从VR标头投射的图像上的桶形失真校正,我在这里使用的算法来自mipav(https://mipav.cit.nih.gov/pubwiki/index.php/Barrel_Distortion_Correction),它们很好地包装了数据,您可以获得很好的效果来自他们的应用程序和ImageMagick的结果。 我从VR标头获得的原始图像就是这样。 projection original images
,带有某些参数的mipav应用程序和ImageMagick的结果类似于以下内容。 results of ImageMagic
但是,我从mipav应用程序获得的算法部分得到了这样的结果。 my result
如您所见,结果是在某种情况下看起来正确无误,但其颜色或图像格式有些奇怪,有人可以帮我找出原因吗???非常感谢!
以下是我的代码。
public class Main2 {
public BufferedImage readFileAsImage(String fileName) {
BufferedImage bufferedImage = null;
File imageFile = new File(fileName);
try {
bufferedImage = ImageIO.read(imageFile);
} catch (IOException e) {
e.printStackTrace();
}
return bufferedImage;
}
public Image convertBufferedImageToImage(BufferedImage bufferedImage) {
BufferedImage tempCard = bufferedImage.getSubimage( 0,bufferedImage.getWidth(),bufferedImage.getHeight());
Image card = SwingFXUtils.toFXImage(tempCard,null );
return card;
}
public int[] exportData(BufferedImage bufferedImage,int[] values,int start,int length) {
if ( (start >= 0) && (length <= values.length)) {
values = bufferedImage.getRGB(0,bufferedImage.getHeight(),values,bufferedImage.getWidth());
}
return values;
}
public BufferedImage importData(BufferedImage bufferedImage,int[] values) {
bufferedImage.setRGB(0,bufferedImage.getWidth());
return bufferedImage;
}
public void saveBufferedImageAsFile(String fName,BufferedImage bufferedImage) {
File outputfile = new File(fName);
try {
ImageIO.write(bufferedImage,"jpg",outputfile);
} catch (IOException e) {
e.printStackTrace();
}
}
public void runAlgorithmn(Image srcImage,BufferedImage srcBufferedImage) {
int xDim;
int yDim;
int sliceSize;
int i,j;
int index,index1;
double ang;
int[] srcBuffer;
int[] destBuffer;
double ySrc;
double xSrc;
int imageMin;
int xBase;
float delX;
int yBase;
float delY;
int sIndex;
int cf;
double xcen;
double ycen;
double xoff;
double yoff;
double rdest;
double rdest2;
double rdest3;
double rdest4;
double rsrc;
double normDist;
cf = 1;
xDim = (int) srcImage.getWidth();
yDim = (int) srcImage.getHeight();
sliceSize = xDim * yDim;
BufferedImage destBufferedImage = new BufferedImage(xDim,yDim,BufferedImage.TYPE_USHORT_555_RGB);
xcen = (xDim - 1.0)/2.0;
ycen = (yDim - 1.0)/2.0;
normDist = Math.min(xcen,ycen);
srcBuffer = new int[cf * sliceSize];
srcBuffer = exportData(srcBufferedImage,srcBuffer,cf * sliceSize);
destBuffer = new int[cf * sliceSize];
// imageMin = Math.min(srcBufferedImage.getMinX(),srcBufferedImage.getMinY());
// for (i = 0; i < sliceSize; i++) {
// destBuffer[i] = imageMin;
// }
double a = 0.08;
double b = -0.28;
double c = 0.0;
double d = 1 - a - b - c;
for (j = 0; j < yDim; j++) {
index1 = j * xDim;
yoff = (j - ycen)/normDist;
for (i = 0; i < xDim; i++) {
xoff = (i - xcen)/normDist;
rdest2 = xoff*xoff + yoff*yoff;
rdest = Math.sqrt(rdest2);
rdest3 = rdest2 * rdest;
rdest4 = rdest2 * rdest2;
rsrc = a * rdest4 + b * rdest3 + c * rdest2 + d * rdest;
rsrc = normDist * rsrc;
ang = Math.atan2(yoff,xoff);
xSrc = xcen + (rsrc * Math.cos(ang));
ySrc = ycen + (rsrc * Math.sin(ang));
// Use bilinear interpolation to find the contributions from the
// 4 nearest neighbors in the original space
if ((xSrc >= 0.0) && ((xSrc) <= (xDim - 1)) && (ySrc >= 0.0) && (ySrc <= (yDim - 1))) {
xBase = (int) Math.floor(xSrc);
delX = (float) (xSrc - xBase);
yBase = (int) Math.floor(ySrc);
delY = (float) (ySrc - yBase);
index = index1 + i;
sIndex = (yBase * xDim) + xBase;
destBuffer[index] = (int) ((1 - delX) * (1 - delY) * srcBuffer[sIndex]);
if (xSrc < (xDim - 1)) {
destBuffer[index] += (int) (delX * (1 - delY) * srcBuffer[sIndex + 1]);
}
if (ySrc < (yDim - 1)) {
destBuffer[index] += (int) ((1 - delX) * delY * srcBuffer[sIndex + xDim]);
}
if ((xSrc < (xDim - 1)) && (ySrc < (yDim - 1))) {
destBuffer[index] += (int) (delX * delY * srcBuffer[sIndex + xDim + 1]);
}
}
}
}
importData(destBufferedImage,destBuffer);
saveBufferedImageAsFile("/Users/pengyuyan/Desktop/singleFrame/images/mytest_result_images/barrel4_result.png",destBufferedImage);
}
public static void main(String[] args) {
Main2 main2 = new Main2();
BufferedImage srcBufferedImage = main2.readFileAsImage("/Users/pengyuyan/Desktop/singleFrame/images/singleImages/4.png");
Image srcImage = main2.convertBufferedImageToImage(srcBufferedImage);
main2.runAlgorithmn(srcImage,srcBufferedImage);
}
}