📄 jjdistancemap.cpp
字号:
#include "stdafx.h"#include "JJDistanceMap.h"JJDistanceMap::JJDistanceMap(){ m_pDistanceMap = NULL; m_pDBF = NULL;}void JJDistanceMap::CreateDistanceMap(JJBinaryVolume* pRefBinary, int iVolX, int iVolY, int iVolZ){ if (m_pDistanceMap != NULL) free(m_pDistanceMap); if (m_pDBF != NULL) free(m_pDBF); m_VolX = iVolX + 2; m_VolY = iVolY + 2; m_VolZ = iVolZ + 2; m_pDistanceMap = (unsigned char *)malloc(m_VolX*m_VolY*m_VolZ); m_pBinaryVolume = pRefBinary; Initialize(); CalDistance();}void JJDistanceMap::CreatePropagationDistanceMap(JJBinaryVolume* pRefBinary, int iVolX, int iVolY, int iVolZ, int iMaxDistance){ if (m_pDistanceMap != NULL) free(m_pDistanceMap); if (m_pDBF != NULL) free(m_pDBF); m_VolX = iVolX; m_VolY = iVolY; m_VolZ = iVolZ; m_pBinaryVolume = pRefBinary; m_iMaxDistance = iMaxDistance; CalPropagationDistance();// CalPropagationDistanceZRatio();}void JJDistanceMap::CreateEuclideanDistanceMap(JJBinaryVolume* pRefBinary, int iVolX, int iVolY, int iVolZ){ if (m_pDistanceMap != NULL) free(m_pDistanceMap); if (m_pDBF != NULL) free(m_pDBF); m_VolX = iVolX; m_VolY = iVolY; m_VolZ = iVolZ; m_pBinaryVolume = pRefBinary; CalEuclideanDistance();}JJDistanceMap::~JJDistanceMap(){ if (m_pDistanceMap != NULL) free(m_pDistanceMap); if (m_pDBF != NULL) free(m_pDBF);}void JJDistanceMap::Initialize(){ int x, y, z; /* volume indexing */ TxtResol3D Resol; /* volume resolution */ FILE *ofp; /* output file for points */ Resol.Ru = m_VolX - 2; Resol.Rv = m_VolY - 2; Resol.Rw = m_VolZ - 2; /* Initialize z border line */ for (z = 0; z <= Resol.Rw+1; z += Resol.Rw+1) { for (y = 0; y <= Resol.Rv+1; y++) { for (x = 0; x <= Resol.Rv+1; x++) { m_pDistanceMap[x + y*m_VolX + z*m_VolX*m_VolY] = MAXVALUE; } /* end of x for */ } /* end of y for */ } /* end of z for */ /* Initialize y border line */ for (z = 1; z <= Resol.Rw; z++) { for (y = 0; y <= Resol.Rv+1; y += Resol.Rv+1) { for (x = 0; x <= Resol.Ru+1; x++) { m_pDistanceMap[x + y*m_VolX + z*m_VolX*m_VolY] = MAXVALUE; } /* end of x for */ } /* end of y for */ } /* end of z for */ /* Initialize x border line */ for (z = 1; z <= Resol.Rw; z++) { for (y = 0; y <= Resol.Rv+1; y++) { for (x = 0; x <= Resol.Ru+1; x += Resol.Ru+1) { m_pDistanceMap[x + y*m_VolX + z*m_VolX*m_VolY] = MAXVALUE; } /* end of x for */ } /* end of y for */ } /* end of z for */ for (z = 1; z <= Resol.Rw; z++) { for (y = 1; y <= Resol.Rv; y++) { for (x = 1; x <= Resol.Ru; x++) { if (m_pBinaryVolume->IsEdge(x - 1, y - 1, z - 1)) m_pDistanceMap[x + y*m_VolX + z*m_VolX*m_VolY] = 0; else m_pDistanceMap[x + y*m_VolX + z*m_VolX*m_VolY] = MAXVALUE; } /* end of x for */ } /* end of y for */ } /* end of z for */}/****************************************************************************** * CalDistance(): Calculate 3D Distance Transformation by Two-Pass ******************************************************************************/void JJDistanceMap::CalDistance(){ short x, y, z; /* volume indexing */ short dist[3]={1,1,1};/* 2D distance matrix */ short minVal; /* minVal value */ char t; /* temporary character variable */ char tfile[20]; /* temporary name file */ FILE *tfp; /* temporary file description */ TxtResol3D Resol; /* volume resolution */ Resol.Ru = m_VolX - 2; Resol.Rv = m_VolY - 2; Resol.Rw = m_VolZ - 2; /* FIRST PASS: Scan Top-Left to Bottom-Right */ for (z = 1; z < Resol.Rw+1; z++) { for (y = 1; y < Resol.Rv+1; y++) { for (x = 1; x < Resol.Ru+1; x++) { /* Assign DisVol value to min */ minVal = m_pDistanceMap[x + y*m_VolX + z*m_VolX*m_VolY]; if (minVal == CONTOUR) { /* Contour */ continue; } else if (minVal < CONTOUR) { /* Inside */ /* Straight Line: Left & Below & BelowCenter */ minVal = maximum(minVal, -dist[0]+minimum(0, m_pDistanceMap[x - 1 + y*m_VolX + z*m_VolX*m_VolY]));//(*VolDis)[z][y][x-1])); minVal = maximum(minVal, -dist[0]+minimum(0, m_pDistanceMap[x + (y - 1)*m_VolX + z*m_VolX*m_VolY]));//(*VolDis)[z][y-1][x])); minVal = maximum(minVal, -dist[0]+minimum(0, m_pDistanceMap[x + y*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y][x])); /* Straight Line: BelowLeft, BelowRight, 4-neightbor */ minVal = maximum(minVal, -dist[1]+minimum(0, m_pDistanceMap[(x - 1) + (y - 1)*m_VolX + (z)*m_VolX*m_VolY]));//(*VolDis)[z][y-1][x-1])); minVal = maximum(minVal, -dist[1]+minimum(0, m_pDistanceMap[(x + 1) + (y - 1)*m_VolX + (z)*m_VolX*m_VolY]));//(*VolDis)[z][y-1][x+1])); minVal = maximum(minVal, -dist[1]+minimum(0, m_pDistanceMap[(x - 1) + (y)*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y][x-1])); minVal = maximum(minVal, -dist[1]+minimum(0, m_pDistanceMap[(x + 1) + (y)*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y][x+1])); minVal = maximum(minVal, -dist[1]+minimum(0, m_pDistanceMap[(x) + (y - 1)*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y-1][x])); minVal = maximum(minVal, -dist[1]+minimum(0, m_pDistanceMap[(x) + (y + 1)*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y+1][x])); /* Diagonal Line: 4-neighbor */ minVal = maximum(minVal, -dist[2]+minimum(0, m_pDistanceMap[(x - 1) + (y - 1)*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y-1][x-1])); minVal = maximum(minVal, -dist[2]+minimum(0, m_pDistanceMap[(x + 1) + (y - 1)*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y-1][x+1])); minVal = maximum(minVal, -dist[2]+minimum(0, m_pDistanceMap[(x - 1) + (y + 1)*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y+1][x-1])); minVal = maximum(minVal, -dist[2]+minimum(0, m_pDistanceMap[(x + 1) + (y + 1)*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y+1][x+1])); } else if (minVal > CONTOUR) { /* Outside */ /* Straight Line: Left & Below & BelowCenter */ minVal = minimum(minVal, dist[0]+maximum(0, m_pDistanceMap[x - 1 + y*m_VolX + z*m_VolX*m_VolY]));//(*VolDis)[z][y][x-1])); minVal = minimum(minVal, dist[0]+maximum(0, m_pDistanceMap[x + (y - 1)*m_VolX + z*m_VolX*m_VolY]));//(*VolDis)[z][y-1][x])); minVal = minimum(minVal, dist[0]+maximum(0, m_pDistanceMap[x + y*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y][x])); /* Straight Line: BelowLeft, BelowRight, 4-neighbor */ minVal = minimum(minVal, dist[1]+maximum(0, m_pDistanceMap[(x - 1) + (y - 1)*m_VolX + (z)*m_VolX*m_VolY]));//(*VolDis)[z][y-1][x-1])); minVal = minimum(minVal, dist[1]+maximum(0, m_pDistanceMap[(x + 1) + (y - 1)*m_VolX + (z)*m_VolX*m_VolY]));//(*VolDis)[z][y-1][x+1])); minVal = minimum(minVal, dist[1]+maximum(0, m_pDistanceMap[(x - 1) + (y)*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y][x-1])); minVal = minimum(minVal, dist[1]+maximum(0, m_pDistanceMap[(x + 1) + (y)*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y][x+1])); minVal = minimum(minVal, dist[1]+maximum(0, m_pDistanceMap[(x) + (y - 1)*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y-1][x])); minVal = minimum(minVal, dist[1]+maximum(0, m_pDistanceMap[(x) + (y + 1)*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y+1][x])); /* Diagonal Line: 4-neighbor */ minVal = minimum(minVal, dist[2]+maximum(0, m_pDistanceMap[(x - 1) + (y - 1)*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y-1][x-1])); minVal = minimum(minVal, dist[2]+maximum(0, m_pDistanceMap[(x + 1) + (y - 1)*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y-1][x+1])); minVal = minimum(minVal, dist[2]+maximum(0, m_pDistanceMap[(x - 1) + (y + 1)*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y+1][x-1])); minVal = minimum(minVal, dist[2]+maximum(0, m_pDistanceMap[(x + 1) + (y + 1)*m_VolX + (z - 1)*m_VolX*m_VolY]));//(*VolDis)[z-1][y+1][x+1])); } /* Write signed minVal value */ m_pDistanceMap[(x) + (y)*m_VolX + (z)*m_VolX*m_VolY] = minVal; } /* end of x for */ } /* end of y for */ } /* end of z for */ /* SECOND PASS: Scan Bottom-Right to Top-Left */ for (z = Resol.Rw; z > 0; z--) { for (y = Resol.Rv; y > 0; y--) { for (x = Resol.Ru; x > 0; x--) { /* Assign DisVol value to min */ minVal = m_pDistanceMap[(x) + (y)*m_VolX + (z)*m_VolX*m_VolY]; if (minVal == CONTOUR) { /* Contour */ continue; } else if (minVal < CONTOUR) { /* Inside */ /* Straight Line: Right & Above & UpperCenter */ minVal = maximum(minVal, -dist[0]+minimum(0, m_pDistanceMap[(x + 1) + (y)*m_VolX + (z)*m_VolX*m_VolY]));//(*VolDis)[z][y][x+1])); minVal = maximum(minVal, -dist[0]+minimum(0, m_pDistanceMap[(x) + (y + 1)*m_VolX + (z)*m_VolX*m_VolY]));//(*VolDis)[z][y+1][x])); minVal = maximum(minVal, -dist[0]+minimum(0, m_pDistanceMap[(x) + (y)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y][x])); /* Straight Line: AboveRight&Left, 4-neighbor */ minVal = maximum(minVal, -dist[1]+minimum(0, m_pDistanceMap[(x + 1) + (y + 1)*m_VolX + (z)*m_VolX*m_VolY]));//(*VolDis)[z][y+1][x+1])); minVal = maximum(minVal, -dist[1]+minimum(0, m_pDistanceMap[(x - 1) + (y + 1)*m_VolX + (z)*m_VolX*m_VolY]));//(*VolDis)[z][y+1][x-1])); minVal = maximum(minVal, -dist[1]+minimum(0, m_pDistanceMap[(x + 1) + (y)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y][x+1])); minVal = maximum(minVal, -dist[1]+minimum(0, m_pDistanceMap[(x - 1) + (y)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y][x-1])); minVal = maximum(minVal, -dist[1]+minimum(0, m_pDistanceMap[(x) + (y + 1)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y+1][x])); minVal = maximum(minVal, -dist[1]+minimum(0, m_pDistanceMap[(x) + (y - 1)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y-1][x])); /* Diagonal Line: 4-neighbor */ minVal = maximum(minVal, -dist[2]+minimum(0, m_pDistanceMap[(x + 1) + (y + 1)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y+1][x+1])); minVal = maximum(minVal, -dist[2]+minimum(0, m_pDistanceMap[(x - 1) + (y + 1)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y+1][x-1])); minVal = maximum(minVal, -dist[2]+minimum(0, m_pDistanceMap[(x + 1) + (y - 1)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y-1][x+1])); minVal = maximum(minVal, -dist[2]+minimum(0, m_pDistanceMap[(x - 1) + (y - 1)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y-1][x-1])); } else if (minVal > CONTOUR) { /* Outside */ /* Straight Line: Right & Above & UpperCenter */ minVal = minimum(minVal, dist[0]+maximum(0, m_pDistanceMap[(x + 1) + (y)*m_VolX + (z)*m_VolX*m_VolY]));//(*VolDis)[z][y][x+1])); minVal = minimum(minVal, dist[0]+maximum(0, m_pDistanceMap[(x) + (y + 1)*m_VolX + (z)*m_VolX*m_VolY]));//(*VolDis)[z][y+1][x])); minVal = minimum(minVal, dist[0]+maximum(0, m_pDistanceMap[(x) + (y)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y][x])); /* Straight Line: AboveRight&Left, 4-neighbor */ minVal = minimum(minVal, dist[1]+maximum(0, m_pDistanceMap[(x + 1) + (y + 1)*m_VolX + (z)*m_VolX*m_VolY]));//(*VolDis)[z][y+1][x+1])); minVal = minimum(minVal, dist[1]+maximum(0, m_pDistanceMap[(x - 1) + (y + 1)*m_VolX + (z)*m_VolX*m_VolY]));//(*VolDis)[z][y+1][x-1])); minVal = minimum(minVal, dist[1]+maximum(0, m_pDistanceMap[(x + 1) + (y)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y][x+1])); minVal = minimum(minVal, dist[1]+maximum(0, m_pDistanceMap[(x - 1) + (y)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y][x-1])); minVal = minimum(minVal, dist[1]+maximum(0, m_pDistanceMap[(x) + (y + 1)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y+1][x])); minVal = minimum(minVal, dist[1]+maximum(0, m_pDistanceMap[(x) + (y - 1)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y-1][x])); /* Diagonal Line: 4-neighbor */ minVal = minimum(minVal, dist[2]+maximum(0, m_pDistanceMap[(x + 1) + (y + 1)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y+1][x+1])); minVal = minimum(minVal, dist[2]+maximum(0, m_pDistanceMap[(x - 1) + (y + 1)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y+1][x-1])); minVal = minimum(minVal, dist[2]+maximum(0, m_pDistanceMap[(x + 1) + (y - 1)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y-1][x+1])); minVal = minimum(minVal, dist[2]+maximum(0, m_pDistanceMap[(x - 1) + (y - 1)*m_VolX + (z + 1)*m_VolX*m_VolY]));//(*VolDis)[z+1][y-1][x-1])); } /* Write signed minVal value */ m_pDistanceMap[(x) + (y)*m_VolX + (z)*m_VolX*m_VolY] = minVal; } /* end of x for */ } /* end of y for */ } /* end of z for */}int JJDistanceMap::maximum(int a, int b){ if (a > b) return a; else return b;}int JJDistanceMap::minimum(int a, int b){ if (a < b) return a; else return b;}int JJDistanceMap::GetDistance(int iX, int iY, int iZ){ return m_pDistanceMap[(iX + 1) + (iY + 1)*m_VolX + (iZ + 1)*m_VolX*m_VolY];}int JJDistanceMap::GetEuclideanDistance(int iX, int iY, int iZ){ return m_pDBF[iX + iY*m_VolX + iZ*m_VolX*m_VolY];}int JJDistanceMap::GetPropagationDistance(int iX, int iY, int iZ){ return m_pDistanceMap[iX + iY*m_VolX + iZ*m_VolX*m_VolY];}float JJDistanceMap::GetPropagationDistanceZRatio(int iX, int iY, int iZ){ return m_pLongDistanceMap[iX + iY*m_VolX + iZ*m_VolX*m_VolY];}void JJDistanceMap::CalPropagationDistanceZRatio(void){ int i, j, k, x, y, z, w, iCurIndex, nNumEdge1 = 0, nNumEdge2 = 0; int nPlane = m_VolX*m_VolY; double nCenterDist; char t; /* temporary character variable */ char tfile[20]; /* temporary name file */ FILE *tfp; /* temporary file description */ // 512*512*512*0.5*2B = 125 MB m_pLongDistanceMap = (float *)malloc(m_VolX*m_VolY*m_VolZ*sizeof(float)); memset((void *)m_pLongDistanceMap, 0, m_VolX*m_VolY*m_VolZ*sizeof(float)); short* xArr1 = new short[10000000]; short* yArr1 = new short[10000000]; short* zArr1 = new short[10000000]; short* xArr2 = new short[10000000]; short* yArr2 = new short[10000000]; short* zArr2 = new short[10000000]; // distance = 0 nNumEdge1 = 0; for (k = 0; k < m_VolZ; k++) { for (j = 0; j < m_VolY; j++) { for (i = 0; i < m_VolX; i++) { iCurIndex = i + j*m_VolX + k*nPlane; if (m_pBinaryVolume->IsEdge(i, j, k)) { m_pLongDistanceMap[iCurIndex] = 0; xArr1[nNumEdge1] = i; yArr1[nNumEdge1] = j; zArr1[nNumEdge1] = k; nNumEdge1++; } else m_pLongDistanceMap[iCurIndex] = 500.0f; } } } // distance 1 nNumEdge2 = 0; for(w = 0; w < nNumEdge1; w++) { i = xArr1[w]; j = yArr1[w]; k = zArr1[w]; iCurIndex = i + j*m_VolX + k*nPlane; nCenterDist = m_pLongDistanceMap[iCurIndex]; for (x = -1; x <= 1; x++) for (y = -1; y <= 1; y++) for (z = -1; z <= 1; z++) { if ((0 <= (i + x)) && ((i + x) < m_VolX) && (0 <= (j + y)) && ((j + y) < m_VolY) && (0 <= (k + z)) && ((k + z) < m_VolZ)) { iCurIndex = (i + x) + (j + y)*m_VolX + (k + z)*nPlane; if (fabs(m_pLongDistanceMap[iCurIndex] - 500.0f) < 0.001f) { if (z == 0) m_pLongDistanceMap[iCurIndex] = nCenterDist + 1.0; else m_pLongDistanceMap[iCurIndex] = nCenterDist + m_lfZRatioXY; xArr2[nNumEdge2] = i + x; yArr2[nNumEdge2] = j + y; zArr2[nNumEdge2] = k + z; nNumEdge2++; } } } } // distance 2 nNumEdge1 = 0; for(w = 0; w < nNumEdge2; w++) { i = xArr2[w]; j = yArr2[w]; k = zArr2[w]; iCurIndex = i + j*m_VolX + k*nPlane; nCenterDist = m_pLongDistanceMap[iCurIndex]; for (x = -1; x <= 1; x++) for (y = -1; y <= 1; y++) for (z = -1; z <= 1; z++) { if ((0 <= (i + x)) && ((i + x) < m_VolX) && (0 <= (j + y)) && ((j + y) < m_VolY) && (0 <= (k + z)) && ((k + z) < m_VolZ)) { iCurIndex = (i + x) + (j + y)*m_VolX + (k + z)*nPlane; if (fabs(m_pLongDistanceMap[iCurIndex] - 500.0f) < 0.001f) { if (z == 0) m_pLongDistanceMap[iCurIndex] = nCenterDist + 1.0; else m_pLongDistanceMap[iCurIndex] = nCenterDist + m_lfZRatioXY; xArr1[nNumEdge1] = i + x; yArr1[nNumEdge1] = j + y; zArr1[nNumEdge1] = k + z; nNumEdge1++; } } } } // distance 3 nNumEdge2 = 0; for(w = 0; w < nNumEdge1; w++) { i = xArr1[w]; j = yArr1[w]; k = zArr1[w]; iCurIndex = i + j*m_VolX + k*nPlane; nCenterDist = m_pLongDistanceMap[iCurIndex]; for (x = -1; x <= 1; x++) for (y = -1; y <= 1; y++) for (z = -1; z <= 1; z++) { if ((0 <= (i + x)) && ((i + x) < m_VolX) && (0 <= (j + y)) && ((j + y) < m_VolY) && (0 <= (k + z)) && ((k + z) < m_VolZ)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -