void loadMask(QString f) { itkcmds::itkImageIO<ImageType> io; ImageType::Pointer img = io.ReadImageT(f.toAscii().data()); g_boundaryMapList.push_back(img); ScalarToRGBFilter::Pointer rgbFilter1 = ScalarToRGBFilter::New(); rgbFilter1->SetInput(img); rgbFilter1->SetAlphaValue(128); rgbFilter1->Update(); BitmapType::Pointer maskBitmap = rgbFilter1->GetOutput(); g_maskBitmapList.push_back(maskBitmap); DistanceMapFilter::Pointer distmapFilter = DistanceMapFilter::New(); distmapFilter->SetInput(img); distmapFilter->Update(); ImageType::Pointer distImg = distmapFilter->GetOutput(); g_distanceMapList.push_back(distmapFilter->GetOutput()); DistanceVectorImageType::Pointer distVector = distmapFilter->GetVectorDistanceMap(); g_distanceVectorList.push_back(distVector); ScalarToRGBFilter::Pointer rgbFilter = ScalarToRGBFilter::New(); rgbFilter->SetInput(distImg); rgbFilter->SetNumberOfThreads(8); rgbFilter->Update(); BitmapType::Pointer rgbImage = rgbFilter->GetOutput(); g_distanceMapBitmapList.push_back(rgbImage); EdgeDetectionFilterType::Pointer edgeFilter = EdgeDetectionFilterType::New(); edgeFilter->SetInput(img); edgeFilter->Update(); ImageType::Pointer edgeImg = edgeFilter->GetOutput(); PointVectorType phantoms; itk::ImageRegionConstIteratorWithIndex<ImageType> iter(edgeImg, edgeImg->GetBufferedRegion()); for (iter.GoToBegin(); !iter.IsAtEnd(); ++iter) { if (iter.Get() > 0) { phantoms.push_back(iter.GetIndex()[0]); phantoms.push_back(iter.GetIndex()[1]); } } g_phantomParticles.push_back(phantoms);}
void DistanceMapFilter::applyDistanceMapFilter(QString flnm, QList<Vec> clipPos, QList<Vec> clipNormal, QList<CropObject> crops, QList<PathObject> paths, uchar *lut, int chan) { int bpv = 1; if (m_voxelType > 0) bpv = 2; int nbytes = bpv*m_nY*m_nZ; bool trim = (qRound(m_dataSize.x) < m_height || qRound(m_dataSize.y) < m_width || qRound(m_dataSize.z) < m_depth); bool clipPresent = (clipPos.count() > 0); m_cropPresent = false; m_tearPresent = false; m_blendPresent = false; for(int ci=0; ci<m_crops.count(); ci++) { if (crops[ci].cropType() < CropObject::Tear_Tear) m_cropPresent = true; else if (crops[ci].cropType() < CropObject::View_Tear) m_tearPresent = true; else if (m_crops[ci].cropType() > CropObject::Displace_Displace && m_crops[ci].cropType() < CropObject::Glow_Ball) m_blendPresent = true; } m_pathCropPresent = false; m_pathBlendPresent = false; for (int i=0; i<m_paths.count(); i++) { if (m_paths[i].blend()) m_pathBlendPresent = true; if (m_paths[i].crop()) m_pathCropPresent = true; } m_meshLog->moveCursor(QTextCursor::End); int d0 = 0; int d1 = m_nX-1; int d0z = d0 + qRound(m_dataMin.z); int d1z = d1 + qRound(m_dataMin.z); uchar *opacityVol = new uchar[m_nX*m_nY*m_nZ]; uchar *cropped = new uchar[nbytes]; uchar *tmp = new uchar[nbytes]; int i0 = 0; for(int i=d0z; i<=d1z; i++) { m_meshProgress->setValue((int)(100.0*(float)i0/(float)m_nX)); qApp->processEvents(); int iv = qBound(0, i, m_depth-1); uchar *vslice = m_vfm->getSlice(iv); memset(cropped, 0, nbytes); if (!trim) memcpy(tmp, vslice, nbytes); else { int wmin = qRound(m_dataMin.y); int hmin = qRound(m_dataMin.x); if (m_voxelType == 0) { for(int w=0; w<m_nY; w++) for(int h=0; h<m_nZ; h++) tmp[w*m_nZ + h] = vslice[(wmin+w)*m_height + (hmin+h)]; } else { for(int w=0; w<m_nY; w++) for(int h=0; h<m_nZ; h++) ((ushort*)tmp)[w*m_nZ + h] = ((ushort*)vslice)[(wmin+w)*m_height + (hmin+h)]; } } int jk = 0; for(int j=0; j<m_nY; j++) for(int k=0; k<m_nZ; k++) { Vec po = Vec(m_dataMin.x+k, m_dataMin.y+j, iv); bool ok = true; // we don't want to scale before pruning int mop = 0; { Vec pp = po - m_dataMin; int ppi = pp.x/m_pruneLod; int ppj = pp.y/m_pruneLod; int ppk = pp.z/m_pruneLod; ppi = qBound(0, ppi, m_pruneX-1); ppj = qBound(0, ppj, m_pruneY-1); ppk = qBound(0, ppk, m_pruneZ-1); int mopidx = ppk*m_pruneY*m_pruneX + ppj*m_pruneX + ppi; mop = m_pruneData[3*mopidx + chan]; ok = (mop > 0); } po *= m_samplingLevel; if (ok && clipPresent) ok = StaticFunctions::getClip(po, clipPos, clipNormal); if (ok && m_cropPresent) ok = checkCrop(po); if (ok && m_pathCropPresent) ok = checkPathCrop(po); if (ok && m_blendPresent) { ushort v; if (m_voxelType == 0) v = tmp[j*m_nZ + k]; else v = ((ushort*)tmp)[j*m_nZ + k]; ok = checkBlend(po, v, lut); } if (ok && m_pathBlendPresent) { ushort v; if (m_voxelType == 0) v = tmp[j*m_nZ + k]; else v = ((ushort*)tmp)[j*m_nZ + k]; ok = checkPathBlend(po, v, lut); } if (ok) cropped[jk] = mop; else cropped[jk] = 0; jk ++; } if (m_voxelType == 0) { for(int j=0; j<m_nY*m_nZ; j++) { if (cropped[j] == 0) tmp[j] = 0; } } else { for(int j=0; j<m_nY*m_nZ; j++) { if (cropped[j] == 0) ((ushort*)tmp)[j] = 0; } } applyOpacity(iv, cropped, lut, tmp); memcpy(opacityVol + i0*m_nY*m_nZ, tmp, m_nY*m_nZ); i0++; } delete [] tmp; delete [] cropped; m_meshProgress->setValue(100); qApp->processEvents(); //------------ if (m_tearPresent) { uchar *data0 = new uchar[m_nX*m_nY*m_nZ]; memcpy(data0, opacityVol, m_nX*m_nY*m_nZ); applyTear(d0, d1, 0, data0, opacityVol, false); delete [] data0; } typedef uchar PixelType; const unsigned int Dimension = 3; typedef itk::Image< PixelType, Dimension > ImageType; ImageType::IndexType start; start.Fill(0); ImageType::SizeType size; size[0] = m_nZ; size[1] = m_nY; size[2] = m_nX; ImageType::RegionType region(start, size); ImageType::Pointer image = ImageType::New(); image->SetRegions(region); image->Allocate(); image->FillBuffer(0); uchar *iptr = (uchar*)image->GetBufferPointer(); memcpy(iptr, opacityVol, m_nX*m_nY*m_nZ); typedef itk::Image< float, 3 > OutputImageType; typedef itk::SignedMaurerDistanceMapImageFilter<ImageType, OutputImageType> DistanceMapFilter; DistanceMapFilter::Pointer filter = DistanceMapFilter::New(); filter->SetInput( image ); filter->SetSquaredDistance(0); filter->SetUseImageSpacing(0); filter->SetInsideIsPositive(1); filter->Update(); QFile fp; fp.setFileName(flnm); fp.open(QFile::WriteOnly); uchar vt = 8; fp.write((char*)&vt, 1); fp.write((char*)&m_nX, 4); fp.write((char*)&m_nY, 4); fp.write((char*)&m_nZ, 4); OutputImageType *dimg = filter->GetOutput(); char *tdata = (char*)(dimg->GetBufferPointer()); fp.write(tdata, 4*m_nX*m_nY*m_nZ); fp.close(); m_meshLog->moveCursor(QTextCursor::End); m_meshLog->insertPlainText("Signed Distance Map data saved in "+flnm); QMessageBox::information(0, "", QString("Signed Distance Map saved in "+flnm)); }