📄 volumedata.cpp
字号:
// VolumeData.cpp : implementation file//////////////////////////////////////////////////////////////////////////// Title: Container of Volume Informations//////////////////////////////////////////////////////////////////////////// Author: H.W.Kye// 138-dong 417-ho Seoul National University// San 56-1 Shinlim-dong Kwanak-gu Seoul, Korea// Email. //// Date :// Update ://////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// include//////////////////////////////////////////////////////////////////////#include "stdafx.h"#include <math.h>#include <stdlib.h>#include <afxmt.h>#include "BlockData.h"#include "volumedata.h"#include "FastInlineFuncs.h"#include "DicomObject.h"#include "ProgressWnd.h"#include <stdlib.h>#include <windowsx.h>#include "ipl.h"//////////////////////////////////////////////////////////////////////// declaration//////////////////////////////////////////////////////////////////////#define DESTROY_ARRAY_INSTANCE(ci) {if(ci) {delete []ci; ci=NULL;}}//////////////////////////////////////////////////////////////////////// RxVolumeDataRxVolumeData::RxVolumeData(){ m_iBlockSize = 16; m_iFilterLevel = 0; m_pnVolume = NULL; m_pDicomInfo = NULL; m_piInterpolatedMap = NULL; m_piReverseInterpolatedMap = NULL; m_pfInterpolatedWeightTable = NULL; m_puInterpolatedWeightTable = NULL; m_bVolumeEdited = FALSE; m_pWndProgress = NULL;}RxVolumeData::~RxVolumeData(void){ DestroyVolumeData();}BOOL RxVolumeData::DestroyVolumeData(){ if(m_pnVolume) { VirtualFree(m_pnVolume, m_iVolumeSizeInByte, MEM_DECOMMIT); VirtualFree(m_pnVolume, 0, MEM_RELEASE); m_pnVolume = NULL; } DESTROY_ARRAY_INSTANCE(m_pDicomInfo); DESTROY_ARRAY_INSTANCE(m_piInterpolatedMap); DESTROY_ARRAY_INSTANCE(m_piReverseInterpolatedMap); DESTROY_ARRAY_INSTANCE(m_pfInterpolatedWeightTable); DESTROY_ARRAY_INSTANCE(m_puInterpolatedWeightTable); return TRUE;}////////////////////////////////////////////////////// 2000.8.24 heewon////////////////////////////////////////////////////BOOL Intermix(DWORD *pdwDst, unsigned short *pnSrcHi, unsigned short *pnSrcLo, int iCount){ for(int i=0; i<iCount; i++) { pdwDst[i] = (DWORD(pnSrcHi[i]) << 16) | DWORD(pnSrcLo[i]); } return TRUE;}BOOL RxVolumeData::VolumeFiltering(int iFilterLevel){ unsigned short *pnVolume = NULL; for(int c=0; c<2; c++) { pnVolume = m_pnVolume; if(c==1) break; m_iFilterLevel = iFilterLevel; if(m_iFilterLevel==0) // do nothing return TRUE; IplImage *srcImage; IplImage *dstImage; srcImage = iplCreateImageHeader( 1, 0, IPL_DEPTH_16U, // data of byte type "Gray", "Gray", // color order IPL_DATA_ORDER_PIXEL, // channel arrangement IPL_ORIGIN_TL, // top left orientation IPL_ALIGN_QWORD, // 8 bytes align m_iBigVolX, m_iBigVolY, // image height NULL, NULL, NULL, NULL); // not tiled dstImage = iplCreateImageHeader( 1, 0, IPL_DEPTH_16U, // data of byte type "Gray", "Gray", // color order IPL_DATA_ORDER_PIXEL, // channel arrangement IPL_ORIGIN_TL, // top left orientation IPL_ALIGN_QWORD, // 8 bytes align m_iBigVolX, m_iBigVolY, // image height NULL, NULL, NULL, NULL); // not tiled iplAllocateImage(dstImage, 0, 0); iplSetBorderMode( srcImage, IPL_BORDER_REPLICATE, IPL_SIDE_ALL, 0); iplSetBorderMode( dstImage, IPL_BORDER_REPLICATE, IPL_SIDE_ALL, 0); for(int i=0; i<m_iSliceNum; i++) { srcImage->imageData = (char*)(pnVolume + m_iBigVolX*m_iBigVolY*i); iplBlur(srcImage, dstImage, m_iFilterLevel*2+1, m_iFilterLevel*2+1, m_iFilterLevel, m_iFilterLevel);// iplMedianFilter(srcImage, dstImage, m_iFilterLevel*2+1, m_iFilterLevel*2+1, m_iFilterLevel, m_iFilterLevel); iplCopy(dstImage, srcImage);// memcpy(srcImage->imageData, dstImage->imageData, m_iBigVolX*m_iBigVolY*sizeof(unsigned short)); } iplDeallocate( srcImage, IPL_IMAGE_HEADER ); iplDeallocate( dstImage, IPL_IMAGE_ALL ); } return TRUE;}BOOL RxVolumeData::InitMinMaxMapFailed(){ m_bdBlockData.DestroyData(); if (m_pWndProgress) delete m_pWndProgress; m_pWndProgress = NULL; return FALSE;}BOOL RxVolumeData::InitMinMaxMap(int iSeriesNum, int iLoadedSeriesCount){ // init progress window if (m_pWndProgress) { delete m_pWndProgress; m_pWndProgress = NULL; } m_pWndProgress = new RxProgressWnd; // message output; range 0-900 CString str; str.Format(_T("%d/%d"), iSeriesNum+1, iLoadedSeriesCount+1); m_pWndProgress->GoModal(str, TRUE, TRUE); m_pWndProgress->SetWindowSize(0); m_pWndProgress->SetRange(0, 100); str.Format(_T("Opening step %d"), iSeriesNum+1); m_pWndProgress->SetText(str); // 0 - 200 BOOL bSuccess = TRUE; // 0-50 bSuccess = m_bdBlockData.CreateData(m_iBigVolX, m_iBigVolY, m_iSliceNum, m_pnVolume, m_pWndProgress); if (!bSuccess) return InitMinMaxMapFailed(); // 50-100 bSuccess = m_bdBlockData.CreateMinMax4Iso(m_iBigVolX, m_iBigVolY, m_iSliceNum, m_pnVolume, (float)m_fRatioZ, m_pWndProgress); if (!bSuccess) return InitMinMaxMapFailed(); // interpolated俊辑 original肺 map窍绰 table积己 MakeInterpolatedMap(); if (m_pWndProgress && bSuccess && m_pWndProgress->m_hWnd){ m_pWndProgress->SetPos(100); m_pWndProgress->PeekAndPump(); delete m_pWndProgress; m_pWndProgress = NULL; } DWORD dwPrevProtect; // jjlee VirtualProtect(m_pnVolume, m_iBigVolX * m_iBigVolY * m_iSliceNum * 2, PAGE_READWRITE, &dwPrevProtect); return bSuccess;}void RxVolumeData::UpdateLabel(int nSliceIdx, unsigned char *pLabel, bool bNotInvert){ // Ku kyobum int nMasking; // bInvert甫 check 窍咯 角力 盒且 康开阑 唱鸥郴绰 // label阑 setting if(bNotInvert) nMasking = 255; else nMasking = 0; unsigned char maskArray[8]; maskArray[0] = 0x7f; maskArray[1] = 0xbf; maskArray[2] = 0xdf; maskArray[3] = 0xef; maskArray[4] = 0xf7; maskArray[5] = 0xfb; maskArray[6] = 0xfd; maskArray[7] = 0xfe; int nImgSize = (m_iBigVolX * m_iBigVolY); int nBaseImgIdx = nImgSize * nSliceIdx; // m_pSliceEditFlags 甫 诀单捞飘 秦具窍绰单.... // 绢痘霸 秦具 窍唱.... for(int y=0;y<m_iBigVolY;y++){ for(int x=0;x<m_iBigVolX;x++){ int nSliceIdx = x + y * m_iBigVolX; if(pLabel[nSliceIdx]==nMasking){ int index = nSliceIdx + nBaseImgIdx; int share = index/8; int remainder = index - share * 8;// m_pSeg2DSlices[share] |= 1<<(7-remainder); } } }}unsigned short *RxVolumeData::MakeBigVolume(int iVolX, int iVolY, int iSliceNum){ m_bFirst3DRender = TRUE; m_iBigVolX = iVolX; m_iBigVolY = iVolY; m_iSliceNum = iSliceNum; m_iVolumeSizeInByte = m_iBigVolX*m_iBigVolY*m_iSliceNum*sizeof(short); m_pnVolume = (unsigned short*)::VirtualAlloc(NULL, iVolX*iVolY*iSliceNum*sizeof(unsigned short), MEM_COMMIT | MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE); ASSERT(m_pnVolume); return m_pnVolume;}void RxVolumeData::SetBigVolume(unsigned short *pVolume, int iVolX, int iVolY, int iSliceNum){ return; m_bFirst3DRender = TRUE; m_pnVolume = pVolume; ///////////// ///////////////// m_iBigVolX = iVolX; m_iBigVolY = iVolY; m_iSliceNum = iSliceNum; m_iVolumeSizeInByte = m_iBigVolX*m_iBigVolY*m_iSliceNum*sizeof(short);}void RxVolumeData::SetInfos(RxDicomObject *pDicomInfo, float fSliceInterval, double afImageOrientation[]){ if (m_pDicomInfo) { delete[] m_pDicomInfo; m_pDicomInfo = NULL; } m_pDicomInfo = pDicomInfo; m_fSliceInterval = fSliceInterval; float fVal; int itype; m_pDicomInfo->GetDicomInfo(DI_PIXELSPACE, &fVal, &itype); m_fPixelSpace = fVal; ASSERT(m_fPixelSpace); m_fRatioZ = m_fSliceInterval/m_fPixelSpace; m_iRatioZ = (int)(m_fRatioZ+0.5); if(m_iRatioZ == 0) m_iRatioZ = 1; m_pDicomInfo->GetDicomInfo(DI_SLICETHICKNESS, &fVal, &itype); m_fSliceThickness = fVal; double fTemp = (m_iSliceNum - 1) * m_fRatioZ + 1; m_iItplVolZ = int(fTemp); m_fMaxMPRThickness = 40.f/(float)m_fPixelSpace; //弥措 4cm m_maskEditVolume.CreateMaskVolume(m_iBigVolX, m_iBigVolY, m_iSliceNum, (char)0xff); // m_maskNoduleVolume.CreateMaskVolume(m_iBigVolX, m_iBigVolY, m_iSliceNum, (char)0x00); m_maskEdgeVolume.CreateMaskVolume(m_iBigVolX, m_iBigVolY, m_iSliceNum, (char)0x00); m_maskVesselVolume.CreateMaskVolume(m_iBigVolX, m_iBigVolY, m_iSliceNum, (char)0x00); m_maskAirwayVolume.CreateMaskVolume(m_iBigVolX, m_iBigVolY, m_iSliceNum, (char)0x00); m_maskLeftEditVolume.CreateMaskVolume(m_iBigVolX, m_iBigVolY, m_iSliceNum, (char)0x00); m_maskRightEditVolume.CreateMaskVolume(m_iBigVolX, m_iBigVolY, m_iSliceNum, (char)0x00);// m_maskVesselEdge.CreateMaskVolume(m_iBigVolX, m_iBigVolY, m_iSliceNum, (char)0x00);// m_maskSkeleton.CreateMaskVolume(m_iBigVolX, m_iBigVolY, m_iSliceNum, (char)0x00); memcpy(m_afGantryAxes, afImageOrientation, sizeof(double)*6); ///////////////////////// //BEGIN:: original volume 且寸窍扁 /* RxSystemInfo sysInfo; int iMemMaxBlock = sysInfo.GetMaxMemoryBlock(); //楷加利栏肺 棱阑 荐 乐绰 弥措 皋葛府 int iMemAvailable = sysInfo.GetAvailMemory(); //fragment鳖瘤 绊妨茄 巢篮 皋葛府 int iSystemMemory = sysInfo.GetSystemMemory(); int iMemOriginal, iMemVR, iMem2D, iMemSSD, iMemMaxOf2D_SSD; iMem2D = iMemOriginal = m_iBigVolX*m_iBigVolY*m_iSliceNum*sizeof(short); iMemSSD = int(m_iBigVolX*m_iBigVolY*m_iSliceNum*2/8);//object绰 2俺 惶绰促绊 啊沥 iMemMaxOf2D_SSD = max(iMem2D, iMemSSD); iMemVR = iMemOriginal; //block min max甫 困茄 剧..焊烹 volume size父怒 鞘夸.. // origial volume阑 父甸绢具 且瘤 搬沥窃 BOOL bAttemptMakeOriginal = TRUE; if( iMemOriginal > int(0.25*iSystemMemory) ) { CString strMsg; strMsg.LoadString(IDS_LOAD_MANY_SLICES); if(AfxMessageBox(strMsg, MB_YESNO) == IDNO) bAttemptMakeOriginal = FALSE; } // original volume阑 父甸绢 航 m_bExistOriginalVol = FALSE; if(bAttemptMakeOriginal) { m_pnOriginalVolume = (unsigned short*)VirtualAlloc(NULL, m_iVolumeSizeInByte, MEM_RESERVE | MEM_TOP_DOWN | MEM_COMMIT, PAGE_READWRITE); if ( m_pnOriginalVolume) { //力措肺 且寸 登菌澜 memcpy(m_pnOriginalVolume, m_pnVolume, m_iVolumeSizeInByte); m_bExistOriginalVol = TRUE; } } // original volume捞 救 父甸绢瘤绰 版快 东户贸府 if(!m_bExistOriginalVol) { m_pnOriginalVolume = m_pnVolume; if(bAttemptMakeOriginal){ CString strMsg; strMsg.LoadString(IDS_INSUFFICIENT_MEM); AfxMessageBox(strMsg); } m_bExistOriginalVol = FALSE; }*/ //END:: original volume 且寸窍扁 //////////////////////////} BOOL RxVolumeData::MakeInterpolatedMap(){ if (m_piInterpolatedMap) { delete[] m_piInterpolatedMap; m_piInterpolatedMap = NULL; } if (m_piReverseInterpolatedMap) { delete[] m_piReverseInterpolatedMap; m_piReverseInterpolatedMap = NULL; } if (m_pfInterpolatedWeightTable) { delete[] m_pfInterpolatedWeightTable; m_pfInterpolatedWeightTable = NULL; } if (m_puInterpolatedWeightTable) { delete[] m_puInterpolatedWeightTable; m_puInterpolatedWeightTable = NULL; } int iNumTable = GetInterpolatedSliceNum() + (int)(m_fRatioZ) + 1; m_piInterpolatedMap = new int[iNumTable]; m_piReverseInterpolatedMap = new int[m_iSliceNum]; m_pfInterpolatedWeightTable = new double[iNumTable]; m_puInterpolatedWeightTable = new unsigned int[iNumTable]; double fFraction; int iSlice; for (int i = 0; i < iNumTable; i++) { fFraction = (double)i / m_fRatioZ; iSlice = (int)fFraction; fFraction -= iSlice; if (iSlice >= m_iSliceNum - 1) { iSlice = m_iSliceNum - 2; fFraction = 1.0; } m_piInterpolatedMap[i] = iSlice; m_pfInterpolatedWeightTable[i] = fFraction; m_puInterpolatedWeightTable[i] = (unsigned int)(fFraction * 65535); } for (i = 0; i < m_iSliceNum; i++) m_piReverseInterpolatedMap[i] = (int)(i * m_fRatioZ); return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -