📄 maskvolume.cpp
字号:
// MaskVolume.cpp: implementation of the RxMaskVolume class.////////////////////////////////////////////////////////////////////////#include "stdafx.h"//#include "ploutos.h"#include "MaskVolume.h"#include "ipl.h"#include <xmmintrin.h>#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif#define CACHESIZE 32//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////RxMaskVolume::RxMaskVolume(){ m_pbyMask = NULL; m_pbyMinMax2x2 = NULL; m_pbyMinMax8x8 = NULL; m_iMaskSize = m_iMinMaxSize2x2 = m_iMinMaxSize8x8 = 0; m_iVolX = m_iVolY = m_iVolZ = 0; m_iVolX2x2 = m_iVolY2x2 = m_iVolZ2x2 = 0; m_iVolX8x8 = m_iVolY8x8 = m_iVolZ8x8 = 0;}RxMaskVolume::~RxMaskVolume(){ if (m_pbyMask) { ::VirtualFree(m_pbyMask, m_iMaskSize, MEM_DECOMMIT); ::VirtualFree(m_pbyMask, 0, MEM_RELEASE); } if (m_pbyMinMax2x2) { ::VirtualFree(m_pbyMinMax2x2, m_iMinMaxSize2x2, MEM_DECOMMIT); ::VirtualFree(m_pbyMinMax2x2, 0, MEM_RELEASE); } if (m_pbyMinMax8x8) { ::VirtualFree(m_pbyMinMax8x8, m_iMinMaxSize8x8, MEM_DECOMMIT); ::VirtualFree(m_pbyMinMax8x8, 0, MEM_RELEASE); }}BOOL RxMaskVolume::CreateMaskVolume(int iVolX, int iVolY, int iVolZ, char chFill ) // = 0{ if (m_pbyMask) return FALSE; m_iVolX = iVolX; m_iVolY = iVolY; m_iVolZ = iVolZ; m_iMaskSize = iVolX * iVolY * iVolZ / 8; m_pbyMask = (unsigned char*)::VirtualAlloc(NULL, m_iMaskSize, MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE); if (!m_pbyMask) { // can't reserve memory m_iMaskSize = 0; return FALSE; } m_pbyMask = (unsigned char*)::VirtualAlloc(m_pbyMask, m_iMaskSize, MEM_COMMIT, PAGE_READWRITE); memset(m_pbyMask, chFill, sizeof(unsigned char) * m_iMaskSize); return TRUE;}BOOL RxMaskVolume::CreateNULLMask(int iVolX, int iVolY, int iVolZ){ if (m_pbyMask) return FALSE; m_iVolX = iVolX; m_iVolY = iVolY; m_iVolZ = iVolZ; m_iMaskSize = iVolX * iVolY * iVolZ / 8; return TRUE;}void RxMaskVolume::DestroyMaskVolume(){ if (m_pbyMask) { ::VirtualFree(m_pbyMask, m_iMaskSize, MEM_DECOMMIT); ::VirtualFree(m_pbyMask, 0, MEM_RELEASE); m_pbyMask = NULL; }}RxMaskVolume RxMaskVolume::operator =(const RxMaskVolume &maskSrc){ ASSERT(m_iMaskSize == maskSrc.m_iMaskSize); memcpy(m_pbyMask, maskSrc.m_pbyMask, m_iMaskSize); return *this;}void RxMaskVolume::operator |= (const RxMaskVolume &maskSrc){ ASSERT(m_iMaskSize == maskSrc.m_iMaskSize); ASSERT(m_iMaskSize %4 == 0); LPDWORD pSrc = (LPDWORD)maskSrc.m_pbyMask; LPDWORD pDst = (LPDWORD)m_pbyMask; int iLoopCount = m_iMaskSize/4; for(int i=0; i<iLoopCount; i++) { pDst[i] |= pSrc[i]; }}// 观俊辑 memory free 秦霖促.BOOL RxMaskVolume::CreateMinMax2x2(){ // X/2 * Y/2 * (Z+1)/2 / 8 m_iMinMaxSize2x2 = m_iVolX2x2 * m_iVolY2x2 * m_iVolZ2x2 / 8; m_pbyMinMax2x2 = (LPBYTE)VirtualAlloc(NULL, m_iMinMaxSize2x2, MEM_RESERVE | MEM_TOP_DOWN | MEM_COMMIT, PAGE_READWRITE); if (m_pbyMinMax2x2 == NULL) return NULL; int nSliceSize = m_iVolY * m_iVolX / 16; int nScanlineSize = m_iVolX / 8; // tmp buffer // size = X * Y/2 * (Z+1)/2 / 8 unsigned char *pbyTmpMinMax = (unsigned char *)_mm_malloc(m_iVolX * m_iVolY * ((m_iVolZ+1)/2) / 16, CACHESIZE); unsigned char *pTmpSlice1 = (unsigned char *)_mm_malloc(nSliceSize, CACHESIZE); unsigned char *pTmpSlice2 = (unsigned char *)_mm_malloc(nSliceSize, CACHESIZE); unsigned char *pTmpSlice3 = (unsigned char *)_mm_malloc(nSliceSize, CACHESIZE); // first slice SliceMinMax2x2(m_pbyMask, pTmpSlice1); int nMinMaxIndex = 0; int nMaskSize = m_iVolY * m_iVolX / 8; // main for (int z = 1; z < m_iVolZ - 1; z += 2) { int nMaskIndex1 = z * nMaskSize; int nMaskIndex2 = nMaskIndex1 + nMaskSize; SliceMinMax2x2(m_pbyMask + nMaskIndex1, pTmpSlice2); SliceMinMax2x2(m_pbyMask + nMaskIndex2, pTmpSlice3); int nIndex = 0; for (int y = 0; y < m_iVolY / 2; y++) { for (int x = 0; x < nScanlineSize; x++) { pTmpSlice2[nIndex] = pTmpSlice2[nIndex] | pTmpSlice3[nIndex]; pbyTmpMinMax[nMinMaxIndex] = pTmpSlice1[nIndex] | pTmpSlice2[nIndex]; nIndex++; nMinMaxIndex++; } } // for reuse, swap unsigned char *tmp = pTmpSlice1; pTmpSlice1 = pTmpSlice2; pTmpSlice2 = tmp; } // last slice if (m_iVolZ % 2 == 0) { int nMaskIndex = (m_iVolZ - 1) * nMaskSize; SliceMinMax2x2(m_pbyMask + nMaskIndex, pTmpSlice2); int nIndex = 0; for (int y = 0; y < m_iVolY / 2; y++) { for (int x = 0; x < nScanlineSize; x++) { pbyTmpMinMax[nMinMaxIndex] = pTmpSlice1[nIndex] | pTmpSlice2[nIndex]; nIndex++; nMinMaxIndex++; } } } else { memcpy(pbyTmpMinMax + nMinMaxIndex, pTmpSlice1, nSliceSize); } // x绵栏肺 or IplROI *srcROI1 = iplCreateROI(0, 0, 0, m_iVolX - 2, m_iVolY/2); IplROI *srcROI2 = iplCreateROI(0, 1, 0, m_iVolX - 2, m_iVolY/2); IplROI *srcROI3 = iplCreateROI(0, 2, 0, m_iVolX - 2, m_iVolY/2); IplROI *dstROI = iplCreateROI(0, 0, 0, m_iVolX - 2, m_iVolY/2); IplROI *endROI1 = iplCreateROI(0, m_iVolX-2, 0, 1, m_iVolY/2); IplROI *endROI2 = iplCreateROI(0, m_iVolX-1, 0, 1, m_iVolY/2); IplImage *srcImage1 = iplCreateImageHeader( 1, 0, IPL_DEPTH_1U, // data of byte type "Gray", "Gray", // color order IPL_DATA_ORDER_PIXEL, // channel arrangement IPL_ORIGIN_TL, // top left orientation IPL_ALIGN_DWORD, // 4 bytes align m_iVolX, m_iVolY/2, // image height NULL, NULL, NULL, NULL); // not tiled if (NULL == srcImage1) return FALSE; srcImage1->roi = srcROI1; IplImage *srcImage2 = iplCreateImageHeader( 1, 0, IPL_DEPTH_1U, // data of byte type "Gray", "Gray", // color order IPL_DATA_ORDER_PIXEL, // channel arrangement IPL_ORIGIN_TL, // top left orientation IPL_ALIGN_DWORD, // 4 bytes align m_iVolX, m_iVolY/2, // image height NULL, NULL, NULL, NULL); // not tiled if (NULL == srcImage2) return FALSE; srcImage2->roi = srcROI2; IplImage *srcImage3 = iplCreateImageHeader( 1, 0, IPL_DEPTH_1U, // data of byte type "Gray", "Gray", // color order IPL_DATA_ORDER_PIXEL, // channel arrangement IPL_ORIGIN_TL, // top left orientation IPL_ALIGN_DWORD, // 4 bytes align m_iVolX, m_iVolY/2, // image height NULL, NULL, NULL, NULL); // not tiled if (NULL == srcImage3) return FALSE; srcImage3->roi = srcROI3; IplImage *dstImage = iplCreateImageHeader( 1, 0, IPL_DEPTH_1U, // data of byte type "Gray", "Gray", // color order IPL_DATA_ORDER_PIXEL, // channel arrangement IPL_ORIGIN_TL, // top left orientation IPL_ALIGN_DWORD, // 4 bytes align m_iVolX, m_iVolY/2, // image height NULL, NULL, NULL, NULL); // not tiled if (NULL == dstImage) return FALSE; dstImage->imageData = (char *)pTmpSlice1; IplImage *tmpImage = iplCreateImageHeader( 1, 0, IPL_DEPTH_1U, // data of byte type "Gray", "Gray", // color order IPL_DATA_ORDER_PIXEL, // channel arrangement IPL_ORIGIN_TL, // top left orientation IPL_ALIGN_DWORD, // 4 bytes align m_iVolX, m_iVolY/2, // image height NULL, NULL, NULL, NULL); // not tiled if (NULL == tmpImage) return FALSE; tmpImage->roi = dstROI; tmpImage->imageData = (char *)pTmpSlice2; IplImage *endImage1 = iplCreateImageHeader( 1, 0, IPL_DEPTH_1U, // data of byte type "Gray", "Gray", // color order IPL_DATA_ORDER_PIXEL, // channel arrangement IPL_ORIGIN_TL, // top left orientation IPL_ALIGN_DWORD, // 4 bytes align m_iVolX, m_iVolY/2, // image height NULL, NULL, NULL, NULL); // not tiled if (NULL == endImage1) return FALSE; endImage1->roi = endROI1; IplImage *endImage2 = iplCreateImageHeader( 1, 0, IPL_DEPTH_1U, // data of byte type "Gray", "Gray", // color order IPL_DATA_ORDER_PIXEL, // channel arrangement IPL_ORIGIN_TL, // top left orientation IPL_ALIGN_DWORD, // 4 bytes align m_iVolX, m_iVolY/2, // image height NULL, NULL, NULL, NULL); // not tiled if (NULL == endImage2) return FALSE; endImage2->roi = endROI2; IplImage *DecimateImage = iplCreateImageHeader( 1, 0, IPL_DEPTH_1U, // data of byte type "Gray", "Gray", // color order IPL_DATA_ORDER_PIXEL, // channel arrangement IPL_ORIGIN_TL, // top left orientation IPL_ALIGN_DWORD, // 4 bytes align m_iVolX/2, m_iVolY/2, // image height NULL, NULL, NULL, NULL); // not tiled if (NULL == DecimateImage) return FALSE; for (z = 0; z < (m_iVolZ + 1) / 2; z++) { // OR dstImage->roi = dstROI; int nIndex = z * nSliceSize; srcImage1->imageData = (char *)(pbyTmpMinMax + nIndex); srcImage2->imageData = (char *)(pbyTmpMinMax + nIndex); srcImage3->imageData = (char *)(pbyTmpMinMax + nIndex); iplOr(srcImage1, srcImage2, tmpImage); iplOr(srcImage3, tmpImage, dstImage); dstImage->roi = endROI1; endImage1->imageData = (char *)(pbyTmpMinMax + nIndex); endImage2->imageData = (char *)(pbyTmpMinMax + nIndex); iplOr(endImage1, endImage2, dstImage); // decimate dstImage->roi = NULL; // z * Y/2 * X/2 / 8 int nMaskIndex = z * m_iVolY2x2 * m_iVolX2x2 / 8; DecimateImage->imageData = (char *)(m_pbyMinMax2x2 + nMaskIndex); iplDecimate(dstImage, DecimateImage, m_iVolX2x2, m_iVolX, m_iVolY2x2, m_iVolY2x2, IPL_INTER_NN); } // deallocate iplDeallocate(srcImage1, IPL_IMAGE_HEADER); iplDeallocate(srcImage2, IPL_IMAGE_HEADER); iplDeallocate(srcImage3, IPL_IMAGE_HEADER); iplDeallocate(dstImage, IPL_IMAGE_HEADER); iplDeallocate(tmpImage, IPL_IMAGE_HEADER); iplDeallocate(endImage1, IPL_IMAGE_HEADER); iplDeallocate(endImage2, IPL_IMAGE_HEADER); iplDeallocate(DecimateImage, IPL_IMAGE_HEADER); iplDeleteROI(srcROI1); iplDeleteROI(srcROI2); iplDeleteROI(srcROI3); iplDeleteROI(dstROI); iplDeleteROI(endROI1); iplDeleteROI(endROI2); // free _mm_free(pbyTmpMinMax); _mm_free(pTmpSlice1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -