public void Calc_5Fr(ImagePlus imp1, ImagePlus imp2) { if (imp1.getType() != imp2.getType()) { error(); return; } if (imp1.getType() == 0) { // getType returns 0 for 8-bit, 1 for 16-bit bitDepth = "8-bit"; Prefs.set("ps.bitDepth", bitDepth); } else { bitDepth = "16-bit"; Prefs.set("ps.bitDepth", bitDepth); } int width = imp1.getWidth(); int height = imp1.getHeight(); if (width != imp2.getWidth() || height != imp2.getHeight()) { error(); return; } ImageStack stack1 = imp1.getStack(); // if (bgStackTitle != "NoBg") ImageStack stack2 = imp2.getStack(); ImageStack stack2 = imp2.getStack(); ImageProcessor ip = imp1.getProcessor(); int dimension = width * height; byte[] pixB; short[] pixS; float[][] pixF = new float[5][dimension]; float[][] pixFBg = new float[5][dimension]; float a; float b; float den; float aSmp; float bSmp; float denSmp; float aBg; float bBg; float denBg; float retF; float azimF; byte[] retB = new byte[dimension]; short[] retS = new short[dimension]; byte[] azimB = new byte[dimension]; short[] azimS = new short[dimension]; // Derived Variables: float swingAngle = 2f * (float) Math.PI * swing; float tanSwingAngleDiv2 = (float) Math.tan(swingAngle / 2.f); float tanSwingAngleDiv2DivSqrt2 = (float) (Math.tan(swingAngle / 2.f) / Math.sqrt(2)); float wavelengthDiv2Pi = wavelength / (2f * (float) Math.PI); // get the pixels of each slice in the stack and convert to float for (int i = 0; i < 5; i++) { if (bitDepth == "8-bit") { pixB = (byte[]) stack1.getPixels(i + 3); for (int j = 0; j < dimension; j++) pixF[i][j] = 0xff & pixB[j]; if (bgStackTitle != "NoBg") { pixB = (byte[]) stack2.getPixels(i + 3); for (int j = 0; j < dimension; j++) pixFBg[i][j] = 0xff & pixB[j]; } } else { pixS = (short[]) stack1.getPixels(i + 3); for (int j = 0; j < dimension; j++) pixF[i][j] = (float) pixS[j]; if (bgStackTitle != "NoBg") { pixS = (short[]) stack2.getPixels(i + 3); for (int j = 0; j < dimension; j++) pixFBg[i][j] = (float) pixS[j]; } } } // Algorithm // terms a and b for (int j = 0; j < dimension; j++) { denSmp = (pixF[1][j] + pixF[2][j] + pixF[3][j] + pixF[4][j] - 4 * pixF[0][j]) / 2; denBg = denSmp; a = (pixF[4][j] - pixF[1][j]); aSmp = a; aBg = a; b = (pixF[2][j] - pixF[3][j]); bSmp = b; bBg = b; if (bgStackTitle != "NoBg") { denBg = (pixFBg[1][j] + pixFBg[2][j] + pixFBg[3][j] + pixFBg[4][j] - 4 * pixFBg[0][j]) / 2; aBg = pixFBg[4][j] - pixFBg[1][j]; bBg = pixFBg[2][j] - pixFBg[3][j]; } // Special case of sample retardance half wave, denSmp = 0 if (denSmp == 0) { retF = (float) wavelength / 4; azimF = (float) (a == 0 & b == 0 ? 0 : (azimRef + 90 + 90 * Math.atan2(a, b) / Math.PI) % 180); } else { // Retardance, the background correction can be improved by separately considering sample // retardance values larger than a quarter wave if (bgStackTitle != "NoBg") { a = aSmp / denSmp - aBg / denBg; b = bSmp / denSmp - bBg / denBg; } else { a = aSmp / denSmp; b = bSmp / denSmp; } retF = (float) Math.atan(tanSwingAngleDiv2 * Math.sqrt(a * a + b * b)); if (denSmp < 0) retF = (float) Math.PI - retF; retF = retF * wavelengthDiv2Pi; // convert to nm if (retF > retCeiling) retF = retCeiling; // Orientation if ((bgStackTitle == "NoBg") || ((bgStackTitle != "NoBg") && (Math.abs(denSmp) < 1))) { a = aSmp; b = bSmp; } azimF = (float) (a == 0 & b == 0 ? 0 : (azimRef + 90 + 90 * Math.atan2(a, b) / Math.PI) % 180); } if (bitDepth == "8-bit") retB[j] = (byte) (((int) (255 * retF / retCeiling)) & 0xff); else retS[j] = (short) (4095 * retF / retCeiling); if (mirror == "Yes") azimF = 180 - azimF; if (bitDepth == "8-bit") azimB[j] = (byte) (((int) azimF) & 0xff); else azimS[j] = (short) (azimF * 10f); } // show the resulting images in slice 1 and 2 imp1.setSlice(3); if (bitDepth == "8-bit") { stack1.setPixels(retB, 1); stack1.setPixels(azimB, 2); } else { stack1.setPixels(retS, 1); stack1.setPixels(azimS, 2); } imp1.setSlice(1); IJ.selectWindow(imp1.getTitle()); Prefs.set("ps.sampleStackTitle", sampleStackTitle); Prefs.set("ps.bgStackTitle", bgStackTitle); Prefs.set("ps.mirror", mirror); Prefs.set("ps.wavelength", wavelength); Prefs.set("ps.swing", swing); Prefs.set("ps.retCeiling", retCeiling); Prefs.set("ps.azimRef", azimRef); Prefs.savePreferences(); }
/*------------------------------------------------------------------*/ void doIt(ImageProcessor ip) { int width = ip.getWidth(); int height = ip.getHeight(); double hLine[] = new double[width]; double vLine[] = new double[height]; if (!(ip.getPixels() instanceof float[])) { throw new IllegalArgumentException("Float image required"); } switch (operation) { case GRADIENT_MAGNITUDE: { ImageProcessor h = ip.duplicate(); ImageProcessor v = ip.duplicate(); float[] floatPixels = (float[]) ip.getPixels(); float[] floatPixelsH = (float[]) h.getPixels(); float[] floatPixelsV = (float[]) v.getPixels(); getHorizontalGradient(h, FLT_EPSILON); getVerticalGradient(v, FLT_EPSILON); for (int y = 0, k = 0; (y < height); y++) { for (int x = 0; (x < width); x++, k++) { floatPixels[k] = (float) Math.sqrt( floatPixelsH[k] * floatPixelsH[k] + floatPixelsV[k] * floatPixelsV[k]); } stepProgressBar(); } } break; case GRADIENT_DIRECTION: { ImageProcessor h = ip.duplicate(); ImageProcessor v = ip.duplicate(); float[] floatPixels = (float[]) ip.getPixels(); float[] floatPixelsH = (float[]) h.getPixels(); float[] floatPixelsV = (float[]) v.getPixels(); getHorizontalGradient(h, FLT_EPSILON); getVerticalGradient(v, FLT_EPSILON); for (int y = 0, k = 0; (y < height); y++) { for (int x = 0; (x < width); x++, k++) { floatPixels[k] = (float) Math.atan2(floatPixelsH[k], floatPixelsV[k]); } stepProgressBar(); } } break; case LAPLACIAN: { ImageProcessor hh = ip.duplicate(); ImageProcessor vv = ip.duplicate(); float[] floatPixels = (float[]) ip.getPixels(); float[] floatPixelsHH = (float[]) hh.getPixels(); float[] floatPixelsVV = (float[]) vv.getPixels(); getHorizontalHessian(hh, FLT_EPSILON); getVerticalHessian(vv, FLT_EPSILON); for (int y = 0, k = 0; (y < height); y++) { for (int x = 0; (x < width); x++, k++) { floatPixels[k] = (float) (floatPixelsHH[k] + floatPixelsVV[k]); } stepProgressBar(); } } break; case LARGEST_HESSIAN: { ImageProcessor hh = ip.duplicate(); ImageProcessor vv = ip.duplicate(); ImageProcessor hv = ip.duplicate(); float[] floatPixels = (float[]) ip.getPixels(); float[] floatPixelsHH = (float[]) hh.getPixels(); float[] floatPixelsVV = (float[]) vv.getPixels(); float[] floatPixelsHV = (float[]) hv.getPixels(); getHorizontalHessian(hh, FLT_EPSILON); getVerticalHessian(vv, FLT_EPSILON); getCrossHessian(hv, FLT_EPSILON); for (int y = 0, k = 0; (y < height); y++) { for (int x = 0; (x < width); x++, k++) { floatPixels[k] = (float) (0.5 * (floatPixelsHH[k] + floatPixelsVV[k] + Math.sqrt( 4.0 * floatPixelsHV[k] * floatPixelsHV[k] + (floatPixelsHH[k] - floatPixelsVV[k]) * (floatPixelsHH[k] - floatPixelsVV[k])))); } stepProgressBar(); } } break; case SMALLEST_HESSIAN: { ImageProcessor hh = ip.duplicate(); ImageProcessor vv = ip.duplicate(); ImageProcessor hv = ip.duplicate(); float[] floatPixels = (float[]) ip.getPixels(); float[] floatPixelsHH = (float[]) hh.getPixels(); float[] floatPixelsVV = (float[]) vv.getPixels(); float[] floatPixelsHV = (float[]) hv.getPixels(); getHorizontalHessian(hh, FLT_EPSILON); getVerticalHessian(vv, FLT_EPSILON); getCrossHessian(hv, FLT_EPSILON); for (int y = 0, k = 0; (y < height); y++) { for (int x = 0; (x < width); x++, k++) { floatPixels[k] = (float) (0.5 * (floatPixelsHH[k] + floatPixelsVV[k] - Math.sqrt( 4.0 * floatPixelsHV[k] * floatPixelsHV[k] + (floatPixelsHH[k] - floatPixelsVV[k]) * (floatPixelsHH[k] - floatPixelsVV[k])))); } stepProgressBar(); } } break; case HESSIAN_ORIENTATION: { ImageProcessor hh = ip.duplicate(); ImageProcessor vv = ip.duplicate(); ImageProcessor hv = ip.duplicate(); float[] floatPixels = (float[]) ip.getPixels(); float[] floatPixelsHH = (float[]) hh.getPixels(); float[] floatPixelsVV = (float[]) vv.getPixels(); float[] floatPixelsHV = (float[]) hv.getPixels(); getHorizontalHessian(hh, FLT_EPSILON); getVerticalHessian(vv, FLT_EPSILON); getCrossHessian(hv, FLT_EPSILON); for (int y = 0, k = 0; (y < height); y++) { for (int x = 0; (x < width); x++, k++) { if (floatPixelsHV[k] < 0.0) { floatPixels[k] = (float) (-0.5 * Math.acos( (floatPixelsHH[k] - floatPixelsVV[k]) / Math.sqrt( 4.0 * floatPixelsHV[k] * floatPixelsHV[k] + (floatPixelsHH[k] - floatPixelsVV[k]) * (floatPixelsHH[k] - floatPixelsVV[k])))); } else { floatPixels[k] = (float) (0.5 * Math.acos( (floatPixelsHH[k] - floatPixelsVV[k]) / Math.sqrt( 4.0 * floatPixelsHV[k] * floatPixelsHV[k] + (floatPixelsHH[k] - floatPixelsVV[k]) * (floatPixelsHH[k] - floatPixelsVV[k])))); } } stepProgressBar(); } } break; default: throw new IllegalArgumentException("Invalid operation"); } ip.resetMinAndMax(); imp.updateAndDraw(); } /* end doIt */