64 img_src_gpu =
nullptr;
65 dimg_src_gpu =
nullptr;
66 depth_index_gpu =
nullptr;
73 depth_index =
nullptr;
79 LOG(
"*** DEPTH MAP : BUILD DATE: %s %s ***\n\n", __DATE__, __TIME__);
88 this->is_ViewingWindow = is_ViewingWindow;
105 LOG(
"<FAILED> Wrong file ext.\n");
111 LOG(
"<FAILED> Loading file.\n");
118 char szNodeName[32] = { 0, };
119 sprintf(szNodeName,
"FlagChangeDepthQuantization");
121 if (!next ||
XML_SUCCESS != next->QueryBoolText(&dm_config_.change_depth_quantization))
123 LOG(
"<FAILED> Not found node : \'%s\' (Boolean) \n", szNodeName);
126 sprintf(szNodeName,
"DefaultDepthQuantization");
128 if (!next ||
XML_SUCCESS != next->QueryUnsignedText(&dm_config_.default_depth_quantization))
130 LOG(
"<FAILED> Not found node : \'%s\' (Unsinged Integer) \n", szNodeName);
133 sprintf(szNodeName,
"NumberOfDepthQuantization");
135 if (!next ||
XML_SUCCESS != next->QueryUnsignedText(&dm_config_.num_of_depth_quantization))
137 LOG(
"<FAILED> Not found node : \'%s\' (Unsinged Integer) \n", szNodeName);
141 if (dm_config_.change_depth_quantization == 0)
142 dm_config_.num_of_depth = dm_config_.default_depth_quantization;
144 dm_config_.num_of_depth = dm_config_.num_of_depth_quantization;
147 sprintf(szNodeName,
"RenderDepth");
149 if (!next ||
XML_SUCCESS != next->QueryBoolText(&dm_config_.change_depth_quantization))
151 LOG(
"<FAILED> Not found node : \'%s\' (Boolean) \n", szNodeName);
157 size_t found = render_depth.find(
':');
158 if (found != string::npos)
160 string s = render_depth.substr(0, found);
161 string e = render_depth.substr(found + 1);
164 dm_config_.render_depth.clear();
165 for (
int k = start; k <= end; k++)
166 dm_config_.render_depth.push_back(k);
170 stringstream ss(render_depth);
174 dm_config_.render_depth.push_back(render);
177 if (dm_config_.render_depth.empty()) {
178 LOG(
"<FAILED> Not found node : \'%s\' (String) \n", szNodeName);
182 sprintf(szNodeName,
"RandomPhase");
184 if (!next ||
XML_SUCCESS != next->QueryBoolText(&dm_config_.random_phase))
186 LOG(
"<FAILED> Not found node : \'%s\' (Boolean) \n", szNodeName);
189 sprintf(szNodeName,
"FieldLength");
191 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&dm_config_.fieldLength))
193 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
196 sprintf(szNodeName,
"NearOfDepth");
198 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&dm_config_.near_depthmap))
200 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
203 sprintf(szNodeName,
"FarOfDepth");
205 if (!next ||
XML_SUCCESS != next->QueryDoubleText(&dm_config_.far_depthmap))
207 LOG(
"<FAILED> Not found node : \'%s\' (Double) \n", szNodeName);
213 LOG(
"**************************************************\n");
214 LOG(
" Read Config (Depth Map) \n");
215 LOG(
"1) Focal Length : %.5lf ~ %.5lf\n", dm_config_.near_depthmap, dm_config_.far_depthmap);
216 LOG(
"2) Render Depth : %d:%d\n", dm_config_.render_depth[0], dm_config_.render_depth[dm_config_.render_depth.size() - 1]);
217 LOG(
"3) Number of Depth Quantization : %d\n", dm_config_.num_of_depth_quantization);
218 LOG(
"**************************************************\n");
228 const int N = pnX * pnY;
237 if (pSrc ==
nullptr) {
238 LOG(
"<FAILED> Load image: %s\n", fname);
242 if (type == IMAGE_TYPE::COLOR)
244 for (vector<uchar*>::iterator it = m_vecRGB.begin(); it != m_vecRGB.end(); it++)
251 for (
int i = 0; i < ch; i++)
259 memcpy(pBuf, pSrc, nSize);
266 LOG(
"<FAILED> separateColor: %d", i);
271 memcpy(pBuf, pSrc, nSize);
276 if (
w != pnX ||
h != pnY)
282 memcpy(pDst, pBuf, N);
284 m_vecRGB.push_back(pDst);
290 m_vecRGBImg[
_X] = pnX;
291 m_vecRGBImg[
_Y] = pnY;
293 else if (type == IMAGE_TYPE::DEPTH)
295 if (depth_img)
delete[] depth_img;
297 depth_img =
new uchar[N];
298 memset(depth_img, 0, N);
303 if (
w != pnX ||
h != pnY)
306 memcpy(depth_img, pBuf, N);
311 m_vecDepthImg[
_X] = pnX;
312 m_vecDepthImg[
_Y] = pnY;
314 LOG(
"Load Image(%s)\n Path: %d\nResolution: %dx%d\nBytePerPixel: %d",
315 type == IMAGE_TYPE::COLOR ?
"Color" :
"Depth", fname,
w,
h,
bytesperpixel);
320 bool ophDepthMap::convertImage()
325 const int N = pnX * pnY;
329 for (
int i = 0; i < ch; i++)
331 uchar* pSrc = m_vecRGB[i];
334 int nOldSize = ((m_vecRGBImg[
_X] + 3) & ~3) * m_vecRGBImg[
_Y];
335 int nNewSize = ((pnX + 3) & ~3) * pnY;
338 memcpy(pOrg, pSrc,
sizeof(
uchar) * nOldSize);
341 m_vecRGB[i] =
new uchar[nNewSize];
344 LOG(
"Resized Image: (%dx%d) to (%dx%d)", m_vecRGBImg[
_X], m_vecRGBImg[
_Y], pnX, pnY);
348 uchar* pSrc = depth_img;
351 int nOldSize = ((m_vecDepthImg[
_X] + 3) & ~3) * m_vecDepthImg[
_Y];
352 int nNewSize = ((pnX + 3) & ~3) * pnY;
355 memcpy(pOrg, pSrc,
sizeof(
uchar) * nOldSize);
358 depth_img =
new uchar[nNewSize];
361 LOG(
"Resized Image: (%dx%d) to (%dx%d)", m_vecDepthImg[
_X], m_vecDepthImg[
_Y], pnX, pnY);
374 const int N = pnX * pnY;
376 for (
size_t i = 0; i < m_vecRGB.size(); i++)
378 delete[] m_vecRGB[i];
383 char imgPath[FILENAME_MAX] = { 0, };
385 sprintf(imgPath,
"%s\\%s.bmp", source_folder, img_name);
387 sprintf(imgPath,
"%s/%s.bmp", source_folder, img_name);
397 LOG(
"<FAILED> Image Load: %s\n", imgPath);
401 LOG(
" <SUCCEEDED> Image Load: %s\n", imgPath);
406 for (
int i = 0; i < ch; i++)
416 memcpy(img, buf,
sizeof(
char) *
w *
h);
422 memset(rgb_img, 0,
sizeof(
char) * N);
424 if (
w != pnX ||
h != pnY)
427 memcpy(rgb_img, img,
sizeof(
char) * N);
429 m_vecRGB.push_back(rgb_img);
435 m_vecRGBImg[
_X] = pnX;
436 m_vecRGBImg[
_Y] = pnY;
440 char dimgPath[FILENAME_MAX] = { 0, };
442 sprintf(dimgPath,
"%s\\%s.bmp", source_folder, depth_img_name);
444 sprintf(dimgPath,
"%s/%s.bmp", source_folder, depth_img_name);
452 LOG(
"<FAILED> Image Load: %s\n", dimgPath);
456 LOG(
" <SUCCEEDED> Image Load: %s\n", dimgPath);
459 m_vecDepthImg[
_X] =
w;
460 m_vecDepthImg[
_Y] =
h;
467 if (depth_img)
delete[] depth_img;
469 depth_img =
new uchar[N];
470 memset(depth_img, 0,
sizeof(
char) * N);
472 if (
w != pnX ||
h != pnY)
475 memcpy(depth_img, dimg,
sizeof(
char) * N);
478 m_vecDepthImg[
_X] = pnX;
479 m_vecDepthImg[
_Y] = pnY;
490 LOG(
"**************************************************\n");
491 LOG(
" Generate Hologram \n");
492 LOG(
"1) Algorithm Method : Depth Map\n");
501 LOG(
"**************************************************\n");
510 prepareInputdataGPU();
519 prepareInputdataCPU();
526 LOG(
"Total Elapsed Time: %lf (s)\n", elapsed_time);
537 for (
uint ch = 0; ch < nChannel; ch++) {
551 for (
uint ch = 0; ch < nChannel; ch++) {
566 LOG(
"Elapsed Time: %lf(s)\n",
ELAPSED_TIME(begin, end));
570 void ophDepthMap::getDepthValues()
579 dlevel.push_back(val);
594 changeDepthQuanCPU();
596 changeDepthQuanGPU();
601 void ophDepthMap::transVW()
604 dlevel_transform.clear();
605 for (
size_t p = 0; p < dlevel.size(); p++)
608 dlevel_transform.push_back(val);
612 void ophDepthMap::initCPU()
616 const uint N = pnX * pnY;
621 for (vector<Real *>::iterator it = m_vecImgSrc.begin(); it != m_vecImgSrc.end(); it++)
626 for (vector<int *>::iterator it = m_vecAlphaMap.begin(); it != m_vecAlphaMap.end(); it++)
630 m_vecAlphaMap.clear();
632 for (
uint ch = 0; ch < nChannel; ch++)
635 int *alpha_map =
new int[N];
637 m_vecImgSrc.push_back(img_src);
638 m_vecAlphaMap.push_back(alpha_map);
641 if (dmap_src)
delete[] dmap_src;
642 dmap_src =
new Real[N];
644 if (depth_index)
delete[] depth_index;
645 depth_index =
new uint[N];
647 if (dmap)
delete[] dmap;
653 bool ophDepthMap::prepareInputdataCPU()
659 memset(depth_index, 0,
sizeof(
uint) * N);
661 if (depth_img ==
nullptr)
663 depth_img =
new uchar[N];
664 memset(depth_img, 0, N);
670 for (
uint ch = 0; ch < nChannel; ch++)
673 #pragma omp parallel for firstprivate(gapDepth, nearDepth) 675 for (
long long int k = 0; k < N; k++)
677 m_vecImgSrc[ch][k] =
Real(m_vecRGB[ch][k]) / 255.0;
678 m_vecAlphaMap[ch][k] = (m_vecRGB[ch][k] > 0 ? 1 : 0);
683 dmap_src[k] =
Real(depth_img[k]) / 255.0;
684 dmap[k] = (1 - dmap_src[k]) * gapDepth + nearDepth;
696 void ophDepthMap::changeDepthQuanCPU()
705 double nearv = dlevel[0];
706 double half_step = dstep / 2.0;
708 depth_fill.resize(dm_config_.
render_depth.size() + 1, 0);
709 Real locDstep = dstep;
712 #pragma omp parallel for firstprivate(nearv, half_step, locDstep) 714 for (
long long int i = 0; i < N; i++)
716 int idx = int(((dmap[i] - nearv) + half_step) / locDstep);
717 depth_index[i] = idx + 1;
718 depth_fill[idx + 1] = 1;
724 void ophDepthMap::calcHoloCPU()
730 const long long int N = pnX * pnY;
740 for (
uint ch = 0; ch < nChannel; ch++)
744 Real *img_src = m_vecImgSrc[ch];
745 int *alpha_map = m_vecAlphaMap[ch];
747 for (
size_t i = 0; i < depth_sz; i++)
753 Real temp_depth = (is_ViewingWindow) ? dlevel_transform[dtr - 1] : dlevel[dtr - 1];
759 carrier_phase_delay.exp();
761 #pragma omp parallel for firstprivate(dtr, rand_phase_val, carrier_phase_delay) 763 for (
long long int j = 0; j < N; j++)
765 input[j][
_RE] = img_src[j] * alpha_map[j] * ((int)depth_index[j] == dtr ? 1.0 : 0.0);
766 input[j] *= rand_phase_val * carrier_phase_delay;
773 m_nProgress = (int)((
Real)(ch * depth_sz + i) * 100 / (depth_sz * nChannel));
791 for (vector<uchar *>::iterator it = m_vecRGB.begin(); it != m_vecRGB.end(); it++)
void encodeSideBand(unsigned int passband)
Encode the CGH according to a passband parameter.
void setViewingWindow(bool is_ViewingWindow)
Set the value of a variable is_ViewingWindow(true or false)
void setResolution(ivec2 resolution)
Function for setting buffer size.
void fftFree(void)
Resource release method.
Real fieldLength
fieldLength variable for viewing window.
void AngularSpectrumMethod(Complex< Real > *src, Complex< Real > *dst, Real lambda, Real distance)
Angular spectrum propagation method.
void GetRandomPhaseValue(Complex< Real > &rand_phase_val, bool rand_phase)
Assign random phase value if random_phase == 1.
bool readImageDepth(const char *source_folder, const char *img_prefix, const char *depth_img_prefix)
Read image and depth map.
Real ** m_lpEncoded
buffer to encoded.
void initialize(void)
Initialize variables for Hologram complex field, encoded data, normalized data.
bool checkExtension(const char *fname, const char *ext)
Functions for extension checking.
structure for 2-dimensional integer vector and its arithmetic.
bool GetRandomPhase()
Function for getting the random phase.
const XMLNode * FirstChild() const
Get the first child node, or null if none exists.
ophDepthMap()
Constructor.
virtual ~ophDepthMap()
Destructor.
void normalize(void)
Normalization function to save as image file after hologram creation.
ivec2 m_vecEncodeSize
Encoded hologram size, varied from encoding type.
Real near_depthmap
near value of depth in object
bool readConfig(const char *fname)
Read parameters from a config file. (*.xml)
bool separateColor(int idx, int width, int height, uchar *src, uchar *dst)
Function for generate each grayscale image from RGB image.
void imgScaleBilinear(uchar *src, uchar *dst, int w, int h, int neww, int newh, int channels=1)
Function for change image size.
bool getImgSize(int &w, int &h, int &bytesperpixel, const char *fname)
Function for getting the image size.
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 convertToFormatGray8(uchar *src, uchar *dst, int w, int h, int bytesperpixel)
Function for convert image format to gray8.
Real far_depthmap
far value of depth in object
void setResolution(ivec2 resolution)
#define ELAPSED_TIME(x, y)
void fftInit2D(ivec2 size, int sign, unsigned int flag)
initialize method for 2D FFT
bool readConfig(const char *fname)
load to configuration file.
XMLError LoadFile(const char *filename)
void ophFree(void)
Pure virtual function for override in child classes.
virtual uchar * loadAsImg(const char *fname)
Function for loading image files.
bool change_depth_quantization
if true, change the depth quantization from the default value.
Real generateHologram(void)
Generate a hologram, main funtion. When the calculation is finished, the angular spectrum is performe...
void resetBuffer()
reset buffer
bool readImage(const char *fname, IMAGE_TYPE type=COLOR)
Read image and depth map.
Complex< Real > ** complex_H
vector< int > render_depth
Used when only few specific depth levels are rendered, usually for test purpose.
uint default_depth_quantization
default value of the depth quantization - 256
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
virtual void ophFree(void)
Pure virtual function for override in child classes.