16 string fnamestr = fname;
17 int checktype =
static_cast<int>(fnamestr.rfind(
"."));
18 matrix<Real> phaseMat;
20 std::string filetype = fnamestr.substr(checktype + 1, fnamestr.size());
22 if (filetype ==
"bmp")
27 fphase = fopen(fnamestr.c_str(),
"rb");
30 LOG(
"real bmp file open fail!\n");
39 LOG(
"bmp header is empty!\n");
44 LOG(
"check your parameter file!\n");
49 LOG(
"image size is different!\n");
58 fread(palette,
sizeof(
rgbquad), 256, fphase);
64 LOG(
"currently only 8 bitpixel is supported.");
79 for (
int j = 0; j < static_cast<int>(
hInfo.
width); j++)
87 LOG(
"file load complete!\n");
91 else if (filetype ==
"bin")
96 ifstream fphase(fnamestr, ifstream::binary);
99 double *phasedata =
new double[total];
101 fphase.read(reinterpret_cast<char*>(phasedata),
sizeof(
double) * total);
107 phaseMat(row, col) = phasedata[
_cfgSig.
rows*col + row];
114 else if (bitpixel == 24)
116 LOG(
"currently only 8 bitpixel is supported.");
167 LOG(
"data nomalization complete\n");
181 matrix<Real> residue(
Nr,
Nc);
183 matrix<Real> branchcut(
Nr,
Nc);
191 auto during_time = ((std::chrono::duration<Real>)(end_time - start_time)).count();
193 LOG(
"Implement time : %.5lf sec\n", during_time);
203 string fnamestr = fname;
207 for (
int i = 0; i <
Nr; i++)
209 for (
int j = 0; j <
Nc; j++)
223 for (
int i = 0; i <
Nr; i++)
225 for (
int j = 0; j <
Nc; j++)
247 matrix<Real> below(
Nr,
Nc);
248 matrix<Real> right(
Nr,
Nc);
249 matrix<Real> belowright(
Nr,
Nc);
250 below.zeros(); right.zeros(); belowright.zeros();
252 for (
int i = 0; i <
Nr-1; i++)
254 for (
int j = 0; j <
Nc-1; j++)
261 for (
int i = 0; i <
Nr-1; i++)
265 for (
int j = 0; j <
Nc - 1; j++)
270 double res1, res2, res3, res4;
272 for (
int i = 0; i <
Nr; i++)
274 for (
int j = 0; j <
Nc; j++)
277 res2 =
mod2pi(below(i, j) - belowright(i,j));
278 res3 =
mod2pi(belowright(i, j) - right(i, j));
281 temp_residue = res1 + res2 + res3 + res4;
282 if (temp_residue >= 6.)
284 outputResidue(i, j) = 1;
286 else if (temp_residue <= -6.)
288 outputResidue(i, j) = -1;
292 outputResidue(i, j) = 0;
297 for (
int i = 0; i <
Nr; i++)
299 outputResidue(i, 0) = 0;
300 outputResidue(i,
Nc - 1) = 0;
302 for (
int j = 0; j <
Nc; j++)
304 outputResidue(0, j) = 0;
305 outputResidue(
Nr - 1, j) = 0;
316 int clusterCounter = 1;
317 int satelliteResidue = 0;
318 matrix<int> residueBinary(
Nr,
Nc);
319 for (
int i = 0; i <
Nr; i++)
321 for (
int j = 0; j <
Nc; j++)
323 if (inputResidue(i, j) != 0)
325 residueBinary(i, j) = 1;
329 residueBinary(i, j) = 0;
333 matrix<Real> residueBalanced(
Nr,
Nc);
334 residueBalanced.zeros();
335 matrix<int> adjacentResidue(
Nr,
Nc);
336 adjacentResidue.zeros();
337 int missedResidue = 0;
339 int adjacentResidueCount = 0;
341 for (
int i = 0; i <
Nr; i++)
343 for (
int j = 0; j <
Nc; j++)
345 if (residueBinary(i, j) == 1)
351 int countNearbyResidueFlag = 1;
353 adjacentResidue.zeros();
354 int chargeCounter = inputResidue(rActive, cActive);
355 if (residueBalanced(rActive, cActive) != 1)
357 while (chargeCounter != 0)
359 for (
int m = rActive - radius;
m < rActive + radius + 1;
m++)
361 for (
int n = cActive - radius; n < cActive + radius + 1; n++)
363 if (((
abs(m - rActive) == radius) | (
abs(n - cActive) == radius)) & (chargeCounter != 0))
365 if ((m < 1) | (m >=
Nr - 1) | (n < 1) | (m >=
Nc - 1))
367 if (m >=
Nr - 1) {
m =
Nr - 1; }
368 if (n >=
Nc - 1) { n =
Nc - 1; }
369 if (n < 1) { n = 0; }
370 if (m < 1) {
m = 0; }
374 residueBalanced(rActive, cActive) = 1;
376 if (residueBinary(m, n))
378 if (countNearbyResidueFlag == 1) { adjacentResidue(m, n) = 1; }
381 if (residueBalanced(m, n) == 0)
383 residueBalanced(m, n) = 1;
384 chargeCounter += inputResidue(m, n);
386 if (chargeCounter == 0) { residueBalanced(rActive, cActive) = 1; }
393 double sumAdjacentResidue = 0;
394 int adjacentSize = 0;
395 for (
int ii = 0; ii <
Nr; ii++)
397 for (
int jj = 0; jj <
Nc; jj++)
399 sumAdjacentResidue += adjacentResidue(ii, jj);
402 if (sumAdjacentResidue == 0)
410 vector<int> rAdjacent, cAdjacent;
411 if (countNearbyResidueFlag == 1)
413 findNZ(adjacentResidue, rAdjacent, cAdjacent);
414 adjacentSize = rAdjacent.size();
415 rActive = rAdjacent[0];
416 cActive = cAdjacent[0];
417 adjacentResidueCount = 1;
418 residueBalanced(rActive, cActive) = 1;
419 countNearbyResidueFlag = 0;
423 adjacentResidueCount += 1;
424 if (adjacentResidueCount <= adjacentSize)
426 rActive = rAdjacent[adjacentResidueCount-1];
427 cActive = cAdjacent[adjacentResidueCount-1];
434 adjacentResidue.zeros();
435 countNearbyResidueFlag = 1;
441 if (clusterCounter != 1)
447 satelliteResidue += 1;
450 while (clusterCounter == 1)
454 for (
int m = rActive - radius;
m < rActive + radius + 1;
m++)
456 for (
int n = cActive - radius; n < cActive + radius + 1; n++)
458 if (((
abs(m - rActive) == radius) | (
abs(n - cActive) == radius) ))
460 if ((m < 1) | (m >=
Nr - 1) | (n < 1) | (m >=
Nc - 1))
462 if (m >=
Nr - 1) {
m =
Nr - 1; }
463 if (n >=
Nc - 1) { n =
Nc - 1; }
464 if (n < 1) { n = 0; }
465 if (m < 1) {
m = 0; }
468 residueBalanced(rActive, cActive) = 1;
470 if (residueBinary(m, n))
474 residueBalanced(rActive, cActive) = 1;
489 LOG(
"Branch cut operation completed. \n");
490 LOG(
"Satellite residues accounted for = %d\n", satelliteResidue);
497 double rdist =
abs(r2 - r1);
498 double cdist =
abs(c2 - c1);
499 int rsign = (r2 > r1) ? 1 : -1;
500 int csign = (c2 > c1) ? 1 : -1;
505 for (
int i = 0; i <= rdist; i++)
508 c = c1 + (int)(round(((
double)(i))*((double)(csign))*cdist / rdist));
514 for (
int j = 0; j <= cdist; j++)
517 r = r1 + (int)(round(((
double)(j))*((
double)(rsign))*rdist / cdist));
530 matrix<int> adjoin(
Nr,
Nc);
533 matrix<int> unwrappedBinary(
Nr,
Nc);
534 unwrappedBinary.zeros();
537 bool refPhaseFound =
false;
538 for (
int i = 1; (i <
Nr - 1) & !refPhaseFound; i++)
540 for (
int j = 1; (j <
Nc - 1) & !refPhaseFound; j++)
542 if (inputBranchCuts(i, j) == 0)
544 adjoin(i - 1, j) = 1;
545 adjoin(i + 1, j) = 1;
546 adjoin(i, j - 1) = 1;
547 adjoin(i, j + 1) = 1;
548 unwrappedBinary(i, j) = 1;
550 refPhaseFound =
true;
568 findNZ(adjoin, rAdjoin, cAdjoin);
569 if (adjoinStuck == rAdjoin.size())
572 LOG(
"countLimit %d\n", countLimit);
578 adjoinStuck = rAdjoin.size();
579 for (
int i = 0; i < rAdjoin.size(); i++)
581 rActive = rAdjoin[i];
582 cActive = cAdjoin[i];
583 if ((rActive <=
Nr - 2) & (rActive >= 1) & (cActive <=
Nc - 2) & (cActive >= 1))
585 if ((inputBranchCuts(rActive + 1, cActive) == 0) & (unwrappedBinary(rActive + 1, cActive) == 1))
589 unwrappedBinary(rActive, cActive) = 1;
590 adjoin(rActive, cActive) = 0;
591 if ((unwrappedBinary(rActive - 1, cActive) == 0) & (inputBranchCuts(rActive - 1, cActive) == 0))
593 adjoin(rActive - 1, cActive) = 1;
595 if ((unwrappedBinary(rActive, cActive-1) == 0) & (inputBranchCuts(rActive, cActive-1) == 0))
597 adjoin(rActive, cActive-1) = 1;
599 if ((unwrappedBinary(rActive, cActive+1) == 0) & (inputBranchCuts(rActive, cActive+1) == 0))
601 adjoin(rActive, cActive+1) = 1;
604 if ((inputBranchCuts(rActive - 1, cActive) == 0) & (unwrappedBinary(rActive - 1, cActive) == 1))
608 unwrappedBinary(rActive, cActive) = 1;
609 adjoin(rActive, cActive) = 0;
610 if ((unwrappedBinary(rActive + 1, cActive) == 0) & (inputBranchCuts(rActive + 1, cActive) == 0))
612 adjoin(rActive + 1, cActive) = 1;
614 if ((unwrappedBinary(rActive, cActive - 1) == 0) & (inputBranchCuts(rActive, cActive - 1) == 0))
616 adjoin(rActive, cActive - 1) = 1;
618 if ((unwrappedBinary(rActive, cActive + 1) == 0) & (inputBranchCuts(rActive, cActive + 1) == 0))
620 adjoin(rActive, cActive + 1) = 1;
623 if ((inputBranchCuts(rActive, cActive +1) == 0) & (unwrappedBinary(rActive, cActive+1) == 1))
627 unwrappedBinary(rActive, cActive) = 1;
628 adjoin(rActive, cActive) = 0;
629 if ((unwrappedBinary(rActive + 1, cActive) == 0) & (inputBranchCuts(rActive + 1, cActive) == 0))
631 adjoin(rActive + 1, cActive) = 1;
633 if ((unwrappedBinary(rActive, cActive - 1) == 0) & (inputBranchCuts(rActive, cActive - 1) == 0))
635 adjoin(rActive, cActive - 1) = 1;
637 if ((unwrappedBinary(rActive -1 , cActive) == 0) & (inputBranchCuts(rActive-1, cActive) == 0))
639 adjoin(rActive-1, cActive) = 1;
642 if ((inputBranchCuts(rActive, cActive-1) == 0) & (unwrappedBinary(rActive, cActive-1) == 1))
646 unwrappedBinary(rActive, cActive) = 1;
647 adjoin(rActive, cActive) = 0;
648 if ((unwrappedBinary(rActive + 1, cActive) == 0) & (inputBranchCuts(rActive + 1, cActive) == 0))
650 adjoin(rActive + 1, cActive) = 1;
652 if ((unwrappedBinary(rActive -1, cActive) == 0) & (inputBranchCuts(rActive-1, cActive) == 0))
654 adjoin(rActive-1, cActive) = 1;
656 if ((unwrappedBinary(rActive, cActive + 1) == 0) & (inputBranchCuts(rActive, cActive + 1) == 0))
658 adjoin(rActive, cActive + 1) = 1;
669 for (
int i = 1; i <=
Nr - 2; i++)
671 for (
int j = 1; j <
Nc - 2; j++)
673 if ((inputBranchCuts(i, j) == 1) &
674 ((inputBranchCuts(i + 1, j) == 0) |
675 (inputBranchCuts(i - 1, j) == 0) |
676 (inputBranchCuts(i, j - 1) == 0) |
677 (inputBranchCuts(i, j + 1) == 0)))
683 findNZ(adjoin, rAdjoin, cAdjoin);
684 for (
int i = 0; i < rAdjoin.size(); i++)
686 rActive = rAdjoin[i];
687 cActive = cAdjoin[i];
689 if (unwrappedBinary(rActive + 1, cActive) == 1)
693 unwrappedBinary(rActive, cActive) = 1;
694 adjoin(rActive, cActive) = 0;
696 if (unwrappedBinary(rActive - 1, cActive) == 1)
700 unwrappedBinary(rActive, cActive) = 1;
701 adjoin(rActive, cActive) = 0;
703 if (unwrappedBinary(rActive, cActive+1) == 1)
707 unwrappedBinary(rActive, cActive) = 1;
708 adjoin(rActive, cActive) = 0;
710 if (unwrappedBinary(rActive, cActive-1) == 1)
714 unwrappedBinary(rActive, cActive) = 1;
715 adjoin(rActive, cActive) = 0;
718 LOG(
"Floodfill completed\n");
723 double diff = phaseInput - phaseRef;
724 double modval =
mod2pi(diff);
725 return phaseRef + modval;
731 temp = fmod(phase, 2 *
M_PI);
734 temp = temp - 2 *
M_PI;
738 temp = temp + 2 *
M_PI;
743 void ophSigPU::findNZ(matrix<int>& inputMatrix, vector<int>& row, vector<int>& col)
747 for (
int i = 0; i < inputMatrix.size(
_X); i++)
749 for (
int j = 0; j < inputMatrix.size(
_Y); j++)
751 if (inputMatrix(i,j) != 0)
763 for (
int i = r1; i <= r2; i++)
765 for (
int j = c1; j <= c2; j++)
767 outputsum += inputMatrix(i, j);
void abs(const oph::Complex< T > &src, oph::Complex< T > &dst)
void floodFill(matrix< Real > &inputBranchCuts)
virtual bool saveAsImg(const char *fname, uint8_t bitsperpixel, uchar *src, int width, int height)
Function for creating image files.
double mod2pi(double phase)
void findNZ(matrix< int > &inputMatrix, vector< int > &row, vector< int > &col)
matrix< Real > PhaseOriginal
void placeBranchCutsInternal(matrix< Real > &branchCuts, int r1, int c1, int r2, int c2)
double unwrap(double phaseRef, double phaseInput)
void phaseResidues(matrix< Real > &outputResidue)
bool savePhaseUnwrapped(const char *fname)
Save the unwrapped phase data to image file.
bool runPU(void)
Run phase unwrapping algorithm.
int matrixPartialSum(matrix< int > &inputMatrix, int r1, int c1, int r2, int c2)
matrix< Real > PhaseUnwrapped
bool setPUparam(int maxBoxRadius)
Set parameters for Goldstein branchcut algorithm.
void branchCuts(matrix< Real > &inputResidue, matrix< Real > &outputBranchCuts)
bool readConfig(const char *fname)
Read configure file.
bool loadPhaseOriginal(void)