16 , m_pHologram(nullptr)
42 LOG(
"<FAILED> Wrong file ext.\n");
48 LOG(
"<FAILED> Loading file.\n");
54 char szNodeName[32] = { 0, };
55 sprintf(szNodeName,
"ScaleX");
58 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&pc_config_.scale[
_X]))
60 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
63 sprintf(szNodeName,
"ScaleY");
65 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&pc_config_.scale[
_Y]))
67 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
70 sprintf(szNodeName,
"ScaleZ");
72 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&pc_config_.scale[
_Z]))
74 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
77 sprintf(szNodeName,
"Distance");
79 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&pc_config_.distance))
81 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
86 sprintf(szNodeName,
"CGH Width");
88 if (!next ||
XML_SUCCESS != next->QueryIntText(&env.CghWidth))
90 LOG(
"<FAILED> Not found node : \'%s\' (Integer) \n", szNodeName);
93 sprintf(szNodeName,
"CGH Height");
95 if (!next ||
XML_SUCCESS != next->QueryIntText(&env.CghHeight))
97 LOG(
"<FAILED> Not found node : \'%s\' (Integer) \n", szNodeName);
100 sprintf(szNodeName,
"CGH Scale");
102 if (!next ||
XML_SUCCESS != next->QueryFloatText(&env.CGHScale))
104 LOG(
"<FAILED> Not found node : \'%s\' (Float) \n", szNodeName);
107 sprintf(szNodeName,
"Segmentation Size");
109 if (!next ||
XML_SUCCESS != next->QueryIntText(&env.SegmentationSize))
111 LOG(
"<FAILED> Not found node : \'%s\' (Integer) \n", szNodeName);
114 sprintf(szNodeName,
"FFT Segmentation Size");
116 if (!next ||
XML_SUCCESS != next->QueryIntText(&env.fftSegmentationSize))
118 LOG(
"<FAILED> Not found node : \'%s\' (Integer) \n", szNodeName);
121 sprintf(szNodeName,
"Red WaveLength");
123 if (!next ||
XML_SUCCESS != next->QueryFloatText(&env.rWaveLength))
125 LOG(
"<FAILED> Not found node : \'%s\' (Float) \n", szNodeName);
129 sprintf(szNodeName,
"Tilting angle on x axis");
131 if (!next ||
XML_SUCCESS != next->QueryFloatText(&env.ThetaX))
133 LOG(
"<FAILED> Not found node : \'%s\' (Float) \n", szNodeName);
136 sprintf(szNodeName,
"Tilting angle on y axis");
138 if (!next ||
XML_SUCCESS != next->QueryFloatText(&env.ThetaY))
140 LOG(
"<FAILED> Not found node : \'%s\' (Float) \n", szNodeName);
143 sprintf(szNodeName,
"Default depth");
145 if (!next ||
XML_SUCCESS != next->QueryFloatText(&env.DefaultDepth))
147 LOG(
"<FAILED> Not found node : \'%s\' (Float) \n", szNodeName);
151 sprintf(szNodeName,
"3D point interval on x axis");
153 if (!next ||
XML_SUCCESS != next->QueryFloatText(&env.xInterval))
155 LOG(
"<FAILED> Not found node : \'%s\' (Float) \n", szNodeName);
158 sprintf(szNodeName,
"3D point interval on y axis");
160 if (!next ||
XML_SUCCESS != next->QueryFloatText(&env.yInterval))
162 LOG(
"<FAILED> Not found node : \'%s\' (Float) \n", szNodeName);
165 sprintf(szNodeName,
"Hologram interval on xi axis");
167 if (!next ||
XML_SUCCESS != next->QueryFloatText(&env.xiInterval))
169 LOG(
"<FAILED> Not found node : \'%s\' (Float) \n", szNodeName);
172 sprintf(szNodeName,
"Hologram interval on eta axis");
174 if (!next ||
XML_SUCCESS != next->QueryFloatText(&env.etaInterval))
176 LOG(
"<FAILED> Not found node : \'%s\' (Float) \n", szNodeName);
190 LOG(
"**************************************************\n");
191 LOG(
" Read Config (Accurate Phase-Added Stereogram) \n");
192 LOG(
"1) Focal Length : %.5lf\n", pc_config_.distance);
193 LOG(
"2) Object Scale : %.5lf / %.5lf / %.5lf\n", pc_config_.scale[
_X], pc_config_.scale[
_Y], pc_config_.scale[
_Z]);
194 LOG(
"**************************************************\n");
207 if (fname ==
nullptr)
return -1;
215 for (
uint ch = 0; ch < nChannel; ch++) {
218 if (px == 0 && py == 0)
224 char buf[256] = { 0, };
225 sprintf(buf,
"%s.bmp", fname);
240 for (
int i = 0; i <
NUMTBL; i++) {
241 float theta = (float)M2_PI * (
float)(i + i - 1) / (
float)(2 *
NUMTBL);
249 double Max = -1E9, Min = 1E9;
256 for (
int i = 0; i < cghheight; i++) {
257 for (
int j = 0; j < cghwidth; j++) {
263 for (
int i = 0; i < cghheight; i++) {
264 for (
int j = 0; j < cghwidth; j++) {
265 double temp = 1.0*(((
m_pHologram[i*cghwidth + j] - Min) / (Max - Min))*255. + 0.5);
266 if (temp >= 255.0) cghfringe[i*cghwidth + j] = 255;
267 else cghfringe[i*cghwidth + j] = (
unsigned char)(temp);
276 float xiInterval = env.xiInterval;
277 float etaInterval = env.etaInterval;
278 float rLamda = env.rWaveLength;
279 float rWaveNum = env.rWaveNumber;
280 float thetaX = env.ThetaX;
281 float thetaY = env.ThetaY;
283 int hsegSize = env.SegmentationSize >> 1;
284 int dsegSize = env.SegmentationSize * env.SegmentationSize;
285 int segNumx = (int)(env.CghWidth / env.SegmentationSize);
286 int segNumy = (int)(env.CghHeight/ env.SegmentationSize);
287 int hsegNumx = segNumx >> 1;
288 int hsegNumy = segNumy >> 1;
290 int FFThsegSize = env.fftSegmentationSize >> 1;
291 int FFTdsegSize = env.fftSegmentationSize * env.fftSegmentationSize;
293 float *SFrequency_cx =
new float[segNumx];
294 float *SFrequency_cy =
new float[segNumy];
295 int *PickPoint_cx =
new int[segNumx];
296 int *PickPoint_cy =
new int[segNumy];
297 int *Coefficient_cx =
new int[segNumx];
298 int *Coefficient_cy =
new int[segNumy];
299 float *dPhaseSFy =
new float[segNumx];
300 float *dPhaseSFx =
new float[segNumy];
301 float *xc =
new float[segNumx];
302 float *yc =
new float[segNumy];
303 float sf_base = 1.0 / (env.xiInterval * env.fftSegmentationSize);
305 float theta_s, theta_c;
306 int dtheta_s, dtheta_c;
308 double *Compensation_cx =
new double[segNumx];
309 double *Compensation_cy =
new double[segNumy];
313 fftw_complex *in, *out;
316 double **inRe =
new double *[segNumy * segNumx];
317 double **inIm =
new double *[segNumy * segNumx];
318 for (
int i = 0; i < segNumy; i++) {
319 for (
int j = 0; j < segNumx; j++) {
320 inRe[i * segNumx + j] =
new double[FFTdsegSize];
321 inIm[i * segNumx + j] =
new double[FFTdsegSize];
322 memset(inRe[i*segNumx + j], 0x00,
sizeof(
double) * FFTdsegSize);
323 memset(inIm[i*segNumx + j], 0x00,
sizeof(
double) * FFTdsegSize);
327 in = (fftw_complex *)fftw_malloc(
sizeof(fftw_complex) * FFTdsegSize);
328 out = (fftw_complex *)fftw_malloc(
sizeof(fftw_complex) * FFTdsegSize);
329 memset(in, 0x00,
sizeof(fftw_complex) * FFTdsegSize);
330 memset(
m_pHologram, 0x00,
sizeof(
double) * env.CghWidth * env.CghHeight);
332 for (
int i = 0; i < segNumy; i++)
333 yc[i] = ((i - hsegNumy) * env.SegmentationSize + hsegSize) * env.etaInterval;
334 for (
int i = 0; i < segNumx; i++)
335 xc[i] = (((i- hsegNumx) * env.SegmentationSize) + hsegSize) * env.xiInterval;
337 for (
int i = 0; i < pc_data_.
n_points; i++)
345 for (
int j = 0; j < segNumy; j++)
347 float theta_cy = (yc[j] - y) - z;
348 SFrequency_cy[j] = (theta_cy + thetaY) / env.rWaveLength;
349 PickPoint_cy[j] = (SFrequency_cy[j] >= 0 ) ? (int)(SFrequency_cy[j] / sf_base + 0.5) : (int)(SFrequency_cy[j] / sf_base - 0.5);
350 Coefficient_cy[j] = (
abs(PickPoint_cy[j]) < FFThsegSize) ? ((env.fftSegmentationSize - PickPoint_cy[j]) % env.fftSegmentationSize) : 0;
351 Compensation_cy[j] = (float)(2 * PI * ((yc[j] - y) * SFrequency_cy[j] + PickPoint_cy[j] * sf_base * FFThsegSize * xiInterval));
353 for (
int j = 0; j < segNumx; j++)
355 float theta_cx = (xc[j] - x) / z;
356 SFrequency_cx[j] = (theta_cx + thetaX) / env.rWaveLength;
357 PickPoint_cx[j] = (SFrequency_cx[j] >= 0) ? (int)(SFrequency_cx[j] / sf_base + 0.5) : (int)(SFrequency_cx[j] / sf_base - 0.5);
358 Coefficient_cx[j] = (
abs(PickPoint_cx[j]) < FFThsegSize) ? ((env.fftSegmentationSize - PickPoint_cx[j]) % env.fftSegmentationSize) : 0;
359 Compensation_cx[j] = (float)(2 * PI * ((xc[j] - x) * SFrequency_cx[j] + PickPoint_cx[j] * sf_base * FFThsegSize * etaInterval));
361 for (
int j = 0; j < segNumy; j++) {
362 for (
int k = 0; k < segNumx; k++) {
363 int idx = j* segNumx + k;
364 int idx2 = Coefficient_cy[j] * env.fftSegmentationSize + Coefficient_cx[k];
365 float R = sqrt((xc[k] - x) * (xc[k] - x) + (yc[j] - y) * (yc[j] - y) + z * z);
366 theta = rWaveNum * R + phase + Compensation_cy[j] + Compensation_cx[k];
369 theta_s = theta + PI;
370 dtheta_c = ((int)(theta_c *
NUMTBL / M2_PI));
371 dtheta_s = ((int)(theta_s *
NUMTBL / M2_PI));
372 idx_c = (dtheta_c) & (
NUMTBL2);
373 idx_s = (dtheta_s) & (
NUMTBL2);
374 inRe[idx][idx2] += (double)(amplitude *
m_COStbl[idx_c]);
375 inIm[idx][idx2] += (double)(amplitude *
m_SINtbl[idx_s]);
382 for (
int j = 0; j < segNumy; j++) {
383 for (
int k = 0; k < segNumx; k++) {
384 int idx = j * segNumx + k;
385 memset(in, 0x00,
sizeof(fftw_complex) * FFTdsegSize);
386 for (
int l = 0; l < env.fftSegmentationSize; l++) {
387 for (
int m = 0;
m < env.fftSegmentationSize;
m++) {
388 int idx2 = l * env.fftSegmentationSize +
m;
389 in[l * env.fftSegmentationSize +
m][0] = inRe[idx][idx2];
390 in[l * env.fftSegmentationSize +
m][1] = inIm[idx][idx2];
394 for (
int l = 0; l < env.SegmentationSize; l++) {
395 for (
int m = 0;
m < env.SegmentationSize;
m++) {
396 m_pHologram[(j * env.SegmentationSize + l) * env.CghWidth + (k * env.SegmentationSize +
m)] +=
397 out[(l + FFThsegSize - hsegSize) * env.fftSegmentationSize + (
m + FFThsegSize - hsegSize)][0];
403 fftw_destroy_plan(plan);
408 delete[] SFrequency_cx;
409 delete[] SFrequency_cy;
410 delete[] PickPoint_cx;
411 delete[] PickPoint_cy;
412 delete[] Coefficient_cx;
413 delete[] Coefficient_cy;
416 for (
int i = 0; i < segNumy; i++) {
417 for (
int j = 0; j < segNumx; j++) {
418 delete[] inRe[i * segNumx + j];
419 delete[] inIm[i * segNumx + j];
void abs(const oph::Complex< T > &src, oph::Complex< T > &dst)
OphConfig & getContext(void)
Function for getting the current context.
virtual bool saveAsImg(const char *fname, uint8_t bitsperpixel, uchar *src, int width, int height)
Function for creating image files.
Real distance
Offset value of point cloud.
int ACPASCalcuation(unsigned char *cghfringe)
bool readConfig(const char *fname)
int loadPointCloud(const char *pc_file)
ulonglong n_points
Number of points.
void setPixelNumberOHC(const ivec2 pixel_number)
getter/setter for OHC file read and write
void initialize(void)
Initialize variables for Hologram complex field, encoded data, normalized data.
void setPixelPitchOHC(const vec2 pixel_pitch)
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 setWavelengthOHC(const Real wavelength, const LenUnit wavelength_unit)
vec3 scale
Scaling factor of coordinate of point cloud.
int save(const char *fname, uint8_t bitsperpixel, uchar *src, uint px, uint py)
Vertex * vertices
Data of point clouds.
bool readConfig(const char *fname)
load to configuration file.
XMLError LoadFile(const char *filename)
uchar ** m_lpNormalized
buffer to normalized.
int loadPointCloud(const char *pc_file, OphPointCloudData *pc_data_)
load to point cloud data.
const XMLElement * FirstChildElement(const char *name=0) const