49 #include <cuda_runtime_api.h> 55 #include "ImgControl.h" 57 #include "PLYparser.h" 73 void cudaFFT(CUstream_st* stream,
int nx,
int ny, cufftDoubleComplex* in_filed, cufftDoubleComplex* output_field,
int direction,
bool bNormailized =
false);
89 void cudaCropFringe(CUstream_st* stream,
int nx,
int ny, cufftDoubleComplex* in_field, cufftDoubleComplex* out_field,
int cropx1,
int cropx2,
int cropy1,
int cropy2);
108 void cudaGetFringe(CUstream_st* stream,
int pnx,
int pny, cufftDoubleComplex* in_field, cufftDoubleComplex* out_field,
int sig_locationx,
int sig_locationy,
118 , m_lpEncoded(nullptr)
119 , m_lpNormalized(nullptr)
122 , m_dFieldLength(0.0)
126 , normalized(nullptr)
135 , m_bRandomPhase(false)
153 for (
uint i = 0; i < m_nOldChannel; i++) {
163 complex_H =
new Complex<Real>*[nChannel];
164 for (
uint i = 0; i < nChannel; i++) {
170 for (
uint i = 0; i < m_nOldChannel; i++) {
180 for (
uint i = 0; i < nChannel; i++) {
186 for (
uint i = 0; i < m_nOldChannel; i++) {
196 for (
uint i = 0; i < nChannel; i++) {
201 m_nOldChannel = nChannel;
229 LOG(
"<FAILED> Wrong file ext.\n");
235 LOG(
"<FAILED> Loading file (%d)\n", ret);
241 char szNodeName[32] = { 0, };
243 sprintf(szNodeName,
"SLM_WaveNum");
245 if (!next ||
XML_SUCCESS != next->QueryIntText(&nWave))
247 LOG(
"<FAILED> Not found node : \'%s\' (Integer) \n", szNodeName);
254 for (
int i = 1; i <= nWave; i++) {
255 sprintf(szNodeName,
"SLM_WaveLength_%d", i);
259 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
264 sprintf(szNodeName,
"SLM_PixelNumX");
268 LOG(
"<FAILED> Not found node : \'%s\' (Integer) \n", szNodeName);
272 sprintf(szNodeName,
"SLM_PixelNumY");
276 LOG(
"<FAILED> Not found node : \'%s\' (Integer) \n", szNodeName);
280 sprintf(szNodeName,
"SLM_PixelPitchX");
284 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
288 sprintf(szNodeName,
"SLM_PixelPitchY");
292 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
335 for (
int i = 0; i < nWave; i++)
342 LOG(
"**************************************************\n");
343 LOG(
" Read Config (Common) \n");
349 LOG(
"4) Image Rotate : %s\n",
imgCfg.
rotate ?
"Y" :
"N");
353 LOG(
"6) Image Merge : %s\n",
imgCfg.
merge ?
"Y" :
"N");
354 LOG(
"**************************************************\n");
367 const Real ssX = pConfig->
ss[
_X] = pnX * ppX;
368 const Real ssY = pConfig->
ss[
_Y] = pnY * ppY;
369 const int offsetX = pConfig->
offset[
_X];
370 const int offsetY = pConfig->
offset[
_Y];
372 const Real tx = lambda / (2 * ppX);
373 const Real ty = lambda / (2 * ppY);
374 const Real sqrtX = sqrt(1 - (tx * tx));
375 const Real sqrtY = sqrt(1 - (ty * ty));
376 const Real x = -ssX / 2;
377 const Real y = -ssY / 2;
381 Real ampZ = amplitude * z;
394 floor((_xbound[
_X] - x) / ppX) + 1,
395 floor((_xbound[
_Y] - x) / ppX) + 1
399 pnY - floor((_ybound[
_Y] - y) / ppY),
400 pnY - floor((_ybound[
_X] - y) / ppY)
403 if (Xbound[
_X] > pnX) Xbound[
_X] = pnX;
404 if (Xbound[
_Y] < 0) Xbound[
_Y] = 0;
405 if (Ybound[
_X] > pnY) Ybound[
_X] = pnY;
406 if (Ybound[
_Y] < 0) Ybound[
_Y] = 0;
409 for (
int yytr = Ybound[
_Y]; yytr < Ybound[
_X]; ++yytr)
411 int offset = yytr * pnX;
412 Real yyy = y + ((pnY - yytr + offsetY) * ppY);
419 for (
int xxtr = Xbound[
_Y]; xxtr < Xbound[
_X]; ++xxtr)
421 Real xxx = x + ((xxtr - 1 + offsetX) * ppX);
428 if (((xxx < range_x[
_X]) && (xxx > range_x[
_Y])) && ((yyy < range_y[
_X]) && (yyy > range_y[
_Y]))) {
430 Real operand = lambda * r * r;
431 Real res_real = (ampZ * sin(kr)) / operand;
432 Real res_imag = (-ampZ * cos(kr)) / operand;
435 dst[offset + xxtr][
_RE] += res_real;
439 dst[offset + xxtr][
_IM] += res_imag;
453 const Real ssX = pConfig->
ss[
_X] = pnX * ppX;
454 const Real ssY = pConfig->
ss[
_Y] = pnY * ppY;
455 const int offsetX = pConfig->
offset[
_X];
456 const int offsetY = pConfig->
offset[
_Y];
464 Real operand = lambda * z;
467 src.
pos[
_X] +
abs(operand / (2 * ppX)),
468 src.
pos[
_X] -
abs(operand / (2 * ppX))
472 src.
pos[
_Y] +
abs(operand / (2 * ppY)),
473 src.
pos[
_Y] -
abs(operand / (2 * ppY))
477 floor((_xbound[
_X] - x) / ppX) + 1,
478 floor((_xbound[
_Y] - x) / ppX) + 1
482 pnY - floor((_ybound[
_Y] - y) / ppY),
483 pnY - floor((_ybound[
_X] - y) / ppY)
486 if (Xbound[
_X] > pnX) Xbound[
_X] = pnX;
487 if (Xbound[
_Y] < 0) Xbound[
_Y] = 0;
488 if (Ybound[
_X] > pnY) Ybound[
_X] = pnY;
489 if (Ybound[
_Y] < 0) Ybound[
_Y] = 0;
491 for (
int yytr = Ybound[
_Y]; yytr < Ybound[
_X]; ++yytr)
493 Real yyy = (y + (pnY - yytr + offsetY) * ppY) - src.
pos[
_Y];
494 int offset = yytr * pnX;
495 for (
int xxtr = Xbound[
_Y]; xxtr < Xbound[
_X]; ++xxtr)
497 Real xxx = (x + (xxtr - 1 + offsetX) * ppX) - src.
pos[
_X];
498 Real p =
k * (xxx * xxx + yyy * yyy + 2 * zz) / (2 * z);
500 Real res_real = amplitude * sin(p) / operand;
501 Real res_imag = amplitude * (-cos(p)) / operand;
506 dst[offset + xxtr][
_RE] += res_real;
510 dst[offset + xxtr][
_IM] += res_imag;
523 const Real ssX = pConfig->
ss[
_X] = pnX * ppX;
524 const Real ssY = pConfig->
ss[
_Y] = pnY * ppY;
525 const Real ssX2 = ssX * 2;
526 const Real ssY2 = ssY * 2;
529 Complex<Real>* in2x =
new Complex<Real>[rc->
double_size];
530 memset(in2x, 0,
sizeof(Complex<Real>) * rc->
double_size);
533 for (
int i = 0; i < pnY; i++) {
534 for (
int j = 0; j < pnX; j++) {
539 Complex<Real>* temp1 =
new Complex<Real>[rc->
double_size];
560 for (
int idxFy = -pnY; idxFy < pnY; idxFy++) {
564 for (
int idxFx = -pnX; idxFx < pnX; idxFx++) {
565 fx[i] = idxFx / ssX2;
570 Complex<Real>* prop =
new Complex<Real>[rc->
double_size];
571 memset(prop, 0,
sizeof(Complex<Real>) * rc->
double_size);
575 Complex<Real>* temp2 =
new Complex<Real>[rc->
double_size];
576 Real lambda_square = lambda * lambda;
580 sqrtPart = sqrt(1 / lambda_square - fx[i] * fx[i] - fy[i] * fy[i]);
582 prop[i][
_IM] *= sqrtPart;
583 temp2[i] = temp1[i] * exp(prop[i]);
586 Complex<Real>* temp3 =
new Complex<Real>[rc->
double_size];
591 for (
int i = 0; i < pnY; i++) {
592 for (
int j = 0; j < pnX; j++) {
610 const int N = pnX * pnY;
621 Real kd =
k * distance;
622 Real fx = -1 / (ppX * 2);
623 Real fy = 1 / (ppY * 2);
626 #pragma omp parallel for firstprivate(pnX, dfx, dfy, lambda, kd, kk) 628 for (
int i = 0; i < N; i++)
633 Real fxx = fx + dfx * x;
634 Real fyy = fy - dfy - dfy * y;
636 Real fxxx = lambda * fxx;
637 Real fyyy = lambda * fyy;
639 Real sval = sqrt(1 - (fxxx * fxxx) - (fyyy * fyyy));
641 Complex<Real> kernel(0, sval);
644 bool prop_mask = ((fxx * fxx + fyy * fyy) < kk) ?
true :
false;
646 Complex<Real> u_frequency;
648 u_frequency = kernel * src[i];
649 dst[i][
_RE] += u_frequency[
_RE];
650 dst[i][
_IM] += u_frequency[
_IM];
655 void ophGen::conv_fft2(Complex<Real>* src1, Complex<Real>* src2, Complex<Real>* dst, ivec2 size)
657 int N = size[
_X] * size[
_Y];
660 Complex<Real>* src1FT =
new Complex<Real>[N];
661 Complex<Real>* src2FT =
new Complex<Real>[N];
662 Complex<Real>* dstFT =
new Complex<Real>[N];
667 for (
int i = 0; i < N; i++)
668 dstFT[i] = src1FT[i] * src2FT[i];
682 const long long int N = pnX * pnY;
685 for (
uint ch = 0; ch < nWave; ch++)
696 gap = maxVal - minVal;
697 for (
uint ch = 0; ch < nWave; ch++)
700 #pragma omp parallel for firstprivate(minVal, gap, pnX) 702 for (
int j = 0; j < pnY; j++) {
704 for (
int i = 0; i < pnX; i++) {
716 if (fname ==
nullptr)
return bOK;
723 if (px == 0 && py == 0)
727 std::string file = fname;
728 std::replace(file.begin(), file.end(),
'\\',
'/');
731 std::vector<std::string> components;
732 std::stringstream ss(file);
736 while (std::getline(ss, item, token)) {
737 components.push_back(item);
742 for (
size_t i = 0; i < components.size() - 1; i++)
744 dir += components[i];
748 std::string filename = components[components.size() - 1];
752 size_t ext_pos = file.rfind(
".");
753 hasExt = (ext_pos == string::npos) ?
false :
true;
756 filename.append(
".bmp");
758 std::string fullpath = dir + filename;
760 if (src ==
nullptr) {
763 saveAsImg(fullpath.c_str(), bitsperpixel, source, p[
_X], p[
_Y]);
765 else if (nChannel == 3) {
767 uint nSize = (((p[
_X] * bitsperpixel >> 3) + 3) & ~3) * p[
_Y];
768 source =
new uchar[nSize];
770 for (
uint i = 0; i < nChannel; i++) {
774 saveAsImg(fullpath.c_str(), bitsperpixel, source, p[
_X], p[
_Y]);
775 if (bAlloc)
delete[] source;
778 for (
uint i = 0; i < nChannel; i++) {
779 char path[FILENAME_MAX] = { 0, };
780 sprintf(path,
"%s%d_%s", dir.c_str(), i, filename.c_str());
782 saveAsImg(path, bitsperpixel / nChannel, source, p[
_X], p[
_Y]);
789 saveAsImg(fullpath.c_str(), bitsperpixel, source, p[
_X], p[
_Y]);
815 for (
uint ch = 0; ch < nChannel; ch++) {
831 memset(
complex_H[ch], 0.,
sizeof(Complex<Real>) * N);
844 void (
ophGen::*encodeFunc) (Complex<Real>*,
Real*,
const int) =
nullptr;
846 Complex<Real> *holo =
nullptr;
847 Real *encoded =
nullptr;
861 LOG(
"<FAILED> WRONG PARAMETERS.\n");
880 void (
ophGen::*encodeFunc) (Complex<Real>*,
Real*,
const int) =
nullptr;
894 default: LOG(
"<FAILED> WRONG PARAMETERS.\n");
return;
897 if (holo ==
nullptr) holo =
complex_H[0];
907 holo ==
nullptr ? holo = *
complex_H : holo;
908 encoded ==
nullptr ? encoded = *
m_lpEncoded : encoded;
914 for (
uint ch = 0; ch < nChannel; ch++) {
933 LOG(
"ENCODE_OFFSSB");
934 Complex<Real> *tmp =
new Complex<Real>[pnXY];
935 memcpy(tmp, holo,
sizeof(Complex<Real>) * pnXY);
942 LOG(
"<FAILED> WRONG PARAMETERS.\n");
954 switch (BIN_ENCODE_FLAG) {
956 LOG(
"ENCODE_SIMPLEBINARY\n");
957 if (holo ==
nullptr || encoded ==
nullptr)
958 for (
uint ch = 0; ch < nChannel; ch++) {
965 LOG(
"ENCODE_EDBINARY\n");
967 LOG(
"<FAILED> WRONG PARAMETERS : %d\n",
ENCODE_FLAG);
970 if (holo ==
nullptr || encoded ==
nullptr)
971 for (
uint ch = 0; ch < nChannel; ch++) {
978 LOG(
"<FAILED> WRONG PARAMETERS.\n");
993 for (
uint ch = 0; ch < nChannel; ch++) {
1007 LOG(
"ENCODE_SIMPLENI\n");
1011 LOG(
"ENCODE_REAL\n");
1015 LOG(
"ENCODE_BURCKHARDT\n");
1019 LOG(
"ENCODE_TWOPHASE\n");
1023 LOG(
"ENCODE_PHASE\n");
1027 LOG(
"ENCODE_AMPLITUDE\n");
1031 LOG(
"ENCODE_SSB\n");
1035 LOG(
"ENCODE_OFFSSB\n");
1040 LOG(
"<FAILED> WRONG PARAMETERS.\n");
1048 const int nX = holosize[
_X];
1049 const int nY = holosize[
_Y];
1050 const int half_nX = nX >> 1;
1051 const int half_nY = nY >> 1;
1053 const long long int N = nX * nY;
1054 const long long int half_N = N >> 1;
1056 Complex<Real>*
AS =
new Complex<Real>[N];
1065 for (
int i = 0; i < nY; i++)
1068 for (
int j = half_nX; j < nX; j++)
1075 for (
int i = 0; i < nY; i++)
1078 for (
int j = 0; j < half_nX; j++)
1085 memset(&
AS[half_N], 0,
sizeof(Complex<Real>) * half_N);
1089 memset(&
AS[0], 0,
sizeof(Complex<Real>) * half_N);
1093 Complex<Real>* filtered =
new Complex<Real>[N];
1101 oph::realPart<Real>(filtered, realFiltered, N);
1107 delete[] realFiltered;
1110 void ophGen::freqShift(Complex<Real>* src, Complex<Real>* dst,
const ivec2 holosize,
int shift_x,
int shift_y)
1112 int N = holosize[
_X] * holosize[
_Y];
1114 Complex<Real>*
AS =
new Complex<Real>[N];
1119 Complex<Real>* shifted =
new Complex<Real>[N];
1120 circShift<Complex<Real>>(
AS, shifted, shift_x, shift_y, holosize.v[
_X], holosize.v[
_Y]);
1131 bool ophGen::saveRefImages(
char* fnameW,
char* fnameWC,
char* fnameAS,
char* fnameSSB,
char* fnameHP,
char* fnameFreq,
char* fnameReal,
char* fnameBin,
char* fnameReconBin,
char* fnameReconErr,
char* fnameReconNo)
1134 int nx = holosize[
_X], ny = holosize[
_Y];
1142 cout <<
"W saved" << endl;
1144 oph::absCplxArr<Real>(
weightC, temp1, ss);
1147 cout <<
"WC saved" << endl;
1149 oph::absCplxArr<Real>(
AS, temp1, ss);
1152 cout <<
"AS saved" << endl;
1156 cout <<
"SSB saved" << endl;
1160 cout <<
"HP saved" << endl;
1162 oph::absCplxArr<Real>(
freqW, temp1, ss);
1165 cout <<
"Freq saved" << endl;
1169 cout <<
"Real saved" << endl;
1173 cout <<
"Bin saved" << endl;
1176 Complex<Real>* temp =
new Complex<Real>[ss];
1177 for (
int i = 0; i < ss; i++) {
1183 for (
int i = 0; i < ss; i++) {
1190 Complex<Real>* reconBin =
new Complex<Real>[ss];
1191 memset(reconBin, 0,
sizeof(Complex<Real>) * ss);
1194 oph::absCplxArr<Real>(reconBin, temp1, ss);
1195 for (
int i = 0; i < ss; i++) {
1196 temp1[i] = temp1[i] * temp1[i];
1199 saveAsImg(fnameReconBin, 8, temp2, nx, ny);
1200 cout <<
"recon bin saved" << endl;
1203 temp =
new Complex<Real>[ss];
1204 for (
int i = 0; i < ss; i++) {
1210 for (
int i = 0; i < ss; i++) {
1217 reconBin =
new Complex<Real>[ss];
1220 oph::absCplxArr<Real>(reconBin, temp1, ss);
1221 for (
int i = 0; i < ss; i++) {
1222 temp1[i] = temp1[i] * temp1[i];
1225 saveAsImg(fnameReconErr, 8, temp2, nx, ny);
1226 cout <<
"recon error saved" << endl;
1231 temp =
new Complex<Real>[ss];
1232 for (
int i = 0; i < ss; i++) {
1238 for (
int i = 0; i < ss; i++) {
1245 reconBin =
new Complex<Real>[ss];
1248 oph::absCplxArr<Real>(reconBin, temp1, ss);
1249 for (
int i = 0; i < ss; i++) {
1250 temp1[i] = temp1[i] * temp1[i];
1253 saveAsImg(fnameReconNo, 8, temp2, nx, ny);
1263 int ss = holosize[
_X] * holosize[
_Y];
1266 weightC =
new Complex<Real>[ss];
1269 memsetArr<Real>(
weight, 0.0, 0, ss - 1);
1274 AS =
new Complex<Real>[ss];
1280 for (
int i = 0; i < ss; i++) {
1289 Complex<Real>* filtered =
new Complex<Real>[ss];
1295 LOG(
"normalize finishied..\n");
1296 if (encoded ==
nullptr)
1297 encoded =
new Real[ss];
1300 LOG(
"shiftW finishied..\n");
1305 for (
int i = 0; i < ss; i++) {
1306 oph::absCplx<Real>(
freqW[i], absFW);
1307 if (((
Real)i / (
Real)holosize[
_X]) < ((
Real)holosize[
_Y] / 2.0) && absFW < 0.6)
1317 for (
int i = 0; i < ss; i++) {
1325 Complex<Real>* toBeBin =
new Complex<Real>[ss];
1326 for (
int i = 0; i < ss; i++) {
1330 int cx = (holosize[
_X] + 1) / 2, cy = (holosize[
_Y] + 1) / 2;
1332 for (
int iy = 0; iy < holosize[
_Y] - Nw[
_Y]; iy++) {
1333 for (
int ix = Nw[
_X]; ix < holosize[
_X] - Nw[
_X]; ix++) {
1335 ii = ix + iy*holosize[
_X];
1336 if (ix >= Nw[
_X] && ix < (holosize[
_X] - Nw[
_X]) && iy < (holosize[
_Y] - Nw[
_Y])) {
1338 if (toBeBin[ii][
_RE] > threshold)
1343 error = toBeBin[ii][
_RE] - encoded[ii];
1345 for (
int iwy = 0; iwy < Nw[
_Y] + 1; iwy++) {
1346 for (
int iwx = -Nw[
_X]; iwx < Nw[
_X] + 1; iwx++) {
1347 iii = (ix + iwx) + (iy + iwy)*holosize[
_X];
1348 jjj = (cx + iwx) + (cy + iwy)*holosize[
_X];
1350 toBeBin[iii] +=
weightC[jjj] * error;
1359 LOG(
"binary finishied..\n");
1368 int cx = (holosize[
_X] + 1) / 2;
1369 int cy = (holosize[
_Y] + 1) / 2;
1375 LOG(
"ERROR DIFFUSION : FLOYD_STEINBERG\n");
1376 weight[(cx + 1) + cy*holosize[
_X]] = 7.0 / 16.0;
1377 weight[(cx - 1) + (cy + 1)*holosize[
_X]] = 3.0 / 16.0;
1378 weight[(cx)+(cy + 1)*holosize[
_X]] = 5.0 / 16.0;
1379 weight[(cx + 1) + (cy + 1)*holosize[
_X]] = 1.0 / 16.0;
1380 Nw[
_X] = 1; Nw[
_Y] = 1;
1383 LOG(
"ERROR DIFFUSION : SINGLE_RIGHT\n");
1384 weight[(cx + 1) + cy*holosize[
_X]] = 1.0;
1385 Nw[
_X] = 1; Nw[
_Y] = 0;
1388 LOG(
"ERROR DIFFUSION : SINGLE_DOWN\n");
1389 weight[cx + (cy + 1)*holosize[
_X]] = 1.0;
1390 Nw[
_X] = 0; Nw[
_Y] = 1;
1393 LOG(
"<FAILED> WRONG PARAMETERS.\n");
1404 int ss = holosize[
_X] * holosize[
_Y];
1406 Complex<Real> term(0, 0);
1407 Complex<Real> temp(0, 0);
1409 for (
int i = 0; i < ss; i++) {
1411 x = i % holosize[
_X] - holosize[
_X] / 2; y = i / holosize[
_X] - holosize[
_Y];
1417 freqW =
new Complex<Real>[ss];
1421 for (
int i = 0; i < ss; i++) {
1434 #pragma omp parallel for firstprivate(threshold) 1436 for (
int i = 0; i < size; i++) {
1437 if (src[i][
_RE] > threshold)
1448 const int pnX2 = pnX << 1;
1449 const int pnY2 = pnY << 1;
1450 const long long int pnXY = pnX * pnY;
1451 const long long int size = pnXY << 2;
1453 Complex<Real>* in2x =
new Complex<Real>[size];
1454 Complex<Real> zero(0, 0);
1455 memset(in2x, 0,
sizeof(Complex<Real>) * size);
1458 int beginY = pnY >> 1;
1459 int beginX = pnX >> 1;
1460 int endY = pnY + beginY;
1461 int endX = pnX + beginX;
1463 for (
int idxnY = beginY; idxnY < endY; idxnY++) {
1464 for (
int idxnX = beginX; idxnX < endX; idxnX++) {
1465 in2x[idxnY * pnX2 + idxnX] = in[idxIn++];
1470 Complex<Real>* temp1 =
new Complex<Real>[size];
1479 for (
int idxFy = -pnY; idxFy < pnY; idxFy++) {
1480 for (
int idxFx = -pnX; idxFx < pnX; idxFx++) {
1487 Complex<Real>* prop =
new Complex<Real>[size];
1488 memsetArr<Complex<Real>>(prop, zero, 0, size - 1);
1492 Complex<Real>* temp2 =
new Complex<Real>[size];
1494 for (
int i = 0; i < size; i++) {
1496 prop[i][
_IM] = 2 *
M_PI * distance;
1497 prop[i][
_IM] *= sqrtPart;
1498 temp2[i] = temp1[i] * exp(prop[i]);
1501 Complex<Real>* temp3 =
new Complex<Real>[size];
1507 for (
int idxNy = pnY / 2; idxNy < pnY + (pnY / 2); idxNy++) {
1508 for (
int idxNx = pnX / 2; idxNx < pnX + (pnX / 2); idxNx++) {
1509 out[idxOut] = temp3[idxNy * pnX * 2 + idxNx];
1529 const int pnXY = pnX * pnY;
1531 const Real ssX = pnX * ppX * 2;
1532 const Real ssY = pnY * ppY * 2;
1533 const Real z = 2 *
M_PI * distance;
1534 const Real v = 1 / (lambda * lambda);
1535 const int hpnX = pnX / 2;
1536 const int hpnY = pnY / 2;
1537 const int pnX2 = pnX * 2;
1538 const int pnY2 = pnY * 2;
1540 Complex<Real>* temp =
new Complex<Real>[pnXY * 4];
1541 memset(temp, 0,
sizeof(Complex<Real>) * pnXY * 4);
1544 #pragma omp parallel for firstprivate(pnX, pnX2, hpnX, hpnY) 1546 for (
int i = 0; i < pnY; i++)
1549 int dst = pnX2 * (i + hpnY) + hpnX;
1550 memcpy(&temp[dst], &in[src],
sizeof(Complex<Real>) * pnX);
1556 #pragma omp parallel for firstprivate(ssX, ssY, z, v) 1558 for (
int j = 0; j < pnY2; j++)
1560 Real fy = (-pnY + j) / ssY;
1562 int iWidth = j * pnX2;
1563 for (
int i = 0; i < pnX2; i++)
1565 Real fx = (-pnX + i) / ssX;
1568 Real sqrtPart = sqrt(v - fxx - fyy);
1569 Complex<Real> prop(0, z * sqrtPart);
1570 temp[iWidth + i] *= prop.exp();
1577 #pragma omp parallel for firstprivate(pnX, pnX2, hpnX, hpnY) 1579 for (
int i = 0; i < pnY; i++)
1581 int src = pnX2 * (i + hpnY) + hpnX;
1583 memcpy(&out[dst], &temp[src],
sizeof(Complex<Real>) * pnX);
1591 if (x == 0.0 && y == 0.0)
return false;
1593 bool bAxisX = (x == 0.0) ? false :
true;
1594 bool bAxisY = (y == 0.0) ? false :
true;
1601 Real ppY2 = ppY * 2;
1602 Real ppX2 = ppX * 2;
1606 Real *waveRatio =
new Real[nChannel];
1608 Complex<Real> pi2(0.0, -2 *
M_PI);
1610 for (
uint i = 0; i < nChannel; i++) {
1613 Real ratioX = x * waveRatio[i];
1614 Real ratioY = y * waveRatio[i];
1617 #pragma omp parallel for firstprivate(ppX, ppY, ppX2, ppY2, ssX, ssY, pi2) 1619 for (
int y = 0; y < pnY; y++) {
1620 Complex<Real> yy(0, 0);
1622 Real startY = ssY + (ppY * y);
1623 Real shiftY = startY / ppY2 * ratioY;
1624 yy = (pi2 * shiftY).exp();
1626 int offset = y * pnX;
1628 for (
int x = 0; x < pnX; x++) {
1633 Real startX = ssX + (ppX * x);
1634 Real shiftX = startX / ppX2 * ratioX;
1635 Complex<Real> xx = (pi2 * shiftX).exp();
1650 const long long int pnXY = pnX * pnY;
1652 Real dfx = 1 / ppX / pnX;
1653 Real dfy = 1 / ppY / pnY;
1655 int beginX = -pnX >> 1;
1656 int endX = pnX >> 1;
1657 int beginY = pnY >> 1;
1658 int endY = -pnY >> 1;
1660 Real carryX = distance * tan(carryingAngleX);
1661 Real carryY = distance * tan(carryingAngleY);
1663 for (
uint ch = 0; ch < nChannel; ch++) {
1665 for (
int i = beginY; i > endY; i--)
1667 Real _carryY = carryY * i * dfy;
1669 for (
int j = beginX; j < endX; j++)
1672 Complex<Real> carrier(0, carryX * x + _carryY);
1687 const long long int pnXY = pnX * pnY;
1688 Real dfx = 1 / ppX / pnX;
1689 Real dfy = 1 / ppY / pnY;
1691 int beginX = -pnX >> 1;
1692 int endX = pnX >> 1;
1693 int beginY = pnY >> 1;
1694 int endY = -pnY >> 1;
1698 for (
int i = beginY; i > endY; i--)
1700 Real y = i * dfy * ppY * carryIdxY;
1702 for (
int j = beginX; j < endX; j++)
1704 Real x = j * dfx * ppX * carryIdxX;
1706 Complex<Real> carrier(0, pi2 * (x + y));
1707 dst[
k] = src[
k] * exp(carrier);
1717 LOG(
"Not found diffracted data.");
1724 int cropx1, cropx2, cropx, cropy1, cropy2, cropy;
1725 if (sig_location[1] == 0) {
1730 cropy = (int)floor(((
Real)pnY) / 2);
1731 cropy1 = cropy - (int)floor(((
Real)cropy) / 2);
1732 cropy2 = cropy1 + cropy - 1;
1735 if (sig_location[0] == 0) {
1740 cropx = (int)floor(((
Real)pnX) / 2);
1741 cropx1 = cropx - (int)floor(((
Real)cropx) / 2);
1742 cropx2 = cropx1 + cropx - 1;
1760 const long long int pnXY = pnX * pnY;
1763 Complex<Real>* h_crop =
new Complex<Real>[pnXY];
1765 for (
uint ch = 0; ch < nChannel; ch++) {
1767 memset(h_crop, 0.0,
sizeof(Complex<Real>) * pnXY);
1769 #pragma omp parallel for firstprivate(cropx1, cropx2, cropy1, cropy2, pnX) 1771 for (
int p = 0; p < pnXY; p++)
1775 if (x >= cropx1 && x <= cropx2 && y >= cropy1 && y <= cropy2)
1779 Complex<Real> *in =
nullptr;
1786 #pragma omp parallel for firstprivate(sig_location) 1788 for (
int i = 0; i < pnXY; i++) {
1789 Complex<Real> shift_phase(1, 0);
1792 m_lpEncoded[ch][i] = (h_crop[i] * shift_phase).real();
1802 const long long int pnXY = pnX * pnY;
1809 cufftDoubleComplex *k_temp_d_, *u_complex_gpu_;
1810 cudaStream_t stream_;
1811 cudaStreamCreate(&stream_);
1813 cudaMalloc((
void**)&u_complex_gpu_,
sizeof(cufftDoubleComplex) * pnXY);
1814 cudaMalloc((
void**)&k_temp_d_,
sizeof(cufftDoubleComplex) * pnXY);
1816 for (
uint ch = 0; ch < nChannel; ch++) {
1817 cudaMemcpy(u_complex_gpu_,
complex_H[ch],
sizeof(cufftDoubleComplex) * pnXY, cudaMemcpyHostToDevice);
1819 cudaMemsetAsync(k_temp_d_, 0,
sizeof(cufftDoubleComplex) * pnXY, stream_);
1820 cudaCropFringe(stream_, pnX, pnY, u_complex_gpu_, k_temp_d_, cropx1, cropx2, cropy1, cropy2);
1822 cudaMemsetAsync(u_complex_gpu_, 0,
sizeof(cufftDoubleComplex) * pnXY, stream_);
1823 cudaFFT(stream_, pnX, pnY, k_temp_d_, u_complex_gpu_, 1,
true);
1825 cudaMemsetAsync(k_temp_d_, 0,
sizeof(cufftDoubleComplex) * pnXY, stream_);
1826 cudaGetFringe(stream_, pnX, pnY, u_complex_gpu_, k_temp_d_, sig_location[0], sig_location[1], ssX, ssY, ppX, ppY,
M_PI);
1828 cufftDoubleComplex* sample_fd = (cufftDoubleComplex*)malloc(
sizeof(cufftDoubleComplex) * pnXY);
1829 memset(sample_fd, 0.0,
sizeof(cufftDoubleComplex) * pnXY);
1831 cudaMemcpyAsync(sample_fd, k_temp_d_,
sizeof(cufftDoubleComplex) * pnXY, cudaMemcpyDeviceToHost, stream_);
1834 for (
int i = 0; i < pnX * pnY; i++)
1837 cudaFree(sample_fd);
1839 cudaStreamDestroy(stream_);
1851 if (sig_location[1] != 0)
1855 Real yy = (ssY / 2.0) - (ppY)*r - ppY;
1858 if (sig_location[1] == 1)
1859 val[
_IM] = 2 *
M_PI * (yy / (4 * ppY));
1861 val[
_IM] = 2 *
M_PI * (-yy / (4 * ppY));
1864 shift_phase_val *= val;
1867 if (sig_location[0] != 0)
1871 Real xx = (-ssX / 2.0) - (ppX)*c - ppX;
1874 if (sig_location[0] == -1)
1875 val[
_IM] = 2 *
M_PI * (-xx / (4 * ppX));
1877 val[
_IM] = 2 *
M_PI * (xx / (4 * ppX));
1880 shift_phase_val *= val;
1888 rand_phase_val[
_RE] = 0.0;
1890 #if REAL_IS_DOUBLE & true 1898 rand_phase_val.exp();
1902 rand_phase_val[
_RE] = 1.0;
1903 rand_phase_val[
_IM] = 0.0;
1917 template <
typename T>
1921 #pragma omp parallel for 1923 for (
int i = 0; i < size; i++) {
1924 encoded[i] = real(holo[i]);
1928 template <
typename T>
1932 #pragma omp parallel for 1934 for (
int i = 0; i < size; i++) {
1935 encoded[i] = imag(holo[i]);
1939 template <
typename T>
1942 double pi2 =
M_PI * 2;
1944 #pragma omp parallel for firstprivate(pi2) 1946 for (
int i = 0; i < size; i++) {
1947 encoded[i] = (holo[i].angle() +
M_PI) / pi2;
1951 template <
typename T>
1955 #pragma omp parallel for 1957 for (
int i = 0; i < size; i++) {
1958 encoded[i] = holo[i].mag();
1962 template <
typename T>
1965 int resize = size >> 1;
1966 Complex<T>* normCplx =
new Complex<T>[resize];
1969 #pragma omp parallel for 1971 for (
int i = 0; i < resize; i++) {
1972 normCplx[i] = holo[i * 2];
1975 oph::normalize<T>(normCplx, normCplx, resize);
1977 T* ampl =
new T[resize];
1980 T* phase =
new T[resize];
1981 Phase(normCplx, phase, resize);
1984 #pragma omp parallel for 1986 for (
int i = 0; i < resize; i++) {
1987 T delPhase = acos(ampl[i]);
1988 encoded[i * 2] = (phase[i] +
M_PI) + delPhase;
1989 encoded[i * 2 + 1] = (phase[i] +
M_PI) - delPhase;
1997 template <
typename T>
2000 int resize = size / 3;
2001 Complex<T>*
norm =
new Complex<T>[resize];
2003 #pragma omp parallel for 2005 for (
int i = 0; i < resize; i++) {
2006 norm[i] = holo[i * 3];
2011 T* phase =
new T[resize];
2014 T* ampl =
new T[resize];
2022 #pragma omp parallel for firstprivate(pi2, pi4, sqrt3) 2024 for (
int i = 0; i < resize; i++) {
2026 if (phase[i] >= 0 && phase[i] < (pi2 / 3))
2028 encoded[idx] = ampl[i] * (cos(phase[i]) + sin(phase[i]) / sqrt3);
2029 encoded[idx + 1] = 2 * sin(phase[i]) / sqrt3;
2031 else if (phase[i] >= (pi2 / 3) && phase[i] < (pi4 / 3))
2033 encoded[idx + 1] = ampl[i] * (cos(phase[i] - (pi2 / 3)) + sin(phase[i] - (pi2 / 3)) / sqrt3);
2034 encoded[idx + 2] = 2 * sin(phase[i] - (pi2 / 3)) / sqrt3;
2036 else if (phase[i] >= (pi4 / 3) && phase[i] < (pi2))
2038 encoded[idx + 2] = ampl[i] * (cos(phase[i] - (pi4 / 3)) + sin(phase[i] - (pi4 / 3)) / sqrt3);
2039 encoded[idx] = 2 * sin(phase[i] - (pi4 / 3)) / sqrt3;
2049 template <
typename T>
2052 T* tmp1 =
new T[size];
2054 #pragma omp parallel for 2056 for (
int i = 0; i < size; i++) {
2057 tmp1[i] = holo[i].mag();
2064 #pragma omp parallel for firstprivate(max) 2066 for (
int i = 0; i < size; i++) {
2067 T tmp = (holo[i] + max).mag();
2068 encoded[i] = tmp * tmp;
2075 for (
int i = 0; i < nVertex; i++)
2086 for (
int i = 0; i < nVertex; i++) {
2087 dst[i] = -fieldLens * src[i] / (src[i] - fieldLens);
2098 #pragma omp parallel for firstprivate(x, y, z) 2100 for (
int i = 0; i < nSize; i++) {
2101 dst[i + 0] = src[i + 0] * x;
2102 dst[i + 1] = src[i + 1] * y;
2103 dst[i + 2] = src[i + 2] * z;
2112 for (
int i = 0; i < len; i++) {
2113 if (src[i] > maxTmp)
2115 if (src[i] < minTmp)
2128 const int pnXY = width * height;
2132 int scaleX = round(width * 4 * waveRatio);
2133 int scaleY = round(height * 4 * waveRatio);
2136 int hh = height * 4;
2137 int nSize = ww * hh;
2138 int nScaleSize = scaleX * scaleY;
2143 memset(img_tmp, 0,
sizeof(
uchar) * nSize);
2145 int h1 = round((hh - scaleY) / 2);
2146 int w1 = round((ww - scaleX) / 2);
2148 #pragma omp parallel for firstprivate(w1, h1, scaleX, ww) 2150 for (
int y = 0; y < scaleY; y++) {
2151 for (
int x = 0; x < scaleX; x++) {
2152 img_tmp[(y + h1)*ww + x + w1] = imgScaled[y*scaleX + x];
2170 for (
uint i = 0; i < nChannel; i++) {
2181 for (
uint i = 0; i < nChannel; i++) {
bool loadPLY(const std::string &fileName, ulonglong &n_points, Vertex **vertices)
void abs(const oph::Complex< T > &src, oph::Complex< T > &dst)
void Phase(Complex< T > *holo, T *encoded, const int size)
void RS_Diffraction(Point src, Complex< Real > *dst, Real lambda, Real distance, Real amplitude)
RS-diffraction method.
virtual bool saveAsImg(const char *fname, uint8_t bitsperpixel, uchar *src, int width, int height)
Function for creating image files.
void setResolution(ivec2 resolution)
Function for setting buffer size.
void cudaFFT(CUstream_st *stream, int nx, int ny, cufftDoubleComplex *in_filed, cufftDoubleComplex *output_field, int direction, bool bNormailized=false)
Convert data from the spatial domain to the frequency domain using 2D FFT on GPU. ...
void conv_fft2(Complex< Real > *src1, Complex< Real > *src2, Complex< Real > *dst, ivec2 size)
Convolution between Complex arrays which have same size.
void GetMaxMin(Real *src, int len, Real &max, Real &min)
Complex< Real > * normalized
bool getWeightED(const ivec2 holosize, const int type, ivec2 *pNw)
void AngularSpectrumMethod(Complex< Real > *src, Complex< Real > *dst, Real lambda, Real distance)
Angular spectrum propagation method.
void encodeSideBand_CPU(int cropx1, int cropx2, int cropy1, int cropy2, ivec2 sig_location)
Encode the CGH according to a signal location parameter on the CPU.
void binarization(Complex< Real > *src, Real *dst, const int size, int ENCODE_FLAG, Real threshold)
void GetRandomPhaseValue(Complex< Real > &rand_phase_val, bool rand_phase)
Assign random phase value if random_phase == 1.
ulonglong n_points
Number of points.
void setPixelNumberOHC(const ivec2 pixel_number)
getter/setter for OHC file read and write
long long int double_size
void initialize(void)
Initialize variables for Hologram complex field, encoded data, normalized data.
void RealPart(Complex< T > *holo, T *encoded, const int size)
Encoding method.
void setPixelPitchOHC(const vec2 pixel_pitch)
bool shiftW(ivec2 holosize)
void TwoPhase(Complex< T > *holo, T *encoded, const int size)
bool checkExtension(const char *fname, const char *ext)
Functions for extension checking.
structure for 2-dimensional integer vector and its arithmetic.
const XMLNode * FirstChild() const
Get the first child node, or null if none exists.
void normalize(const Complex< T > *src, Complex< T > *dst, const int &size)
Normalize all elements of Complex<T>* src from 0 to 1.
void Burckhardt(Complex< T > *holo, T *encoded, const int size)
void setWavelengthOHC(const Real wavelength, const LenUnit wavelength_unit)
void ImaginaryPart(Complex< T > *holo, T *encoded, const int size)
void encodeSideBand(bool bCPU, ivec2 sig_location)
Encode the CGH according to a signal location parameter.
bool Shift(Real x, Real y)
void normalize(void)
Normalization function to save as image file after hologram creation.
bool binaryErrorDiffusion(Complex< Real > *holo, Real *encoded, const ivec2 holosize, const int type, Real threshold)
bool save(const char *fname, uint8_t bitsperpixel=8, uchar *src=nullptr, uint px=0, uint py=0)
Function for saving image files.
ivec2 m_vecEncodeSize
Encoded hologram size, varied from encoding type.
void singleSideBand(Complex< Real > *holo, Real *encoded, const ivec2 holosize, int passband)
Encoding method.
void cudaGetFringe(CUstream_st *stream, int pnx, int pny, cufftDoubleComplex *in_field, cufftDoubleComplex *out_field, int sig_locationx, int sig_locationy, Real ssx, Real ssy, Real ppx, Real ppy, Real PI)
Encode the CGH according to a signal location parameter on the GPU.
void encodeSideBand_GPU(int cropx1, int cropx2, int cropy1, int cropy2, ivec2 sig_location)
Encode the CGH according to a signal location parameter on the GPU.
void getShiftPhaseValue(Complex< Real > &shift_phase_val, int idx, ivec2 sig_location)
Calculate the shift phase value.
void imgScaleBilinear(uchar *src, uchar *dst, int w, int h, int neww, int newh, int channels=1)
Function for change image size.
void * load(const char *fname)
Function for loading image files.
Real ** m_lpEncoded
buffer to encoded.
void SimpleNI(Complex< T > *holo, T *encoded, const int size)
void CorrectionChromaticAberration(uchar *src, uchar *dst, int width, int height, int ch)
void waveCarry(Real carryingAngleX, Real carryingAngleY, Real distance)
Wave carry.
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 fresnelPropagation(OphConfig context, Complex< Real > *in, Complex< Real > *out, Real distance)
Fresnel propagation.
void Fresnel_FFT(Complex< Real > *src, Complex< Real > *dst, Real lambda, Real waveRatio, Real distance)
Fresnel-fft method.
void Amplitude(Complex< T > *holo, T *encoded, const int size)
Complex< Real > * weightC
SSB_PASSBAND
Passband in Single-side band encoding.
void cudaCropFringe(CUstream_st *stream, int nx, int ny, cufftDoubleComplex *in_field, cufftDoubleComplex *out_field, int cropx1, int cropx2, int cropy1, int cropy2)
Crop input data according to x, y coordinates on GPU.
bool saveRefImages(char *fnameW, char *fnameWC, char *fnameAS, char *fnameSSB, char *fnameHP, char *fnameFreq, char *fnameReal, char *fnameBin, char *fnameReconBin, char *fnameReconErr, char *fnameReconNo)
virtual bool loadAsOhc(const char *fname)
Function to read OHC file.
bool readConfig(const char *fname)
load to configuration file.
XMLError LoadFile(const char *filename)
virtual uchar * loadAsImg(const char *fname)
Function for loading image files.
Real rand(const Real min, const Real max, oph::ulong _SEED_VALUE=0)
Get random Real value from min to max.
void getAmplitude(oph::Complex< Real > *src, Real *dst, const int &size)
void ScaleChange(Real *src, Real *dst, int nSize, Real scaleX, Real scaleY, Real scaleZ)
Vertex * vertices
Data of point clouds.
Complex< Real > ** complex_H
Real minOfArr(const std::vector< Real > &arr)
Complex< Real > * AS
Binary Encoding - Error diffusion.
Real maxOfArr(const std::vector< Real > &arr)
uchar ** m_lpNormalized
buffer to normalized.
void resetBuffer()
reset buffer
void setPixelNumber(ivec2 n)
Function for setting the output resolution.
#define ELAPSED_TIME(x, y)
ImgEncoderOhc * OHC_encoder
OHC file format Variables for read and write.
void Fresnel_Diffraction(Point src, Complex< Real > *dst, Real lambda, Real distance, Real amplitude)
Fresnel-diffraction method.
virtual bool loadAsOhc(const char *fname)
Function to read OHC file.
void transVW(int nVertex, Vertex *dst, Vertex *src)
int ENCODE_METHOD
Encoding method flag.
void freqShift(Complex< Real > *holo, Complex< Real > *encoded, const ivec2 holosize, int shift_x, int shift_y)
Frequency shift.
int loadPointCloud(const char *pc_file, OphPointCloudData *pc_data_)
load to point cloud data.
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.
virtual void ophFree(void)
Pure virtual function for override in child classes.
virtual ~ophGen(void)=0
Destructor.