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);
538 for (
uint ch = 0; ch < nChannel; ch++) {
545 for (
uint ch = 0; ch < nChannel; ch++)
559 for (
uint ch = 0; ch < nChannel; ch++) {
565 location =
ivec2(0, 1);
568 location =
ivec2(0, -1);
571 location =
ivec2(-1, 0);
574 location =
ivec2(1, 0);
590 LOG(
"Elapsed Time: %lf(s)\n",
ELAPSED_TIME(begin, end));
594 void ophDepthMap::getDepthValues()
603 dlevel.push_back(val);
618 changeDepthQuanCPU();
620 changeDepthQuanGPU();
625 void ophDepthMap::transVW()
628 dlevel_transform.clear();
629 for (
size_t p = 0; p < dlevel.size(); p++)
632 dlevel_transform.push_back(val);
636 void ophDepthMap::initCPU()
640 const uint N = pnX * pnY;
645 for (vector<Real *>::iterator it = m_vecImgSrc.begin(); it != m_vecImgSrc.end(); it++)
650 for (vector<int *>::iterator it = m_vecAlphaMap.begin(); it != m_vecAlphaMap.end(); it++)
654 m_vecAlphaMap.clear();
656 for (
uint ch = 0; ch < nChannel; ch++)
659 int *alpha_map =
new int[N];
661 m_vecImgSrc.push_back(img_src);
662 m_vecAlphaMap.push_back(alpha_map);
665 if (dmap_src)
delete[] dmap_src;
666 dmap_src =
new Real[N];
668 if (depth_index)
delete[] depth_index;
669 depth_index =
new uint[N];
671 if (dmap)
delete[] dmap;
677 bool ophDepthMap::prepareInputdataCPU()
683 memset(depth_index, 0,
sizeof(
uint) * N);
685 if (depth_img ==
nullptr)
687 depth_img =
new uchar[N];
688 memset(depth_img, 0, N);
694 for (
uint ch = 0; ch < nChannel; ch++)
697 #pragma omp parallel for firstprivate(gapDepth, nearDepth) 699 for (
long long int k = 0;
k < N;
k++)
701 m_vecImgSrc[ch][
k] =
Real(m_vecRGB[ch][
k]) / 255.0;
702 m_vecAlphaMap[ch][
k] = (m_vecRGB[ch][
k] > 0 ? 1 : 0);
707 dmap_src[
k] =
Real(depth_img[
k]) / 255.0;
708 dmap[
k] = (1 - dmap_src[
k]) * gapDepth + nearDepth;
720 void ophDepthMap::changeDepthQuanCPU()
729 double nearv = dlevel[0];
730 double half_step = dstep / 2.0;
732 depth_fill.resize(dm_config_.
render_depth.size() + 1, 0);
733 Real locDstep = dstep;
736 #pragma omp parallel for firstprivate(nearv, half_step, locDstep) 738 for (
long long int i = 0; i < N; i++)
740 int idx = int(((dmap[i] - nearv) + half_step) / locDstep);
741 depth_index[i] = idx + 1;
742 depth_fill[idx + 1] = 1;
748 void ophDepthMap::calcHoloCPU()
754 const long long int N = pnX * pnY;
764 for (
uint ch = 0; ch < nChannel; ch++)
768 Real *img_src = m_vecImgSrc[ch];
769 int *alpha_map = m_vecAlphaMap[ch];
771 for (
size_t i = 0; i < depth_sz; i++)
777 Real temp_depth = (is_ViewingWindow) ? dlevel_transform[dtr - 1] : dlevel[dtr - 1];
783 carrier_phase_delay.exp();
785 #pragma omp parallel for firstprivate(dtr, rand_phase_val, carrier_phase_delay) 787 for (
long long int j = 0; j < N; j++)
789 input[j][
_RE] = img_src[j] * alpha_map[j] * ((int)depth_index[j] == dtr ? 1.0 : 0.0);
790 input[j] *= rand_phase_val * carrier_phase_delay;
797 m_nProgress = (int)((
Real)(ch * depth_sz + i) * 100 / (depth_sz * nChannel));
815 for (vector<uchar *>::iterator it = m_vecRGB.begin(); it != m_vecRGB.end(); it++)
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.
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 encodeSideBand(bool bCPU, ivec2 sig_location)
Encode the CGH according to a signal location parameter.
vector< int > render_depth
Used when only few specific depth levels are rendered, usually for test purpose.
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.
Real ** m_lpEncoded
buffer to encoded.
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)
void fftInit2D(ivec2 size, int sign, unsigned int flag)
initialize method for 2D FFT
SSB_PASSBAND
Passband in Single-side band encoding.
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.
Complex< Real > ** complex_H
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
#define ELAPSED_TIME(x, y)
bool readImage(const char *fname, IMAGE_TYPE type=COLOR)
Read image and depth map.
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.