50 #include "ImgControl.h" 66 #define IMAGE_VAL(x,y,c,w,n,mem) (mem[x*n + y*w*n + c]) 67 vec3
image_sample(
float xx,
float yy,
int c,
size_t w,
size_t h,
double* in);
69 void circshift(Complex<Real>* in, Complex<Real>* out,
int shift_x,
int shift_y,
int nx,
int ny);
70 void ScaleBilnear(
double* src,
double* dst,
int w,
int h,
int neww,
int newh,
double multiplyval = 1.0);
71 void reArrangeChannel(std::vector<double*>& src,
double* dst,
int pnx,
int pny,
int chnum);
72 void rotateCCW180(
double* src,
double* dst,
int pnx,
int pny,
double mulival = 1.0);
84 LOG(
"<FAILED> Wrong file ext.\n");
91 LOG(
"<FAILED> Loading file (%d)\n", ret);
98 char szNodeName[32] = { 0, };
99 sprintf(szNodeName,
"SLM_WaveNum");
101 if (!next ||
XML_SUCCESS != next->QueryIntText(&nWave))
103 LOG(
"<FAILED> Not found node : \'%s\' (Integer) \n", szNodeName);
111 for (
int i = 1; i <= nWave; i++) {
112 sprintf(szNodeName,
"SLM_WaveLength_%d", i);
116 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
121 sprintf(szNodeName,
"SLM_PixelNumX");
125 LOG(
"<FAILED> Not found node : \'%s\' (Integer) \n", szNodeName);
129 sprintf(szNodeName,
"SLM_PixelNumY");
133 LOG(
"<FAILED> Not found node : \'%s\' (Integer) \n", szNodeName);
137 sprintf(szNodeName,
"SLM_PixelPitchX");
141 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
145 sprintf(szNodeName,
"SLM_PixelPitchY");
149 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
164 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&rec_config.EyeLength))
167 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&rec_config.EyePupilDiaMeter))
170 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&rec_config.EyeBoxSizeScale))
173 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&rec_config.EyeBoxSize[
_X]))
176 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&rec_config.EyeBoxSize[
_Y]))
179 if (!next ||
XML_SUCCESS != next->QueryIntText(&rec_config.EyeBoxUnit))
182 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&rec_config.EyeCenter[
_X]))
185 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&rec_config.EyeCenter[
_Y]))
188 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&rec_config.EyeCenter[
_Z]))
191 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&rec_config.EyeFocusDistance))
194 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&rec_config.ResultSizeScale))
197 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&rec_config.SimulationTo))
200 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&rec_config.SimulationFrom))
203 if (!next ||
XML_SUCCESS != next->QueryIntText(&rec_config.SimulationStep))
206 if (!next ||
XML_SUCCESS != next->QueryIntText(&rec_config.SimulationMode))
209 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&rec_config.RatioAtRetina))
212 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&rec_config.RatioAtPupil))
215 if (!next ||
XML_SUCCESS != next->QueryBoolText(&rec_config.CreatePupilFieldImg))
218 if (!next ||
XML_SUCCESS != next->QueryBoolText(&rec_config.CenteringRetinaImg))
224 rec_config.EyeBoxSize = rec_config.EyeBoxSizeScale * rec_config.EyePupilDiaMeter * rec_config.EyeBoxSize;
227 LOG(
"**************************************************\n");
228 LOG(
" Read Config (Common) \n");
234 LOG(
"4) Image Rotate : %s\n",
imgCfg.
rotate ?
"Y" :
"N");
238 LOG(
"6) Image Merge : %s\n",
imgCfg.
merge ?
"Y" :
"N");
239 LOG(
"**************************************************\n");
248 const int N = pnX * pnY;
255 int nSize = nLine *
h;
259 LOG(
"Failed::Image Load: %s\n", path);
262 LOG(
"Succeed::Image Load: %s\n", path);
265 memset(tmp, 0,
sizeof(
char) * nSize);
267 if (
w != pnX ||
h != pnY)
273 memcpy(tmp, imgload,
sizeof(
char) * nSize);
280 for (
int i = 0; i < N; i++)
295 const int N = pnX * pnY;
302 int nSize = nLine *
h;
306 LOG(
"Failed::Image Load: %s\n", phase);
309 LOG(
"Succeed::Image Load: %s\n", phase);
312 memset(phaseTmp, 0,
sizeof(
char) * nSize);
314 if (
w != pnX ||
h != pnY)
320 memcpy(phaseTmp, imgload,
sizeof(
char) * nSize);
333 LOG(
"Failed::Image Load: %s\n", amplitude);
336 LOG(
"Succeed::Image Load: %s\n", amplitude);
339 memset(ampTmp, 0,
sizeof(
char) * nSize);
341 if (
w != pnX ||
h != pnY)
347 memcpy(ampTmp, imgload,
sizeof(
char) * nSize);
356 for (
int i = 0; i < N; i++)
361 p = p / 255.0 * PI2 -
M_PI;
363 Complex<Real> tmp(0, p);
379 const int N = pnX * pnY;
386 int nSize = nLine *
h;
390 LOG(
"Failed::Image Load: %s\n", real);
393 LOG(
"Succeed::Image Load: %s\n", real);
396 memset(realTmp, 0,
sizeof(
char) * nSize);
398 if (
w != pnX ||
h != pnY)
404 memcpy(realTmp, imgload,
sizeof(
char) * nSize);
416 LOG(
"Failed::Image Load: %s\n", imag);
419 LOG(
"Succeed::Image Load: %s\n", imag);
422 memset(imagTmp, 0,
sizeof(
char) * nSize);
424 if (
w != pnX ||
h != pnY)
430 memcpy(imagTmp, imgload,
sizeof(
char) * nSize);
437 for (
int i = 0; i < N; i++)
451 LOG(
"Propagation to observer plane\n");
456 field_set_.resize(channel);
457 pp_set_.resize(channel);
458 fftw_complex *in =
nullptr;
459 fftw_complex *out =
nullptr;
462 for (
int ch = 0; ch < channel; ch++)
467 fftw_destroy_plan(fftw_plan_fwd);
472 LOG(
"Propagation to observer plane\n");
477 const int N = pnX * pnY;
481 field_set_.resize(nChannel);
482 pn_set_.resize(nChannel);
483 pp_set_.resize(nChannel);
485 fftw_complex *in =
nullptr, *out =
nullptr;
492 Real ssX = pnX * ppX;
493 Real ssY = pnY * ppY;
496 for (
int ctr = 0; ctr < nChannel; ctr++)
498 LOG(
"Color Number: %d\n", ctr + 1);
501 field_set_[ctr] =
new Complex<Real>[N];
502 memset(field_set_[ctr], 0.0,
sizeof(Complex<Real>) * N);
507 Real kk =
k / (prop_z * 2);
508 Real kpropz =
k * prop_z;
509 Real lambdapropz = lambda * prop_z;
510 Real ss_res_x = fabs(lambdapropz / ppX);
511 Real ss_res_y = fabs(lambdapropz / ppY);
512 Real hss_res_x = ss_res_x / 2.0;
513 Real hss_res_y = ss_res_y / 2.0;
514 Real pp_res_x = ss_res_x /
Real(pnX);
515 Real pp_res_y = ss_res_y /
Real(pnY);
516 Real absppX = fabs(lambdapropz / (4 * ppX));
517 Real absppY = fabs(lambdapropz / (4 * ppY));
520 #pragma omp parallel for private(loopi) 521 for (loopi = 0; loopi < N; loopi++)
526 double xx_src = (-ssX / 2.0) + (ppX * double(x));
527 double yy_src = (ssY / 2.0) - ppY - (ppY * double(y));
529 if (f_field != prop_z)
531 double effective_f = f_field * prop_z / (f_field - prop_z);
532 double sval = (xx_src*xx_src) + (yy_src*yy_src);
533 sval *=
M_PI / lambda / effective_f;
534 Complex<Real> kernel(0, sval);
538 double anti_aliasing_mask = fabs(xx_src) < fabs(lambda*effective_f / (4 * ppX)) ? 1 : 0;
539 anti_aliasing_mask *= fabs(yy_src) < fabs(lambda*effective_f / (4 * ppY)) ? 1 : 0;
541 field_set_[ctr][x + y * pnX] = u[x + y * pnX] * kernel * anti_aliasing_mask;
547 field_set_[ctr][x + y * pnX] = u[x + y * pnX];
558 #pragma omp parallel for private(loopi) 559 for (loopi = 0; loopi < N; loopi++)
564 double xx_res = (-ss_res_x / 2.0) + (pp_res_x * double(x));
565 double yy_res = (ss_res_y / 2.0) - pp_res_y - (pp_res_y * double(y));
567 Complex<Real> tmp1(0,
k*prop_z);
571 Complex<Real> tmp2(0, lambda*prop_z);
573 double ssval = (xx_res*xx_res) + (yy_res*yy_res);
574 ssval *=
k / (2 * prop_z);
575 Complex<Real> tmp3(0, ssval);
579 Complex<Real> coeff = tmp1 / tmp2 * tmp3;
581 field_set_[ctr][x + y * pnX] *= coeff;
584 pp_set_[ctr][0] = pp_res_x;
585 pp_set_[ctr][1] = pp_res_y;
589 fftw_destroy_plan(fft_plan_fwd);
596 const int N = pnX * pnY;
605 const Real simGap = (simStep > 1) ? (simTo - simFrom) / (simStep - 1) : 0;
607 const Real tx = 1 / ppX;
608 const Real ty = 1 / ppY;
609 const Real dx = tx / pnX;
610 const Real dy = ty / pnY;
612 const Real htx = tx / 2;
613 const Real hty = ty / 2;
614 const Real hdx = dx / 2;
615 const Real hdy = dy / 2;
616 const Real baseX = -htx + hdx;
617 const Real baseY = -hty + hdy;
619 Complex<Real>* tmp =
new Complex<Real>[N];
620 Complex<Real>* src =
nullptr;
621 Complex<Real>* dst =
new Complex<Real>[N];
622 Complex<Real>** kernels =
new Complex<Real>*[nWave];
623 for (
int i = 0; i < nWave; i++)
625 kernels[i] =
new Complex<Real>[N];
628 LOG(
"%s : Get Spatial Kernel\n", __FUNCTION__);
630 for (
int ch = 0; ch < nWave; ch++)
639 #pragma omp parallel for private(i) firstprivate(pnX, lambda, dx, dy, baseX, baseY) 641 for (i = 0; i < N; i++)
646 Real curX = baseX + (x * dx);
647 Real curY = baseY + (y * dy);
648 Real xx = curX * lambda;
649 Real yy = curY * lambda;
650 Real powxx = xx * xx;
651 Real powyy = yy * yy;
653 kernels[ch][i][
_RE] = 0;
654 kernels[ch][i][
_IM] = sqrt(1 - powxx - powyy);
658 LOG(
"%s : Simultation\n", __FUNCTION__);
661 for (
int step = 0; step < simStep; step++)
664 for (
int ch = 0; ch < nWave; ch++)
670 Real z = simFrom + (step * simGap);
679 for (
int i = 0; i < N; i++)
681 Complex<Real> kernel = kernels[ch][i];
689 for (
int i = 0; i < N; i++)
691 encode[i] = dst[i].mag();
699 m_vecEncoded.push_back(encode);
700 m_vecNormalized.push_back(normal);
703 LOG(
"step: %d => max: %e / min: %e\n", step, max, min);
706 for (
int ch = 0; ch < nWave; ch++)
708 int idx = step * nWave + ch;
709 normalize(m_vecEncoded[idx], m_vecNormalized[idx], pnX, pnY, max, min);
713 normalize(m_vecEncoded[step], m_vecNormalized[step], pnX, pnY);
716 m_oldSimStep = simStep;
720 for (
int i = 0; i < nWave; i++)
731 LOG(
"Color Number: %d\n", chnum + 1);
735 const int N = pnX * pnY;
741 Real ssX = pnX * ppX;
742 Real ssY = pnY * ppY;
743 Real hssX = ssX / 2.0;
744 Real hssY = ssY / 2.0;
749 Real kk =
k / (prop_z * 2);
750 Real kpropz =
k * prop_z;
751 Real lambdapropz = lambda * prop_z;
752 Real ss_res_x = fabs(lambdapropz / ppX);
753 Real ss_res_y = fabs(lambdapropz / ppY);
754 Real hss_res_x = ss_res_x / 2.0;
755 Real hss_res_y = ss_res_y / 2.0;
756 Real pp_res_x = ss_res_x /
Real(pnX);
757 Real pp_res_y = ss_res_y /
Real(pnY);
760 field_set_[chnum] =
new Complex<Real>[N];
761 memset(field_set_[chnum], 0.0,
sizeof(Complex<Real>) * N);
766 Real absppX = fabs(lambdapropz / (ppX4));
767 Real absppY = fabs(lambdapropz / (ppY4));
770 #pragma omp parallel for private(i) 771 for (i = 0; i < N; i++)
776 Real xx_src = -hssX + (ppX *
Real(x));
777 Real yy_src = hssY - ppY - (ppY *
Real(y));
778 Real xxx = xx_src - cxy[
_X];
779 Real yyy = yy_src - cxy[
_Y];
781 Real sval = xxx * xxx + yyy * yyy;
783 Complex<Real> kernel(0, sval);
787 Real anti_aliasing_mask = fabs(xxx) < absppX ? 1 : 0;
788 anti_aliasing_mask *= fabs(yyy) < absppY ? 1 : 0;
790 field_set_[chnum][x + y * pnX] = tmp[x + y * pnX] * kernel * anti_aliasing_mask;
798 #pragma omp parallel for private(i) 799 for (i = 0; i < N; i++)
804 Real xx_res = -hss_res_x + (pp_res_x *
Real(x));
805 Real yy_res = hss_res_y - pp_res_y - (pp_res_y *
Real(y));
806 Real xxx = xx_res - cxy[
_X];
807 Real yyy = yy_res - cxy[
_Y];
809 Complex<Real> tmp1(0, kpropz);
813 Complex<Real> tmp2(0, lambdapropz);
815 Real ssval = xxx * xxx + yyy * yyy;
817 Complex<Real> tmp3(0, ssval);
821 Complex<Real> coeff = tmp1 / tmp2 * tmp3;
823 field_set_[chnum][x + y * pnX] *= coeff;
828 pp_set_[chnum][
_X] = pp_res_x;
829 pp_set_[chnum][
_Y] = pp_res_y;
834 LOG(
"Simulation start\n");
856 memcpy(&bSimPos[0], rec_config.
SimulationPos,
sizeof(bSimPos));
859 std::vector<vec3> var_vals;
860 var_vals.resize(simStep);
864 var_step = (simTo - simFrom) / (simStep - 1);
865 for (
int i = 0; i < simStep; i++)
866 var_vals[i] = simFrom + var_step * i;
870 var_vals[0] = (simTo + simFrom) / 2.0;
874 Real pp_e_x, pp_e_y, ss_e_x, ss_e_y;
876 Real pp_p_x, pp_p_y, ss_p_x, ss_p_y;
877 vec2 eye_box_range_x, eye_box_range_y;
878 ivec2 eye_box_range_idx, eye_box_range_idy;
879 ivec2 eye_shift_by_pn;
881 field_ret_set_.resize(nChannel);
882 pn_ret_set_.resize(nChannel);
883 pp_ret_set_.resize(nChannel);
884 ss_ret_set_.resize(nChannel);
885 recon_set.resize(simStep * nChannel);
886 img_set.resize(simStep * nChannel);
887 img_size.resize(simStep * nChannel);
888 focus_recon_set.resize(simStep);
889 focus_img_set.resize(simStep);
890 focus_img_size.resize(simStep);
892 std::string varname2;
894 for (
int vtr = 0; vtr < simStep; vtr++)
897 eyeFocusDistance = var_vals[vtr][
_X];
900 if (bSimPos[
_X]) eyeCenter[
_X] = var_vals[vtr][
_X];
901 if (bSimPos[
_Y]) eyeCenter[
_Y] = var_vals[vtr][
_X];
902 if (bSimPos[
_Z]) eyeCenter[
_Z] = var_vals[vtr][
_X];
905 for (
int ctr = 0; ctr < nChannel; ctr++)
908 k = 2 *
M_PI / lambda;
912 pp_e_x = pp_set_[ctr][
_X];
913 pp_e_y = pp_set_[ctr][
_Y];
914 ss_e_x =
Real(pn_e_x) * pp_e_x;
915 ss_e_y =
Real(pn_e_y) * pp_e_y;
917 eye_shift_by_pn[0] = round(eyeCenter[
_X] / pp_e_x);
918 eye_shift_by_pn[1] = round(eyeCenter[
_Y] / pp_e_y);
920 Complex<Real>* hh_e_shift =
new Complex<Real>[pn_e_x * pn_e_y];
921 memset(hh_e_shift, 0.0,
sizeof(Complex<Real>) * pn_e_x * pn_e_y);
922 circshift(field_set_[ctr], hh_e_shift, -eye_shift_by_pn[0], eye_shift_by_pn[1], pn_e_x, pn_e_y);
927 eye_box_range_x[0] = -boxSize[
_X] / 2.0;
928 eye_box_range_x[1] = boxSize[
_X] / 2.0;
929 eye_box_range_y[0] = -boxSize[
_Y] / 2.0;
930 eye_box_range_y[1] = boxSize[
_Y] / 2.0;
931 eye_box_range_idx[0] = floor((eye_box_range_x[0] + ss_e_x / 2.0) / pp_e_x);
932 eye_box_range_idx[1] = floor((eye_box_range_x[1] + ss_e_x / 2.0) / pp_e_x);
933 eye_box_range_idy[0] = pn_e_y - floor((eye_box_range_y[1] + ss_e_y / 2.0) / pp_e_y);
934 eye_box_range_idy[1] = pn_e_y - floor((eye_box_range_y[0] + ss_e_y / 2.0) / pp_e_y);
939 int temp = floor((pn_e_x - boxSize[
_X]) / 2.0);
940 eye_box_range_idx[0] = temp;
941 eye_box_range_idx[1] = temp + boxSize[
_X] - 1;
942 temp = floor((pn_e_y - boxSize[
_Y]) / 2.0);
943 eye_box_range_idy[0] = temp;
944 eye_box_range_idy[1] = temp + boxSize[
_Y] - 1;
947 pn_p_x = eye_box_range_idx[1] - eye_box_range_idx[0] + 1;
948 pn_p_y = eye_box_range_idy[1] - eye_box_range_idy[0] + 1;
951 ss_p_x = pn_p_x * pp_p_x;
952 ss_p_y = pn_p_y * pp_p_y;
954 int N = pn_p_x * pn_p_y;
955 int N2 = pn_e_x * pn_e_y;
956 Complex<Real>* hh_p =
new Complex<Real>[N];
957 memset(hh_p, 0.0,
sizeof(Complex<Real>) * N);
961 for (
int p = 0; p < N2; p++)
966 if (x >= eye_box_range_idx[0] - 1 && x <= eye_box_range_idx[1] - 1 && y >= eye_box_range_idy[0] - 1 && y <= eye_box_range_idy[1] - 1)
968 int xx = cropidx % pn_p_x;
969 int yy = cropidx / pn_p_x;
970 hh_p[yy*pn_p_x + xx] = hh_e_shift[p];
976 Real f_eye = eyeLen * (eyeCenter[
_Z] - eyeFocusDistance) / (eyeLen + (eyeCenter[
_Z] - eyeFocusDistance));
977 Real effective_f = f_eye * eyeLen / (f_eye - eyeLen);
979 Complex<Real>* hh_e_ =
new Complex<Real>[N];
980 memset(hh_e_, 0.0,
sizeof(Complex<Real>) * N);
984 for (loopp = 0; loopp < N; loopp++)
986 int x = loopp % pn_p_x;
987 int y = loopp / pn_p_x;
989 Real XE = -ss_p_x / 2.0 + (pp_p_x *x);
990 Real YE = ss_p_y / 2.0 - pp_p_y - (pp_p_y * y);
992 Real sval = (XE*XE) + (YE*YE);
993 sval *=
M_PI / lambda / effective_f;
994 Complex<Real> eye_propagation_kernel(0, sval);
995 eye_propagation_kernel.exp();
997 Real eye_lens_anti_aliasing_mask = fabs(XE) < fabs(lambda*effective_f / (4 * pp_e_x)) ? 1.0 : 0.0;
998 eye_lens_anti_aliasing_mask *= fabs(YE) < fabs(lambda*effective_f / (4 * pp_e_y)) ? 1.0 : 0.0;
1000 Real eye_pupil_mask = sqrt(XE*XE + YE * YE) < (eyePupil / 2.0) ? 1.0 : 0.0;
1002 hh_e_[x + y * pn_p_x] = hh_p[x + y * pn_p_x] * eye_propagation_kernel * eye_lens_anti_aliasing_mask * eye_pupil_mask;
1009 Real pp_ret_x, pp_ret_y;
1010 int pn_ret_x, pn_ret_y;
1013 pp_ret_x = lambda * eyeLen / ss_p_x;
1014 pp_ret_y = lambda * eyeLen / ss_p_y;
1017 ret_size_xy[0] = pp_ret_x * pn_ret_x;
1018 ret_size_xy[1] = pp_ret_y * pn_ret_y;
1020 field_ret_set_[ctr] =
new Real[pn_p_x * pn_p_y];
1021 memset(field_ret_set_[ctr], 0.0,
sizeof(
Real)*pn_p_x*pn_p_y);
1024 for (loopp = 0; loopp < pn_p_x*pn_p_y; loopp++)
1026 int x = loopp % pn_p_x;
1027 int y = loopp / pn_p_x;
1029 Real XR = ret_size_xy[0] / 2.0 + (pp_ret_x * x);
1030 Real YR = ret_size_xy[1] / 2.0 - pp_ret_y - (pp_ret_y * y);
1032 Real sval = (XR*XR) + (YR*YR);
1033 sval *=
k / (2 * eyeLen);
1034 Complex<Real> val1(0, sval);
1037 Complex<Real> val2(0,
k * eyeLen);
1039 Complex<Real> val3(0, lambda * eyeLen);
1041 field_ret_set_[ctr][x + pn_p_x * y] = (hh_e_[x + pn_p_x * y] * (val1 * val2 / val3)).mag();
1046 pp_ret_set_[ctr] = vec2(pp_ret_x, pp_ret_y);
1047 pn_ret_set_[ctr] = ivec2(pn_ret_x, pn_ret_y);
1048 ss_ret_set_[ctr] = pp_ret_set_[ctr] * pn_ret_set_[ctr];
1050 if (bCreatePupilImg)
1052 Real pp_min = (pp_e_x > pp_e_y) ? pp_e_y : pp_e_x;
1053 Real ss_max = (ss_e_x > ss_e_y) ? ss_e_x : ss_e_y;
1054 Real pn_tar = ceil(ss_max / pp_min);
1055 pp_min = ss_max / pn_tar;
1056 Real pn_e_tar_x = round(ss_e_x / pp_min);
1057 Real pn_e_tar_y = round(ss_e_y / pp_min);
1059 Real resize_scale_x = pn_e_tar_x * resultSizeScale;
1060 Real resize_scale_y = pn_e_tar_y * resultSizeScale;
1062 int N = resize_scale_x * resize_scale_y;
1064 recon_set[vtr * nChannel + ctr] =
new Real[N];
1065 img_set[vtr * nChannel + ctr] =
new uchar[N];
1067 memset(recon_set[vtr * nChannel + ctr], 0.0,
sizeof(
Real) * N);
1068 memset(img_set[vtr * nChannel + ctr], 0,
sizeof(
uchar) * N);
1071 , pn_e_x, pn_e_y, pp_e_x, pp_e_y, resize_scale_x, resize_scale_y);
1073 std::string fname = std::string(
"./").append(
"").append(
"/FIELD/");
1074 fname = fname.append(
"FIELD_COLOR_").append(std::to_string(ctr + 1)).append(
"_").append(
"").append(
"_SAT_").append(
"").append(
"_").append(std::to_string(vtr + 1)).append(
".bmp");
1075 normalize(recon_set[vtr * nChannel + ctr], img_set[vtr * nChannel + ctr], (
int)resize_scale_x, (
int)resize_scale_y);
1076 img_size[vtr * nChannel + ctr][
_X] = (int)resize_scale_x;
1077 img_size[vtr * nChannel + ctr][
_Y] = (int)resize_scale_y;
1082 Real pnx_max = 0.0, pny_max = 0.0;
1083 for (
int i = 0; i < nChannel; i++)
1085 pnx_max = (pn_ret_set_[i][0] > pnx_max ? pn_ret_set_[i][0] : pnx_max);
1086 pny_max = (pn_ret_set_[i][1] > pny_max ? pn_ret_set_[i][1] : pny_max);
1089 Real retinal_image_shift_x = eyeCenter[
_X] * eyeLen / eyeCenter[
_Z];
1090 Real retinal_image_shift_y = eyeCenter[
_Y] * eyeLen / eyeCenter[
_Z];
1092 res_set_.resize(nChannel);
1093 res_set_norm_255_.resize(nChannel);
1097 for (loopi = 0; loopi < nChannel; loopi++)
1100 Real* hh_ret_ =
new Real[pn_ret_set_[loopi][0] * pn_ret_set_[loopi][1]];
1101 memset(hh_ret_, 0.0,
sizeof(
Real)*pn_ret_set_[loopi][0] * pn_ret_set_[loopi][1]);
1103 if (bCenteringRetinaImg)
1105 Real retinal_image_shift_by_pn_x = round(retinal_image_shift_x / pp_ret_set_[loopi][0]);
1106 Real retinal_image_shift_by_pn_y = round(retinal_image_shift_y / pp_ret_set_[loopi][1]);
1108 circshift(field_ret_set_[loopi], hh_ret_, -retinal_image_shift_by_pn_x, retinal_image_shift_by_pn_y, pn_ret_set_[loopi][0], pn_ret_set_[loopi][1]);
1112 hh_ret_ = field_ret_set_[loopi];
1114 delete[] field_ret_set_[loopi];
1116 int size = (int)(pnx_max * pny_max);
1117 res_set_[loopi] =
new Real[size];
1118 memset(res_set_[loopi], 0.0,
sizeof(
Real) * size);
1119 ScaleBilnear(hh_ret_, res_set_[loopi], pn_ret_set_[loopi][0], pn_ret_set_[loopi][1], pnx_max, pny_max, lambda * lambda);
1123 Real maxvalue = res_set_[0][0];
1124 Real minvalue = res_set_[0][0];
1125 for (
int i = 0; i < nChannel; i++)
1127 for (
int j = 0; j < pnx_max*pny_max; j++)
1129 maxvalue = res_set_[i][j] > maxvalue ? res_set_[i][j] : maxvalue;
1130 minvalue = res_set_[i][j] < minvalue ? res_set_[i][j] : minvalue;
1134 for (
int j = 0; j < pnx_max*pny_max; j++)
1136 res_set_[0][j] = (res_set_[0][j] - minvalue) / (maxvalue - minvalue) * 255;
1140 for (loopi = 0; loopi < nChannel; loopi++)
1142 for (
int j = 0; j < pnx_max*pny_max; j++)
1144 if (res_set_[loopi][j] > ratioAtRetina * maxvalue)
1145 res_set_[loopi][j] = ratioAtRetina * maxvalue;
1147 res_set_[loopi][j] = (res_set_[loopi][j] - minvalue) / (ratioAtRetina*maxvalue - minvalue);
1152 Real ret_size_x = pnx_max * resultSizeScale;
1153 Real ret_size_y = pny_max * resultSizeScale;
1155 int size = (int)(ret_size_x * ret_size_y);
1158 for (loopi = 0; loopi < nChannel; loopi++)
1160 Real* res_set_norm =
new Real[size];
1161 memset(res_set_norm, 0.0,
sizeof(
Real) * size);
1163 ScaleBilnear(res_set_[loopi], res_set_norm, pnx_max, pny_max, ret_size_x, ret_size_y);
1165 res_set_norm_255_[loopi] =
new Real[size];
1166 memset(res_set_norm_255_[loopi], 0.0,
sizeof(
Real) * size);
1168 rotateCCW180(res_set_norm, res_set_norm_255_[loopi], ret_size_x, ret_size_y, 255.0);
1170 delete[] res_set_norm;
1173 for (
int i = 0; i < nChannel; i++)
1174 delete[] res_set_[i];
1176 int N = ret_size_x * ret_size_y;
1178 focus_recon_set[vtr] =
new Real[N * nChannel];
1179 focus_img_set[vtr] =
new uchar[N * nChannel];
1180 memset(focus_recon_set[vtr], 0.0,
sizeof(
Real) * N * nChannel);
1181 memset(focus_img_set[vtr], 0,
sizeof(
uchar) * N * nChannel);
1184 memcpy(focus_recon_set[vtr], res_set_norm_255_[0],
sizeof(
Real)*ret_size_x*ret_size_y);
1186 reArrangeChannel(res_set_norm_255_, focus_recon_set[vtr], ret_size_x, ret_size_y, nChannel);
1188 std::string fname = std::string(
"./").append(
"").append(
"/").append(
"").append(
"_SAT_").append(
"").append(
"_").append(varname2).append(
"_").append(std::to_string(vtr + 1)).append(
".bmp");
1190 normalize(focus_recon_set[vtr], focus_img_set[vtr], ret_size_x, ret_size_y);
1192 focus_img_size[vtr][
_X] = (int)ret_size_x;
1193 focus_img_size[vtr][
_Y] = (int)ret_size_y;
1195 m_vecEncoded.push_back(focus_recon_set[vtr]);
1196 m_vecNormalized.push_back(focus_img_set[vtr]);
1199 for (
int i = 0; i < nChannel; i++)
1200 delete[] res_set_norm_255_[i];
1208 if (fname ==
nullptr)
return bOK;
1210 uchar* source = src;
1211 bool bAlloc =
false;
1215 if (px == 0 && py == 0)
1219 std::string file = fname;
1220 std::replace(file.begin(), file.end(),
'\\',
'/');
1223 std::vector<std::string> components;
1224 std::stringstream ss(file);
1228 while (std::getline(ss, item, token)) {
1229 components.push_back(item);
1234 for (
size_t i = 0; i < components.size() - 1; i++)
1236 dir += components[i];
1240 std::string filename = components[components.size() - 1];
1244 size_t ext_pos = file.rfind(
".");
1245 hasExt = (ext_pos == string::npos) ?
false :
true;
1248 filename.append(
".bmp");
1250 std::string fullpath = dir + filename;
1252 if (nChannel == 1) {
1253 saveAsImg(fullpath.c_str(), bitsperpixel, src, p[
_X], p[
_Y]);
1255 else if (nChannel == 3) {
1257 uint nSize = (((p[
_X] * bitsperpixel >> 3) + 3) & ~3) * p[
_Y];
1260 for (
uint i = 0; i < nChannel; i++) {
1263 saveAsImg(fullpath.c_str(), bitsperpixel, source, p[
_X], p[
_Y]);
1264 if (bAlloc)
delete[] source;
1267 char path[FILENAME_MAX] = { 0, };
1268 sprintf(path,
"%s%s", dir.c_str(), filename.c_str());
1269 saveAsImg(path, bitsperpixel / nChannel, src, p[
_X], p[
_Y]);
1296 pnX = focus_img_size[0][
_X];
1297 pnY = focus_img_size[0][
_Y];
1301 step = (simTo - simFrom) / (nSimStep - 1);
1304 char tmpPath[FILENAME_MAX] = { 0, };
1305 bool bMultiStep = nSimStep > 1 ?
true :
false;
1306 uint nSize = (((pnX * nChannel) + 3) & ~3) * pnY;
1309 for (
int i = 0; i < nSimStep; i++)
1311 sprintf(tmpPath,
"%s\\FOCUS_%.4f.%s", path, bMultiStep ?
1312 simFrom + (step * i) : (simFrom + simTo) / 2, ext);
1318 for (
int ch = 0; ch < nChannel; ch++)
1320 mergeColor(ch, pnX, pnY, m_vecNormalized[i * nChannel + ch], tmp);
1322 saveAsImg(tmpPath, 8 * nChannel, tmp, pnX, pnY);
1326 for (
int ch = 0; ch < nChannel; ch++)
1328 memset(tmp, 0,
sizeof(
uchar) * nSize);
1329 sprintf(tmpPath,
"%s\\FOCUS_%.4f (%d).%s", path, bMultiStep ? simFrom + step * i : (simFrom + simTo) / 2, ch, ext);
1330 mergeColor(ch, pnX, pnY, m_vecNormalized[i * nChannel + ch], tmp);
1331 saveAsImg(tmpPath, 8 * nChannel, tmp, pnX, pnY);
1337 memcpy(tmp, m_vecNormalized[i],
sizeof(
uchar) * nSize);
1338 saveAsImg(tmpPath, 8 * nChannel, tmp, pnX, pnY);
1346 const int N = pnx * pny;
1353 memset(dimg, 0.0,
sizeof(
Real) * N);
1355 Real maxvalue = src[0].mag();
1356 for (
int k = 0;
k < N;
k++)
1358 Real val = src[
k].mag();
1359 maxvalue = val > maxvalue ? val : maxvalue;
1363 Real SAT_VAL = maxvalue * ratioAtPupil;
1364 Real hss_x = (pnx * ppx) / 2.0;
1365 Real hss_y = (pny * ppy) / 2.0;
1366 Real halfPupil = eyePupil / 2.0;
1368 Real maxv = dimg[0], minv = dimg[0];
1369 for (
int k = 0;
k < N;
k++)
1371 if (dimg[
k] > SAT_VAL)
1374 maxv = (dimg[
k] > maxv) ? dimg[
k] : maxv;
1375 minv = (dimg[
k] < minv) ? dimg[
k] : minv;
1378 for (
int k = 0;
k < N;
k++)
1383 Real xx = -hss_x + (ppx * x);
1384 Real yy = -hss_y + (pny - 1) * ppy - (ppy * y);
1385 Real xxx = xx - eyeCenter[
_X];
1386 Real yyy = yy - eyeCenter[
_Y];
1387 bool eye_pupil_mask = sqrt(xxx * xxx + yyy * yyy) < halfPupil ? 1.0 : 0.0;
1390 Real field_out = (val - minv) / (maxv - minv) * 255.0;
1391 Real field_in = (val - minv) / (maxv - minv) * 127.0 + 128.0;
1392 dimg[
k] = field_in * eye_pupil_mask + field_out * (1 - eye_pupil_mask);
1404 memcpy(&bSimPos[0], rec_config.
SimulationPos,
sizeof(bSimPos));
1406 std::string varname;
1411 varname.append(
"FOCUS");
1413 LOG(
"Step # %d %s = %.8f \n", vtr + 1, varname.c_str(), var_vals[0]);
1415 sprintf(temp,
"%.5f", var_vals[0]);
1417 varname2.append(varname).append(
"_").append(temp);
1418 varname2.replace(varname2.find(
'.'), 1,
"_");
1423 varname.append(
"POSITION");
1425 if (bSimPos[
_X]) varname.append(
"_X");
1426 if (bSimPos[
_Y]) varname.append(
"_Y");
1427 if (bSimPos[
_Z]) varname.append(
"_Z");
1429 LOG(
"Step # %d %s = ", vtr + 1, varname.c_str());
1431 varname2.append(varname);
1434 LOG(
"%.8f ", var_vals[0]);
1436 sprintf(temp,
"%.5f", var_vals[0]);
1437 varname2.append(
"_").append(temp);
1438 varname2.replace(varname2.find(
'.'), 1,
"_");
1441 LOG(
"%.8f ", var_vals[1]);
1443 sprintf(temp,
"%.5f", var_vals[1]);
1444 varname2.append(
"_").append(temp);
1445 varname2.replace(varname2.find(
'.'), 1,
"_");
1448 LOG(
"%.8f ", var_vals[2]);
1450 sprintf(temp,
"%.5f", var_vals[2]);
1451 varname2.append(
"_").append(temp);
1452 varname2.replace(varname2.find(
'.'), 1,
"_");
1460 for (vector<Real*>::iterator it = m_vecEncoded.begin(); it != m_vecEncoded.end(); it++)
1465 for (vector<uchar*>::iterator it = m_vecNormalized.begin(); it != m_vecNormalized.end(); it++)
1469 m_vecEncoded.clear();
1470 m_vecNormalized.clear();
1479 LOG(
"1) Algorithm Method : Angular Spectrum\n");
1480 LOG(
"2) Reconstruct Image with %s\n", m_mode &
MODE_GPU ?
1502 for (
int i = 0; i < m_nOldChannel; i++) {
1511 complex_H =
new Complex<Real>*[nChannel];
1512 for (
int i = 0; i < nChannel; i++) {
1514 memset(
complex_H[i], 0,
sizeof(Complex<Real>) * N);
1516 m_nOldChannel = nChannel;
1523 for (vector<Real*>::iterator it = m_vecEncoded.begin(); it != m_vecEncoded.end(); it++)
1527 m_vecEncoded.clear();
1529 for (vector<uchar*>::iterator it = m_vecNormalized.begin(); it != m_vecNormalized.end(); it++)
1533 m_vecNormalized.clear();
1539 for (
int i = 0; i < nx; i++)
1541 for (
int j = 0; j < ny; j++)
1543 ti = (i + shift_x) % nx;
1546 tj = (j + shift_y) % ny;
1550 out[ti + tj * nx] = in[i + j * nx];
1555 void circshift(Complex<Real>* in, Complex<Real>* out,
int shift_x,
int shift_y,
int nx,
int ny)
1558 for (
int i = 0; i < nx; i++)
1560 for (
int j = 0; j < ny; j++)
1562 ti = (i + shift_x) % nx;
1565 tj = (j + shift_y) % ny;
1569 out[ti + tj * nx] = in[i + j * nx];
1576 int x1 = (int)floor(xx);
1577 int x2 = (int)ceil(xx);
1578 int y1 = (int)floor(yy);
1579 int y2 = (int)ceil(yy);
1581 if (x1 < 0 || x1 >= (
int)
w || x2 < 0 || x2 >= (int)
w)
return vec3(0);
1582 if (y1 < 0 || y1 >= (
int)
h || y2 < 0 || y2 >= (
int)
h)
return vec3(0);
1585 double v1, v2, v3, v4, tvx, tvy;
1587 tvx = xx - floor(xx);
1588 tvy = yy - floor(yy);
1590 for (
int i = 0; i < tc; i++) {
1595 v1 = (1.0 - tvx)*v1 + tvx * v2;
1596 v3 = (1.0 - tvx)*v3 + tvx * v4;
1597 v1 = (1.0 - tvy)*v1 + tvy * v3;
1605 void ScaleBilnear(
double* src,
double* dst,
int w,
int h,
int neww,
int newh,
double multiplyval)
1607 for (
int y = 0; y < newh; y++)
1609 for (
int x = 0; x < neww; x++)
1611 float gx = (x / (float)neww) * (
w - 1);
1612 float gy = (y / (float)newh) * (
h - 1);
1615 dst[x + y * neww] = ret[0];
1638 void rotateCCW180(
double* src,
double* dst,
int pnx,
int pny,
double mulival)
1640 for (
int i = 0; i < pnx*pny; i++)
1645 int newx = pnx - x - 1;
1646 int newy = pny - y - 1;
1648 dst[newx + newy * pnx] = mulival * src[x + y * pnx];
1656 for (
int k = 0;
k < pnx*pny;
k++)
1658 for (
int c = 0; c < chnum; c++)
1661 dst[
k*chnum + 2] = src[c][
k];
1663 dst[
k*chnum + 0] = src[c][
k];
1665 dst[
k*chnum + c] = src[c][
k];
virtual bool saveAsImg(const char *fname, uint8_t bitsperpixel, uchar *src, int width, int height)
Function for creating image files.
void reArrangeChannel(std::vector< double *> &src, double *dst, int pnx, int pny, int chnum)
void fftFree(void)
Resource release method.
void GetPupilFieldFromVWHologram()
void SaveImage(const char *path, const char *ext="bmp")
void rotateCCW180(double *src, double *dst, int pnx, int pny, double mulival=1.0)
bool checkExtension(const char *fname, const char *ext)
Functions for extension checking.
void getVarname(int vtr, vec3 &var_vals, std::string &varname2)
virtual void ophFree(void)
Pure virtual function for override in child classes.
const XMLNode * FirstChild() const
Get the first child node, or null if none exists.
bool readImage(const char *path)
virtual ~ophRec(void)
Destructor.
void GetPupilFieldFromHologram()
void circshift(Real *in, Real *out, int shift_x, int shift_y, int nx, int ny)
void imgScaleBilinear(uchar *src, uchar *dst, int w, int h, int neww, int newh, int channels=1)
Function for change image size.
vec3 image_sample(float xx, float yy, int c, size_t w, size_t h, double *in)
bool getImgSize(int &w, int &h, int &bytesperpixel, const char *fname)
Function for getting the image size.
bool readImagePNA(const char *phase, const char *amplitude)
bool readImageRNI(const char *real, const char *imaginary)
void fft2(ivec2 n, Complex< Real > *in, int sign=OPH_FORWARD, uint flag=OPH_ESTIMATE)
Functions for performing fftw 2-dimension operations inside Openholo.
void GetPupilFieldImage(Complex< Real > *src, double *dst, int pnx, int pny, double ppx, double ppy, double scaleX, double scaleY)
bool save(const char *fname, uint8_t bitsperpixel, uchar *src, uint px, uint py)
XMLError LoadFile(const char *filename)
void ASM_Propagation_GPU()
bool readConfig(const char *fname)
Complex< Real > ** complex_H
void ScaleBilnear(double *src, double *dst, int w, int h, int neww, int newh, double multiplyval=1.0)
#define ELAPSED_TIME(x, y)
void Perform_Simulation()
#define IMAGE_VAL(x, y, c, w, n, mem)
void Propagation_Fresnel_FFT(int chnum)
bool loadAsImgUpSideDown(const char *fname, uchar *dst)
Function for loading image files | Output image data upside down.
const XMLElement * FirstChildElement(const char *name=0) const
bool mergeColor(int idx, int width, int height, uchar *src, uchar *dst)
Function for generate RGB image from each grayscale image.
virtual void ophFree(void)
Pure virtual function for override in child classes.
void normalize(T *src, uchar *dst, int x, int y)